1

给定一个图像和一个模板图像,我想匹配这些图像并找出可能的损坏,如果有的话

未损坏的图像

**原图**

损坏的图像

**损坏的图像**

模板图像

**模板图片**

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

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

  1. 使用ORB从模板以及图像中查找所有keypoints和。为此,我使用了OpenCV的内置函数,名为.descriptorsdetectAndCompute()
  2. 在此之后,我使用了蛮力匹配器并使用knnMatch().
  3. 然后我用Lowe's Ratio Test来找到好的匹配项。

结果: 如果我将模板与其自身匹配template-template,我会得到1751个匹配项,这应该是完美匹配的理想值。

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

**匹配未损坏的图像**

在损坏的图像中,我得到了346 个很好的匹配项。

**匹配损坏的图像**

我们可以从匹配的数量上看出差异,但我有几个问题:

  1. 如何确定损坏的确切位置?
  2. image-template我如何通过查看和中的良好匹配数来断定图像包含损坏template-template

PS:我期待一个详尽的答案,因为我是 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;
    }
4

0 回答 0