#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
using namespace std;
using namespace cv;
int main()
{
// 读取图片
Mat img1 = imread("digit.png");
if (img1.empty()) { cerr << "Error: read image failed! \n"; return -1; }
namedWindow("Input1", WINDOW_AUTOSIZE);
imshow("Input1", img1);
Mat img2 = imread("digitSet.png");
if (img2.empty()) { cerr << "Error: read image failed! \n"; return -1; }
namedWindow("Input2", WINDOW_AUTOSIZE);
imshow("Input2", img2);
cvtColor(img1, img1, COLOR_BGR2GRAY);
cvtColor(img2, img2, COLOR_BGR2GRAY);
Mat edge1, edge2;
//Canny(img1, edge1, 10, 30, 3); //如果使用canny算子,会出现边缘处存在多次contour,导致误差较大
//Canny(img2, edge2, 10, 30, 3);
edge1 = img1; //由于图片为黑白图像(ppt里面绘制的),可以直接使用
edge2 = img2;
// 寻找contour
vector<vector<Point>> cnt1, cnt2;
vector<Vec4i> hierarchy1, hierarchy2;
findContours(edge1, cnt1, hierarchy1, RETR_TREE, CHAIN_APPROX_NONE);
findContours(edge2, cnt2, hierarchy2, RETR_TREE, CHAIN_APPROX_NONE);
//绘制找到的边缘contour
Mat dst1 = Mat::zeros(edge1.rows, edge1.cols, CV_8UC3);
int idx = 0;
for (; idx<cnt1.size(); idx++)
{
Scalar color(rand() & 255, rand() & 255, rand() & 255);
drawContours(dst1, cnt1, idx, color, 1, 8, hierarchy1, 1);
}
namedWindow("Template", WINDOW_AUTOSIZE);
imshow("Template", dst1);
Mat dst2 = Mat::zeros(edge2.rows, edge2.cols, CV_8UC3);
idx = 0;
for (; idx<cnt2.size(); idx++)
{
Scalar color(rand() & 255, rand() & 255, rand() & 255);
drawContours(dst2, cnt2, idx, color, 1, 8, hierarchy2, 1);
}
namedWindow("TODO", WINDOW_AUTOSIZE);
imshow("TODO", dst2);
// 计算HuMoment,并进行匹配
Moments m1 = moments(cnt1[0], true);
Mat hu1;
HuMoments(m1, hu1);
idx = 0;
Moments m2;
Mat hu2;
Mat result = Mat::zeros(edge2.rows, edge2.cols, CV_8UC3);
for (; idx < cnt2.size(); idx++) {
m2 = moments(cnt2[idx], true);
HuMoments(m2, hu2);
double likely = matchShapes(hu1, hu2, CONTOURS_MATCH_I1, 1);
cout << "The HuMoment of index " << idx << ": " << likely << endl;
if (likely < 0.6) {
Scalar color(rand() & 255, rand() & 255, rand() & 255);
drawContours(result, cnt2, idx, color, 1, 8, hierarchy2, 1);
}
}
namedWindow("Result", WINDOW_AUTOSIZE);
imshow("Result", result);
// 按Esc键退出
while (true) { if (27 == waitKey(0)) break; }
destroyAllWindows();
return 0;
}
实例图片1: digit.png
实例图片2: digitSet.png