我在使用OpenCV 3.0的Win 8.1 64位计算机上使用VS2012 C ++ / CLI。
我正在尝试实施SURF的GPU版本。
当我没有指定ROI时,我没有问题。因此,以下行没有问题,并检测完整图像中的关键点:
surf(*dImages->d_gpuGrayFrame,cuda::GpuMat(),Images->SurfKeypoints);
但是,指定ROI的努力会导致崩溃。例如,我通过Top,Left和Bottom,Right坐标指定ROI(我知道在非GPU代码中工作)。在GPU代码中,如果ROI小于源图像本身,则以下情况会导致崩溃(如果ROI与源图像的大小相同,则不会崩溃)。
int theight = (Images->LoadFrameClone.rows-Images->CropBottom) - Images->CropTop ;
int twidth = (Images->LoadFrameClone.cols-Images->CropRight)-Images->CropLeft ;
Rect tRect = Rect(Images->CropLeft,Images->CropTop,twidth,theight);
cuda::GpuMat tmask = cuda::GpuMat(*dImages->d_gpuGrayFrame,tRect);
surf(*dImages->d_gpuGrayFrame,tmask,Images->SurfKeypoints); // fails on this line
我知道tmask的大小非零,并且底层图像是正确的。据我所知,唯一的问题是在SURF GPU调用中指定ROI。任何导致这可能发生的原因?
由于
答案 0 :(得分:0)
我在OpenCV 3.1中遇到了同样的问题。据推测,SURF算法不适用于具有通过设置ROI引入的步长或步幅的图像。我没有试过掩盖,看看这是否有所作为。
解决方法是将ROI复制到另一个连续的GpuMat。内存到内存副本在GPU上几乎是免费的(我的GTX780以142 GB /秒的速度进行设备到设备的记忆),这使得这个hack有点不那么可憎。
GpuMat src; // filled with some image
GpuMat srcRoi = GpuMat (src, roi); // roi within src
GpuMat dst;
srcRoi.copyTo (dst);
surf(dst, GpuMat(), KeypointsGpu, DescriptorsGpu);