opencv上gpu版surf特征点与orb特征点提取及匹配实例
2016-09-25 23:42
483 查看
一、前言
本文主要实现了使用opencv里的gpu版surf特征检测器和gpu版orb检测器,分别对图片进行特征点提取及匹配,并对寻获的特征点进行了距离筛选,将匹配较为好的特征点进行展示
二、实现代码
我不生产代码,我只是代码的搬运工和修改工
三、运行结果
运行环境为vs2013+opencv2.4.9+cuda7.0,结果展示如下,orb算法寻找特征点及计算描述子速度较快,gpu版的surf特征点对输入图片大小有要求,不能太小
本文主要实现了使用opencv里的gpu版surf特征检测器和gpu版orb检测器,分别对图片进行特征点提取及匹配,并对寻获的特征点进行了距离筛选,将匹配较为好的特征点进行展示
二、实现代码
我不生产代码,我只是代码的搬运工和修改工
//main.cpp// #include <opencv2/core/core.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/gpu/gpu.hpp> #include <opencv2/nonfree/gpu.hpp> #include <opencv2/nonfree/features2d.hpp> #include <iostream> using namespace std; using namespace cv; Mat rotatedImage(const Mat & _src, double _degree) { int width_src = _src.cols; int height_src = _src.rows; float center_x = width_src / 2.0; float center_y = height_src / 2.0; double angle = _degree * CV_PI / 180.; double a = sin(angle), b = cos(angle); Mat map_matrix = getRotationMatrix2D(Point2f(center_x, center_y), _degree, 1.0);//获得旋转矩阵 int height_rotated = height_src*fabs(b) + width_src*fabs(a); int width_rotated = height_src*fabs(a) + width_src*fabs(b); map_matrix.at<double>(0, 2) += (width_rotated - width_src) / 2.0; //将坐标移到中点 map_matrix.at<double>(1, 2) += (height_rotated - height_src) / 2.0; //将坐标移到中点 Mat dst; warpAffine(_src, dst, map_matrix, Size(width_rotated, height_rotated), CV_INTER_CUBIC | CV_WARP_FILL_OUTLIERS, BORDER_CONSTANT, cvScalarAll(0)); return dst; } //主要获得surf特征点、描述子、及特征点匹配 void surfExtractor(Mat& _src_Img, Mat& _dst_Img ) { gpu::GpuMat src_gpu(_src_Img); gpu::GpuMat dst_gpu(_dst_Img); std::vector<KeyPoint> keypoints_src; std::vector<KeyPoint> keypoints_dst; std::vector<DMatch> matches; gpu::SURF_GPU FeatureFinder_gpu(500); gpu::GpuMat keypoints_gpu_src, keypoints_gpu_dst; gpu::GpuMat descriptors_gpu_src, descriptors_gpu_dst; std::vector<float> descriptors_v1, descriptors_v2; //计算特征点和特征描述子 FeatureFinder_gpu(src_gpu, gpu::GpuMat(), keypoints_gpu_src, descriptors_gpu_src); FeatureFinder_gpu(dst_gpu, gpu::GpuMat(), keypoints_gpu_dst, descriptors_gpu_dst); //将特征点下载回cpu,便于画图使用 FeatureFinder_gpu.downloadKeypoints(keypoints_gpu_src, keypoints_src); FeatureFinder_gpu.downloadKeypoints(keypoints_gpu_dst, keypoints_dst); //使用gpu提供的BruteForceMatcher进行特征点匹配 gpu::BruteForceMatcher_GPU< L2<float> > matcher_lk; matcher_lk.match(descriptors_gpu_src, descriptors_gpu_dst, matches, gpu::GpuMat()); float max_distance = 0.2; //定义特征点好坏衡量距离 std::vector<DMatch> good_matches; //收集较好的匹配点 for (int i = 0; i < descriptors_gpu_src.rows; i++) { if (matches[i].distance < max_distance) { good_matches.push_back(matches[i]); } } Mat image_matches; drawMatches(_src_Img, keypoints_src, _dst_Img, keypoints_dst, good_matches, image_matches, Scalar(0, 255, 0) , Scalar::all(-1), vector<char>(), 0); imshow("Gpu Surf", image_matches); } void orbExtractor(Mat& _src_Img, Mat& _dst_Img) { gpu::GpuMat src_gpu(_src_Img); gpu::GpuMat dst_gpu(_dst_Img); std::vector<KeyPoint> keypoints_src, keypoints_dst; gpu::GpuMat descriptors_gpu_src, descriptors_gpu_dst; std::vector<DMatch> matches; gpu::ORB_GPU orb_finder(500); orb_finder.blurForDescriptor = true; //设置模糊 cv::gpu::GpuMat fullmask_1(src_gpu.size(), CV_8U, 0xFF); cv::gpu::GpuMat fullmask_2(dst_gpu.size(), CV_8U, 0xFF); orb_finder(src_gpu, fullmask_1, keypoints_src, descriptors_gpu_src); orb_finder(dst_gpu, fullmask_2, keypoints_dst, descriptors_gpu_dst); //使用gpu提供的BruteForceMatcher进行特征点匹配 gpu::BruteForceMatcher_GPU< HammingLUT > matcher_lk; matcher_lk.match(descriptors_gpu_src, descriptors_gpu_dst, matches, gpu::GpuMat()); float max_distance = 60; //定义特征点好坏衡量距离 std::vector<DMatch> good_matches; //收集较好的匹配点 for (int i = 0; i < descriptors_gpu_src.rows; i++) { if (matches[i].distance < max_distance) { good_matches.push_back(matches[i]); } } Mat image_matches; drawMatches(_src_Img, keypoints_src, _dst_Img, keypoints_dst, good_matches, image_matches, Scalar(255, 0, 0), Scalar::all(-1), vector<char>(), 0); imshow("Gpu ORB", image_matches); } int main() { int num_devices = cv::gpu::getCudaEnabledDeviceCount(); if (num_devices <= 0) { std::cerr << "There is no device." << std::endl; return -1; } int enable_device_id = -1; for (int i = 0; i < num_devices; i++) { cv::gpu::DeviceInfo dev_info(i); if (dev_info.isCompatible()) { enable_device_id = i; } } if (enable_device_id < 0) { std::cerr << "GPU module isn't built for GPU" << std::endl; return -1; } gpu::setDevice(enable_device_id); Mat src_Img = imread("book.bmp" , 0); Mat dst_Img = rotatedImage(src_Img, -30.0); surfExtractor(src_Img, dst_Img); orbExtractor(src_Img, dst_Img); cv::waitKey(0); return 0; }
三、运行结果
运行环境为vs2013+opencv2.4.9+cuda7.0,结果展示如下,orb算法寻找特征点及计算描述子速度较快,gpu版的surf特征点对输入图片大小有要求,不能太小
相关文章推荐
- opencv上gpu版surf特征点与orb特征点提取及匹配实例
- 要点初见:OpenCV3中CUDA ORB特征提取算法的实现(GPU加速的ORB算法)
- ORB特征提取匹配opencv3代码实现
- OpenCV中特征点提取和匹配的通用方法
- OpenCV中特征点提取和匹配的通用方法
- OpenCV中特征检测,提取与匹配使用方法学习
- OpenCV中特征点提取和匹配的通用方法
- OpenCV_局部图像特征的提取与匹配_源代码
- OpenCV中特征点提取和匹配的通用方法
- OpenCV中特征点提取和匹配的通用方…
- Opencv运动物体常用的特征提取与匹配方法
- opencv2.4.9特征点的提取和匹配
- OpenCV中特征检测,提取与匹配使用方法学习
- OpenCV中特征点提取和匹配的通用方…
- 利用opencv提取Hu不变量特征 形状匹配 机器学习识别手写数字 傅里叶变换
- OpenCV的ORB特征提取算法
- 【opencv】特征点提取和匹配的通用方法
- OpenCV中feature2D学习——SIFT和SURF算子实现特征点提取与匹配
- 利用opencv提取Hu不变量特征 形状匹配
- OpenCV_局部图像特征的提取与匹配_源代码