First, preface
This paper mainly realizes the use of OpenCV in the GPU version of the surf feature detector and GPU version of the Orb detector, respectively, the feature points of the image extraction and matching, and the search for the feature points of the distance screening, matching a better feature points to display
Second, the implementation of the Code
I do not produce code, I just code for Porter and modification work
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);//Get rotation matrix 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; Move coordinates to midpoint map_matrix.at<double> (1, 2) + = (HEIGHT_ROTATED-HEIGHT_SRC)/2.0; Move coordinates to the midpoint 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;
}//Main get surf feature points, descriptors, and feature points matching 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;
Compute feature points and feature descriptors sub-featurefinder_gpu (Src_gpu, Gpu::gpumat (), KEYPOINTS_GPU_SRC, DESCRIPTORS_GPU_SRC);
Featurefinder_gpu (Dst_gpu, Gpu::gpumat (), KEYPOINTS_GPU_DST, DESCRIPTORS_GPU_DST);
Download feature points back to the CPU for easy drawing using featurefinder_gpu.downloadkeypoints (KEYPOINTS_GPU_SRC, KEYPOINTS_SRC);
Featurefinder_gpu.downloadkeypoints (KEYPOINTS_GPU_DST, KEYPOINTS_DST); MakeFeature point matching gpu::bruteforcematcher_gpu< l2<float> > Matcher_lk with GPU-provided bruteforcematcher;
Matcher_lk.match (DESCRIPTORS_GPU_SRC, DESCRIPTORS_GPU_DST, Matches, Gpu::gpumat ()); float max_distance = 0.2; Define feature points good or bad measure distance std::vector<dmatch> good_matches; Collect a good match point for (int i = 0; i < descriptors_gpu_src.rows; i++) {if (Matches[i].distance < max_distance) {goo
D_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::a
ll ( -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; Set the modulePaste 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);
Feature point matching using GPU-provided bruteforcematcher gpu::bruteforcematcher_gpu< hamminglut > matcher_lk;
Matcher_lk.match (DESCRIPTORS_GPU_SRC, DESCRIPTORS_GPU_DST, Matches, Gpu::gpumat ()); float max_distance = 60; Define feature points good or bad measure distance std::vector<dmatch> good_matches; Collect a good match point for (int i = 0; i < descriptors_gpu_src.rows; i++) {if (Matches[i].distance < max_distance) {goo
D_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::a
ll ( -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::D eviceinfo 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; }
iii. Results of Operation
The running environment is vs2013+opencv2.4.9+cuda7.0, the result shows as follows, The Orb algorithm looks for the characteristic point and the computation descriptor speed is fast, the GPU edition surf characteristic point has the request to the input picture size, cannot be too small