索引地址:系列索引
OpenCV提供了一个名为matchShapes的函数,它接收两个图像(或轮廓)并使用Hu Moments找到它们之间的距离。所以,不必在自己计算hu矩。只需将图像二值化并使用matchShapes。
说明
函数比较两个形状,3个被实现的方法都使用hu 不变量。
声明
| double matchShapes( InputArray contour1, InputArray contour2, int method, double parameter );
|
method 参数
| enum ShapeMatchModes { CONTOURS_MATCH_I1 =1, CONTOURS_MATCH_I2 =2, CONTOURS_MATCH_I3 =3 };
|
令 D(A,B)为形状A和B之间的距离,并且$H_i^A $和 HiB为形状A和B的对数变换的Hu矩。定义对应于三种情况的距离:
1.CONTOURS_MATCH_I1
D(A,B)=i=0∑6∣HiB1−HiA1∣
2.CONTOURS_MATCH_I2 =2
D(A,B)=i=0∑6∣HiB−HiA∣
3.CONTOURS_MATCH_I3 =3
D(A,B)=i=0∑6∣HiA∣∣HiA−HiB∣
如果两幅图一样那么距离为0。可以推测值越大两幅图越不像
测试代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
| #include <iostream> #include <opencv2/opencv.hpp>
using namespace std; using namespace cv;
void getHuMoments(Mat &src1,Mat &src2){ Mat gray1, binary1, dst1; Mat gray2, binary2, dst2; cvtColor(src1, gray1, COLOR_BGR2GRAY); cvtColor(src2, gray2, COLOR_BGR2GRAY);
imshow("src1", src1); imshow("src2", src2);
threshold(gray1, binary1, 127, 255, THRESH_BINARY | THRESH_OTSU); imshow("binary1", binary1); threshold(gray2, binary2, 127, 255, THRESH_BINARY | THRESH_OTSU); imshow("binary2", binary2);
Moments ms1,ms2; ms1 = moments(binary1, false); ms2 = moments(binary2, false); double hu1[7],hu2[7]; HuMoments(ms1, hu1); HuMoments(ms2, hu2);
cout << endl << endl; cout << " img1:" << endl; for (size_t i = 0; i < 7; i++) { hu1[i] = -1 * copysign(1.0, hu1[i]) * log10(abs(hu1[i])); cout << " hu1[" << i+1 << "]=" << hu1[i] << endl; } cout << endl;
cout << " img2:" << endl; for (size_t i = 0; i < 7; i++) { hu2[i] = -1 * copysign(1.0, hu2[i]) * log10(abs(hu2[i])); cout << " hu2[" << i+1 << "]=" << hu2[i] << endl; }
double d1 = matchShapes(binary1, binary2, CONTOURS_MATCH_I1, 0); double d2 = matchShapes(binary1, binary2, CONTOURS_MATCH_I2, 0); double d3 = matchShapes(binary1, binary2, CONTOURS_MATCH_I3, 0);
cout << " hu矩匹配值:" << endl; cout << " CONTOURS_MATCH_T1 :" << d1 << endl; cout << " CONTOURS_MATCH_T2 :" << d2 << endl; cout << " CONTOURS_MATCH_T3 :" << d3 << endl; }
int main() { Mat src1 = imread("1.jpg"); Mat src2 = imread("1.png");
if (src1.empty()||src2.empty()) { cout << " input the image error!" << endl; } getHuMoments(src1, src2);
waitKey(0); return 0; }
|
测试图片1为tifa,测试图片2为从图片1中截取的部分脸
结果为:
