Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

GPU SIFT and dealing with GPU pointers

Hi,

I'm using the GPU libraires of OpenCV to perform a 3D-geometric based image comparison. I use SURF_GPU to get keypoints and descriptors and cv::gpu::BruteForceMatcher_GPU to do the actual matching. I already implemented a serial version which works fine, but I'm having some hard time figuring out how to deal with some OpenCV structures using a GPU without having to convert between data types all the time and saving intermediary results in the CPU. Here is what I already did and what I'm trying to do now:

  1. SIFT extractor stuff and matches in the GPU are OK! I do the matchings in both directions, so I can get only matches which are symmetrical, i.e.


    GpuMat trainIdxMat1, distanceMat1, allDist1;
    GpuMat trainIdxMat2, distanceMat2, allDist2;
    matcher.knnMatchSingle(im1_descriptors_gpu, im2_descriptors_gpu, 
            trainIdxMat1, distanceMat1, allDist1, 2);
    matcher.knnMatchSingle(im2_descriptors_gpu, im1_descriptors_gpu, 
            trainIdxMat2, distanceMat2, allDist2, 2);

  1. Rejecting bad matches - problems dealing with GPU pointers! As I want to filter out bad matches, (in my serial version) I iterate through the found matches and delete matches for which the ratio first_best_match.distance/second_best_match.distance is larger than some threshold (e.g. 0.7). I already wrote a kernel myself and want to pass it pointers to the found matches so it can process them all. I get these pointers like explained here (http://answers.opencv.org/question/9783/cuda-with-opencv-stl-transformation/). That's part of my code to do it:


    int2* trainIdx1 = trainIdxMat1.ptr<int2>();
    float2* distance1 = distanceMat1.ptr<float2>();
    int2* trainIdx2 = trainIdxMat2.ptr<int2>();
    float2* distance2 = distanceMat2.ptr<float2>();
Then I pass these pointers to my CUDA-Kernel. My problem here is, that I'm not sure how to best delete the bad matches without having to downloading them and storing them somewhere and so on. It would be great if I could delete them directly from the device, i.e. from my matching array.

  1. Iterating through both match arrays and check which matched points are in matches1 and matches2 as well. Here I have similar questions about deleting matched points from my matches without having to juggle with pointers, arrays and minimizing data transfer between CPU and GPU. I think, I could figure it out, after getting a better understanding about the things in (2).

I hope the question is not too confusing! Please, let me know if I should clarify something better! I would be very thankful for any kind of help!

GPU SIFT and dealing with GPU pointers

Hi,

I'm using the GPU libraires of OpenCV to perform a 3D-geometric based image comparison. I use SURF_GPU to get keypoints and descriptors and cv::gpu::BruteForceMatcher_GPU to do the actual matching. I already implemented a serial version which works fine, but I'm having some hard time figuring out how to deal with some OpenCV structures using a GPU without having to convert between data types all the time and saving intermediary results in the CPU. Here is what I already did and what I'm trying to do now:

  1. SIFT extractor stuff and matches in the GPU are OK! I do the matchings in both directions, so I can get only matches which are symmetrical, i.e.


    GpuMat trainIdxMat1, distanceMat1, allDist1;
    GpuMat trainIdxMat2, distanceMat2, allDist2;
    matcher.knnMatchSingle(im1_descriptors_gpu, im2_descriptors_gpu, 
            trainIdxMat1, distanceMat1, allDist1, 2);
    matcher.knnMatchSingle(im2_descriptors_gpu, im1_descriptors_gpu, 
            trainIdxMat2, distanceMat2, allDist2, 2);

  1. Rejecting bad matches - problems dealing with GPU pointers! As I want to filter out bad matches, (in my serial version) I iterate through the found matches and delete matches for which the ratio first_best_match.distance/second_best_match.distance is larger than some threshold (e.g. 0.7). I already wrote a kernel myself and want to pass it pointers to the found matches so it can process them all. I get these pointers like explained here (http://answers.opencv.org/question/9783/cuda-with-opencv-stl-transformation/). here. That's part of my code to do it:


    int2* trainIdx1 = trainIdxMat1.ptr<int2>();
    float2* distance1 = distanceMat1.ptr<float2>();
    int2* trainIdx2 = trainIdxMat2.ptr<int2>();
    float2* distance2 = distanceMat2.ptr<float2>();
Then I pass these pointers to my CUDA-Kernel. My problem here is, that I'm not sure how to best delete the bad matches without having to downloading them and storing them somewhere and so on. It would be great if I could delete them directly from the device, i.e. from my matching array.

  1. Iterating through both match arrays and check which matched points are in matches1 and matches2 as well. Here I have similar questions about deleting matched points from my matches without having to juggle with pointers, arrays and minimizing data transfer between CPU and GPU. I think, I could figure it out, after getting a better understanding about the things in (2).

I hope the question is not too confusing! Please, let me know if I should clarify something better! I would be very thankful for any kind of help!