鉴于图片和模板图片,我想匹配图片并找到可能的损坏,如果有的话。
未损坏的图像
图片损坏
模板图片
注意:上图显示了损坏的示例,可以是任何大小和形状。假设已经完成了正确的预处理,并且模板和图像都转换为具有白色背景的二进制文件。
我使用以下方法检测关键点并匹配它:
keypoints
和descriptors
以及图片。为此,我使用了名为detectAndCompute()
的 OpenCV 的内置函数。knnMatch()
进行匹配。 Lowe's Ratio Test
找到了很好的匹配。 结果:
如果我将模板与自身template-template
匹配,我会得到 1751 匹配,这应该是完美匹配的理想值。
在未损坏的图像中,我得到了 847 好的匹配。
在受损的图像中,我得到了 346 的好匹配。
我们可以看到与比赛数量的差异,但我有几个问题:
image-template
和template-template
中的良好匹配数量来确定图片是否包含损坏?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;
}