本系列代码托管于:https://github.com/chintsan-code/opencv4-tutorials
本篇使用的项目为:match_shapes
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
RNG rng(12345);
void contour_info(Mat &image, vector<vector<Point>> &contours);
int main(int argc, const char** argv) {
Mat src1 = imread("../sample/abc.png");
Mat src2 = imread("../sample/a.png");
if (src1.empty() || src2.empty()) {
cout << "could not load image..." << endl;
return -1;
}
imshow("input1", src1);
imshow("input2", src2);
vector<vector<Point>> contours1;
vector<vector<Point>> contours2;
contour_info(src1, contours1);
contour_info(src2, contours2);
Moments mm2 = moments(contours2[0]);
Mat hu2;
HuMoments(mm2, hu2);
for (size_t t = 0; t < contours1.size(); t++) {
Moments mm = moments(contours1[t]);
double cx = mm.m10 / mm.m00; // 轮廓中心x
double cy = mm.m01 / mm.m00; // 轮廓中心y
drawMarker(src1, Point(cx, cy), Scalar(255, 0, 0), MARKER_TILTED_CROSS, 10, 2, 8);
Mat hu;
HuMoments(mm, hu);
double dist = matchShapes(hu, hu2, CONTOURS_MATCH_I1, 0);
if (dist < 1.0) {
printf("matched distance value : %.2f\n", dist);
drawContours(src1, contours1, t, Scalar(0, 0, 255), 2, 8);
}
}
imshow("match contours demo", src1);
waitKey(0);
destroyAllWindows();
return 0;
}
void contour_info(Mat &image, vector<vector<Point>> &contours) {
// 二值化
Mat dst;
GaussianBlur(image, dst, Size(3, 3), 0);
Mat gray, binary;
cvtColor(dst, gray, COLOR_BGR2GRAY);
threshold(gray, binary, 0, 255, THRESH_BINARY | THRESH_OTSU);
// 轮廓发现
vector<Vec4i> hirearchy;
findContours(binary, contours, hirearchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point());
}
几何距
(1)n阶距
阶数:\(p+q\)
例如:
- 0阶距:\(m_{00}\)
- 1阶距:\(m_{10}、m_{01}\)
- 2阶距:\(m_{11}、m_{20}、m_{02}\)
(2)中心距
(3)归一化中心矩
(4)Hu距:平移不变性、旋转不变性、放缩不变性
moments:计算几何距,最高计算3阶
Moments moments( InputArray array, bool binaryImage = false );
- array:输入
- binaryImage:如果为true,非0像素将会被视为1
- @return:返回几何距信息
- n阶距:m00, m10, m01, m20, m11, m02, m30, m21, m12, m03
- 计算轮廓中心:
- Xavg = m10 / m00
- Yavg = m01 / m00
- 计算轮廓中心:
- 中心距:mu20, mu11, mu02, mu30, mu21, mu12, mu03
- 归一化中心距:nu20, nu11, nu02, nu30, nu21, nu12, nu03
- n阶距:m00, m10, m01, m20, m11, m02, m30, m21, m12, m03
HuMoments:计算Hu距
void HuMoments( const Moments& m, OutputArray hu );
- m:输入的几何距
- hu:输出的Hu距
matchShapes:轮廓匹配
double matchShapes( InputArray contour1, InputArray contour2, int method, double parameter );
- contour1:输入的第一个轮廓或灰度图,如果要用基于Hu距的匹配,应该输入轮廓的Hu距
- contour2:输入的第二个轮廓或灰度图,如果要用基于Hu距的匹配,应该输入轮廓的Hu距
- method:比较方法,见下图。
- CONTOURS_MATCH_I1
- CONTOURS_MATCH_I2
- CONTOURS_MATCH_I3
- parameter:比较方法的特定参数(目前不支持),设为0即可
- @return:匹配值,是一个距离,距离越小越相似
评论 (0)