使用要素匹配查找图像中的损坏

时间:2016-06-10 07:49:28

标签: c++ opencv feature-extraction feature-detection orb

鉴于图片和模板图片,我想匹配图片并找到可能的损坏,如果有的话

未损坏的图像

**Original Image**

图片损坏

**Damaged Image**

模板图片

**Template Image**

注意:上图显示了损坏的示例,可以是任何大小和形状。假设已经完成了正确的预处理,并且模板和图像都转换为具有白色背景的二进制文件。

我使用以下方法检测关键点并匹配它:

  1. 使用 ORB 查找模板中的所有keypointsdescriptors以及图片。为此,我使用了名为detectAndCompute() OpenCV 的内置函数。
  2. 在此之后,我使用了Brute Force Matcher并使用knnMatch()进行匹配。
  3. 然后我使用Lowe's Ratio Test找到了很好的匹配。
  4. 结果: 如果我将模板与自身template-template匹配,我会得到 1751 匹配,这应该是完美匹配的理想值。

    在未损坏的图像中,我得到了 847 好的匹配。

    **Matches on Undamaged Image**

    在受损的图像中,我得到了 346 的好匹配。

    **Matches on the Damaged Image**

    我们可以看到与比赛数量的差异,但我有几个问题:

    1. 如何确定损坏的确切位置?
    2. 如何通过查看image-templatetemplate-template中的良好匹配数量来确定图片是否包含损坏?
    3. P.S。:我期待一个精心回答,因为我是OpenCV的新手。

      编辑:以下是供您参考的代码。

          #include <iostream>
      
          #include <opencv2/features2d/features2d.hpp>
          #include <opencv2/calib3d/calib3d.hpp>
          #include <opencv2/imgproc/imgproc.hpp>
          #include <opencv2/highgui/highgui.hpp>
      
          using namespace std;
          using namespace cv;
      
          int main() {
      
                  Mat image = imread("./Images/PigeonsDamaged.jpg");
                  Mat temp = imread("./Templates/Pigeons.bmp");
      
                  Mat img_gray, temp_gray;
      
                  cvtColor(image, img_gray, CV_RGB2GRAY);
                  cvtColor(temp, temp_gray, CV_RGB2GRAY);
      
                  /**** Pre-processing *****/
      
                  threshold(temp_gray, temp_gray, 200, 255, THRESH_BINARY);
                  adaptiveThreshold(img_gray, img_gray, 255, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY_INV, 221, 0);
      
                  /*****/
      
                  /***** ORB keypoint detector *****/
      
                  Mat img_descriptors, temp_descriptors;
                  vector<KeyPoint> img_keypoints, temp_keypoints;
      
                  vector<KeyPoint> &img_kp = img_keypoints;
                  vector<KeyPoint> &temp_kp = temp_keypoints;
      
                  Ptr<ORB> orb = ORB::create(100000, 1.2f, 4, 40, 0, 4, ORB::HARRIS_SCORE, 40, 20);
      
                  orb -> detectAndCompute(img_gray, noArray(), img_kp, img_descriptors, false);
                  orb -> detectAndCompute(temp_gray, noArray(), temp_kp, temp_descriptors, false);
      
                  cout << "Temp Keypoints " << temp_kp.size() << endl;
      
                  /*****/
      
                  vector<vector<DMatch> > featureMatches;
                  vector<vector<DMatch> > &matches = featureMatches;
      
                  Mat & img_desc_ref = img_descriptors;
                  Mat & temp_desc_ref = temp_descriptors;
      
                  BFMatcher bf(NORM_HAMMING2, false);    /** Never keep crossCheck true when using knnMatch. Imp: Use NORM_HAMMING2 for WTA_K = 3 or 4 **/
                  bf.knnMatch(img_descriptors, temp_descriptors, matches, 3);
      
                  /*****/
      
                  /***** Ratio Test *****/
      
                  vector<DMatch> selected;
                  vector<Point2f> src_pts, temp_pts;
      
                  float testRatio = 0.75;
      
                  for (int i = 0; i < featureMatches.size(); ++i) {
      
                          if (featureMatches[i][0].distance < testRatio * featureMatches[i][1].distance) {
                                  selected.push_back(featureMatches[i][0]);
                          }
      
                  }
      
      
                  cout << "Selected Size: " << selected.size() << endl;
      
                  /*****/
      
                  /*** Draw the Feature Matches ***/
      
                  Mat output;
                  vector <DMatch> &priorityMatches = selected;
      
                  drawMatches(image, img_kp, temp, temp_kp, priorityMatches, output, Scalar(0, 255, 0), Scalar::all(-1));
      
                  namedWindow("Output", CV_WINDOW_FREERATIO);
                  imshow("Output", output);
                  waitKey();
      
                  /******/
      
                  return 0;
          }
      

0 个答案:

没有答案