Matching the identified planar object

Matching the identified planar object:

        In everyday life, we are exposed photograph is often a problem because the angle or direction of the text in the image caused by inclination or deflection angle.

Perspective transformation (Perspective Transformation) image can be corrected. It may be performed to identify the image plane by perspective transformation;

 

 Two main API:

 

 

 

 Code demonstrates:

 

  1 #include <opencv2/opencv.hpp>
  2 #include <opencv2/xfeatures2d.hpp>
  3 #include <iostream>
  4 #include <math.h>
  5 
  6 using namespace cv;
  7 using namespace std;
  8 using namespace cv::xfeatures2d;
  9 
 10 int main(int argc, char** argv) {
 11     Mat img1 = imread("L:/opencv_picture/book1.jpg", IMREAD_GRAYSCALE);
 12     Mat img2 = imread("L:/opencv_picture/book2.jpg", IMREAD_GRAYSCALE);
 13     if (!img1.data || !img2.data) {
 14         return -1;
 15     }
 16     imshow("object image", img1);
 17     imshow("object in scene", img2);
 18 
 19     // surf featurs extraction
 20     int minHessian = 400;
 21     Ptr<SURF> detector = SURF::create(minHessian);
 22     vector<KeyPoint> keypoints_obj;
 23     vector<KeyPoint> keypoints_scene;
 24     Mat descriptor_obj, descriptor_scene;
 25     detector->detectAndCompute(img1, Mat(), keypoints_obj, descriptor_obj);
 26     detector->detectAndCompute(img2, Mat(), keypoints_scene, descriptor_scene);
 27 
 28     // matching
 29     FlannBasedMatcher matcher;
 30     vector<DMatch> matches;
 31     matcher.match(descriptor_obj, descriptor_scene, matches);
 32 
 33     // find good matched points
 34     double minDist = 1000;
 35     double maxDist = 0;
 36     for (int i = 0; i < descriptor_obj.rows; i++) {
 37         double dist = matches[i].distance;
 38         if (dist > maxDist) {
 39             maxDist = dist;
 40         }
 41         if (dist < minDist) {
 42             minDist = dist;
 43         }
 44     }
 45     printf("max distance : %f\n", maxDist);
 46     printf("min distance : %f\n", minDist);
 47     vector<DMatch> goodMatches;
 48     for (int i = 0; i < descriptor_obj.rows; i++) {
 49         double dist = matches[i].distance;
 50         if (dist < max(3 * minDist, 0.02)) {
 51             goodMatches.push_back(matches[i]);
 52         }
 53     }
 54 
 55     Mat matchesImg;
 56     drawMatches(img1, keypoints_obj, img2, keypoints_scene, goodMatches, matchesImg, Scalar::all(-1),
 57         Scalar::all(-1), vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS
 58     );
 59     //以上代码参考上一节内容:FLANN特征点匹配
 60     vector<Point2f> obj;
 61     vector<Point2f> objInScene;
 62     for (size_t t = 0; t < goodMatches.size(); t++) {
 63         obj.push_back(keypoints_obj[goodMatches[t].queryIdx].pt);
 64 //将keypoints_obj中goodMatches[t]中的queryIdx参数(左图索引)用指针.pt分别压入堆栈obj中
 65         objInScene.push_back(keypoints_scene[goodMatches[t].trainIdx].pt);
 66 //将keypoints_scene中goodMatches[t]中的trainIdx参数(右图索引)用指针.pt分别压入堆栈objScene中
 67     }
 68     Mat H = findHomography(obj, objInScene, RANSAC);
 69 //findHomography函数:计算多个二维点对之间的最优单映射变换矩阵 H
 70 //第三个参数:0 - 利用所有点的常规方法      RANSAC - 基于RANSAC的鲁棒算法
 71 //              LMEDS - 最小中值鲁棒算法      RHO    - 基于PROSAC的鲁棒算法
 72 
 73     vector<Point2f> obj_corners(4);    //图一矩形四个顶点
 74     vector<Point2f> scene_corners(4);  //在图二中经过变换后的图一的四个顶点
 75     obj_corners[0] = Point(0, 0);
 76     obj_corners[1] = Point(img1.cols, 0);
 77     obj_corners[2] = Point(img1.cols, img1.rows);
 78     obj_corners[3] = Point(0, img1.rows);
 79     perspectiveTransform(obj_corners, scene_corners, H); //开始变换
 80     //perspectiveTransform函数采用H变换,将图一的四个顶点变换到图2中也就是scene_corners
 81 
 82     // draw line   (每个点都要加上图1的横坐标,以为两张图一起显示)
 83     line(matchesImg, scene_corners[0] + Point2f(img1.cols, 0), scene_corners[1] + Point2f(img1.cols, 0), Scalar(0, 0, 255), 2, 8, 0);
 84     line(matchesImg, scene_corners[1] + Point2f(img1.cols, 0), scene_corners[2] + Point2f(img1.cols, 0), Scalar(0, 0, 255), 2, 8, 0);
 85     line(matchesImg, scene_corners[2] + Point2f(img1.cols, 0), scene_corners[3] + Point2f(img1.cols, 0), Scalar(0, 0, 255), 2, 8, 0);
 86     line(matchesImg, scene_corners[3] + Point2f(img1.cols, 0), scene_corners[0] + Point2f(img1.cols, 0), Scalar(0, 0, 255), 2, 8, 0);
 87     
 88     //仅在dst原图(图二)上画出目标图像
 89     Mat dst;
 90     cvtColor(img2, dst, COLOR_GRAY2BGR);
 91     line(dst, scene_corners[0], scene_corners[1], Scalar(0, 0, 255), 2, 8, 0);
 92     line(dst, scene_corners[1], scene_corners[2], Scalar(0, 0, 255), 2, 8, 0);
 93     line(dst, scene_corners[2], scene_corners[3], Scalar(0, 0, 255), 2, 8, 0);
 94     line(dst, scene_corners[3], scene_corners[0], Scalar(0, 0, 255), 2, 8, 0);
 95 
 96     imshow("find known object demo", matchesImg);
 97     imshow("Draw object", dst);
 98 
 99     waitKey(0);
100     return 0;
101 }

 

 

 

 效果图:

 

 

 

 

Guess you like

Origin www.cnblogs.com/Jack-Elvis/p/11995690.html