zoukankan      html  css  js  c++  java
  • 平面对象的匹配与识别

    平面对象的匹配与识别:

            在日常生活中,我们接触的照片经常会因为角度或者方向的问题,而导致图像中的文字倾斜或者角度偏转。

    透视变换(Perspective Transformation)可以将图片进行校正。也可以通过透视变换进行图像的平面识别;

     主要是两个API:

     

     代码演示:

      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
    ", maxDist);
     46     printf("min distance : %f
    ", 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 }

     效果图:

  • 相关阅读:
    数据访问(从数据库中访问数据)
    加载类、设计模式(单例模式和工厂模式)
    面向对象之静态
    面向对象三大特性之继承和多态
    面向对象三大特性之封装
    面向对象基础知识
    mysql下载与安装过程
    Idea添加依赖的步骤:
    Java JDBC 在IDEA环境下连接MySQL
    JAVA中集合HashMap嵌套联系
  • 原文地址:https://www.cnblogs.com/Jack-Elvis/p/11995690.html
Copyright © 2011-2022 走看看