我正在尝试使用OpenCV查找ORB功能。当我直接传递图像时,我注意到特征往往位于图像的中心区域周围。为了避免这种情况,我将图像划分为网格,将每个网格视为一个小图像,然后在每个网格中找到特征,即每一个小形象。这样,特征不仅限于中心区域。
现在,为了加快速度,我决定使用OpenCV的CUDA implementation for ORB。非常方便的是,它的初始化与非CUDA版本相同:
static Ptr<ORB> cv::cuda::ORB::create (int nfeatures = 500,
float scaleFactor = 1.2f,
int nlevels = 8,
int edgeThreshold = 31,
int firstLevel = 0,
int WTA_K = 2,
int scoreType = ORB::HARRIS_SCORE,
int patchSize = 31,
int fastThreshold = 20,
bool blurForDescriptor = false
)
因此,我可以使用相同的参数值。此外,我不需要在代码中做太多的更改,我正在寻找功能:
for(ractangel_roi : list_of_rectangle_rois) {
cv::Mat cpu_patch = big_image(rectangle_roi);
cv::cuda::GpuMat gpu_patch;
gpu_patch.upload(cpu_patch);
orb_cuda->detectAndCompute(gpu_patch, cv::cuda::GpuMat(), key_point_vector, cv::cuda::GpuMat());
}
我没有得到任何编译错误,它运行的前几帧罚款。但是我总是得到这个运行时错误:
terminate called after throwing an instance of 'cv::Exception'
what(): OpenCV(4.x.x) /tmp/opencv/modules/core/src/matrix_wrap.cpp:1659: error: (-215:Assertion failed) !fixedSize() in function 'release'
Aborted (core dumped
我试着玩不同的图像序列。但是在某些帧之后我得到相同的错误。
我怀疑它可能会耗尽GPU(CUDA)内存。因此,我在每次迭代后都编写了一段代码来检查CUDA内存总量和可用内存。但它从一开始就保持不变,直到它给出运行时错误。
根本原因是什么,如何修复此错误?
**注意:**如果我不将图像划分为网格并将整个图像转换为cv::cuda::GpuMat
并将其传递给orb_cuda
,则不会出现上述错误。
**编辑1:**我有多个不同的数据集,在某个帧上所有数据集都出现了这个错误。我的意思是帧编号因数据集而异,但当我一次又一次地运行代码时,它们保持一致。由于它发生在多个不同的帧(数据集不是公共的),我不能在这里分享它们。
1条答案
按热度按时间von4xj4u1#
我找到了解决方案(但不是100%确定它为什么有效)。
在我的应用程序中,我不需要担心特性描述符,所以在前面我使用
detectAndCompute
函数时,我传递的是空的GpuMat
:根据OpenCV文档,
因此,如果我创建
cv::cuda::GpuMat()
的临时示例并传递该对象,而不是传递cv::cuda::GpuMat()
,则不会得到错误:我能想到的唯一一件事就是为什么上面的解决方案可以工作,对于
descriptors
,数据类型是OutputArray
。这就是为什么我需要传递一个实际的cv::cuda::GpuMat()
对象,而不是一个空对象。但我也不是100%确定。如果有人有更好的见解,如果你能在这里分享,将不胜感激。