Win10平台 OpenCV GPU模块的编译

  最近搞了个”机械臂+机器视觉”的项目,发现视觉这块用到的特征点匹配算法有点慢,因此有了用OpenCV的GPU模块来实现的想法。然而官网下载编译好的版本并没有这一块,而别人编译好的又少东西比较烦,因此决定自己来。

  需要下载和安装的东西

  1.OpenCV源码:http://opencv.org/releases.html,我下的是2.4.13.3版本

  2.CUDA:https://developer.nvidia.com/cuda-downloads,我下的是8.0.61_win版本,下载完装上

  3.CMake:https://cmake.org/download/,我下的是3.9.1版本,如果下载的是安装版的也直接装上

  编译过程

  打开CMake

这里写图片描述

  第一项选OpenCV源码文件夹,第二项选输出文件夹

这里写图片描述

  点击“Configure按钮”,然后选择相应的VS版本

这里写图片描述

  注意,这里如果选择的是“Visual Studio 14 2015”,就是后面没带“Win64”的会报一堆CUDA相关的错误,这个应该是CUDA相关内容不支持win32造成的。我觉得x64才是未来,所以就没解决它,君若有想法可以研究下如何解决。

  当然,即便是选择了Win64,我还是遇到了下面的错误:

这里写图片描述

  这篇博客给出了解决方法

  就是“OpenCV2.4.13.3”文件夹下的CMakeLists.txt中的

`set(OPENCV_VCSVERSION "unknown")`

  改为

 set(OPENCV_VCSVERSION "2.4.13.3")

  具体位置如下:

  if(NOT GIT_RESULT EQUAL 0)
    set(OPENCV_VCSVERSION "unknown")
  endif()
else()
  # We don't have git:
  # set(OPENCV_VCSVERSION "unknown")
  set(OPENCV_VCSVERSION "2.4.13.3")
endif()

  弄完再点一次“Configure”,然后点击“Generate”,就在输出文件夹下面多处了个“sln”文件,可以用VS2015打开然后编译了。编译过程速度感人,请耐心去睡个觉。

  一觉起来编译好了,用上,发现因为要把图像数据从内存拷贝到显存中,快不到哪去。。。额。。。

  测试代码如下:

int num_devices = gpu::getCudaEnabledDeviceCount();//获取显卡数量
if (num_devices <=0)
{
    printf("没有显卡");
    return;
}
int enable_device_id = -1;//查找可以使用的显卡
for (size_t i = 0; i < num_devices; i++)
{
    gpu::DeviceInfo dev_info(i);
    if (dev_info.isCompatible())
    {
        enable_device_id = i;
    }
}
if (enable_device_id < 0)
{
    printf("没有可使用显卡");
    return;
}
gpu::setDevice(enable_device_id);
Mat src_host = cv::imread("1.png", CV_LOAD_IMAGE_GRAYSCALE);
long begintime = clock();
gpu::GpuMat dst, src;
src.upload(src_host);
gpu::threshold(src, dst, 128.0, 255.0, CV_THRESH_BINARY);
Mat result_host;
dst.download(result_host);
printf("花费时间:%ds", clock() - begintime);
imshow("Result", result_host);
waitKey();

  特征点匹配的代码如下:

//目前CUDA仅仅支持8位单通道图像
Mat img1 = cv::imread("1.png", IMREAD_GRAYSCALE);
Mat img2 = cv::imread("2.png", IMREAD_GRAYSCALE);
long begintime = clock();
gpu::GpuMat gpuimg1, gpuimg2;
gpuimg1.upload(img1);
gpuimg2.upload(img2);
gpu::GpuMat keypoints_gpu_img1, keypoints_gpu_img2;
gpu::GpuMat descriptors_gpu_img1, descriptors_gpu_img2;
//计算特征点和特征描述子  
gpu::SURF_GPU surf(700);
surf(gpuimg1, gpu::GpuMat(), keypoints_gpu_img1, descriptors_gpu_img1);
surf(gpuimg2, gpu::GpuMat(), keypoints_gpu_img2, descriptors_gpu_img2);
//将特征点下载回cpu,便于画图使用  
std::vector<KeyPoint> keypoints_img1;
std::vector<KeyPoint> keypoints_img2;
surf.downloadKeypoints(keypoints_gpu_img1, keypoints_img1);
surf.downloadKeypoints(keypoints_gpu_img2, keypoints_img2);
//使用gpu提供的BruteForceMatcher进行特征点匹配  
std::vector<DMatch> matches;
gpu::BruteForceMatcher_GPU< L2<float> > matcher_lk;
matcher_lk.match(descriptors_gpu_img1, descriptors_gpu_img2, matches, gpu::GpuMat());
float max_distance = 0.2;   //定义特征点好坏衡量距离  
std::vector<DMatch> good_matches;  //收集较好的匹配点  
for (int i = 0; i < descriptors_gpu_img1.rows; i++) {
    if (matches[i].distance < max_distance) {
        good_matches.push_back(matches[i]);
    }
}
Mat image_matches;
drawMatches(img1, keypoints_img1, img2, keypoints_img2, good_matches,
    image_matches, Scalar(0, 255, 0), Scalar::all(-1), vector<char>(), 0);
printf("花费时间:%dms\n",clock()- begintime);
imshow("Gpu Surf", image_matches);
waitKey();

猜你喜欢

转载自blog.csdn.net/oHanTanYanYing/article/details/77542521