1
votes

I am using VS2012 C++/CLI on a Win 8.1 64 bit machine with OpenCV 3.0.

I am trying to implement the GPU version of SURF.

When I do not specify an ROI, I have no problem. Thus, the following line gives no problem and detects keypoints in the full image:

surf(*dImages->d_gpuGrayFrame,cuda::GpuMat(),Images->SurfKeypoints);

However, efforts to specify an ROI cause a crash. For example, I specify the ROI by Top,Left and Bottom,Right coordinates (which I know work in non-GPU code). In the GPU code, the following causes a crash if the ROI is any smaller than the source image itself (no crash if the ROI is the same size as the source image).

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

I know that tmask is non-zero in size and that the underlying image is correct. As far as I can tell, the only issue is specifying an ROI in the SURF GPU call. Any leads on why this may be happening?

Thanks

1
did you print tWidth and tHeight? Maybe the Rect doesnt create a legal ROI (e.g. crop area is too big)? did you try for really small crop sizes? - Micka
tWidth and tHeight have been printed dynamically and I can see that they are the correct size. When tWidth and tHeight are the same size as the underlying image (i.e., 1920 x 1080) then it works. As soon as tWidth and tHeight are specified to be smaller (i.e., an actual ROI), then it crashes. I have not tried really small small ROIs. What would that show? - user1805103
ROI and masks are different things. In fact, the mask should be your ROI instead I guess. Can you try to create an 8 bit single channel image (without ROI) where you draw a filled rect to tRect region and use that as a mask? - Micka
not sure how ROIs work in OpenCV, but if only the ROI of tmask is used as the "mask" parameter, it is smaller than your input image and therefore no legal mask. - Micka
or try to set the same ROI to *dImages->d_gpuGrayFrame - Micka

1 Answers

0
votes

I experienced the same problem in OpenCV 3.1. Presumably the SURF algorithm doesn't work with images which have a step or stride which has been introduced by setting an ROI. I have not tried masking to see if this makes a difference.

A work around is to just copy the ROI to another contiguous GpuMat. Memory to memory copies are almost free on the GPU (my GTX780 does device to device memcopy at 142 GB/sec), which makes this hack a bit less odious.

GpuMat src;                           // filled with some image
GpuMat srcRoi = GpuMat (src, roi);    // roi within src
GpuMat dst;
srcRoi.copyTo (dst);
surf(dst, GpuMat(), KeypointsGpu, DescriptorsGpu);