原文出处:http://blog.csdn.net/lu597203933/article/details/14532053
Hu距的概念在前一篇文章里已经介绍了
这里主要阐述在opencv里面Hu距的实现。
<1>普通矩和中心矩的计算
Void cvMoments(const CvArr*arr,CvMoments*moments, int binary = 0)
arr:图像(1-通道或3通道,有COI设置)或者多边形(点的CvSeq或一族点的向量)
moments:返回矩阵态度接口的指针
binary(仅对图像)如果标识为非0,则所有零像素点被当成零,其它的被看成1.
Double cvGetSpatialMoment(&moment, p, q); //得到普通矩
Double cvGetCentralMoment(&moment, p, q); // 得到中心矩
<2>计算hu矩
Void cvGetHuMoment(CvMoments *moment,CvHuMoments *humoment)
代码:
[cpp] view plaincopyprint?
IplImage *src = cvCreateImage(cvSize(10,10), 8, 1);
cvZero(src);
for(int yy = 0; yy < 5; yy++)
{
for(int xx = 0; xx < 5; xx++)
{
cvSetReal2D(src, yy, xx, 255);
}
}
double m00, m10, m01;
CvMoments moment;
cvMoments(src, &moment, 2); //第三个像素点非0,则所有的0像素点被当做0,非0像素点被当做1
m00 = cvGetSpatialMoment(&moment, 0, 0); // 得到普通矩
m10 = cvGetSpatialMoment(&moment, 1, 0);
m01 = cvGetSpatialMoment(&moment, 0, 1);
double u20;
u20 = cvGetCentralMoment(&moment, 2, 0); //得到中心矩
CvHuMoments humoment;
cvGetHuMoments(&moment, &humoment);
double hu1 = humoment.hu1; // 得到hu矩
cout << hu1 << endl;
<3>OPENCV还提供了输入图像直接进行hu矩匹配的函数,返回的是两个图像或轮廓之间hu矩的相似度:
double cvMatchShapes(const void*object1,const void*object2,int method,doubleparameter=0);
计算两个轮廓之间 hu 矩相似程度:
[cpp] view plaincopyprint?
#include <iostream>
#include "cv.h"
#include "cxcore.h"
#include "highgui.h"
using namespace std;
CvSeq *getImageContours(CvArr *src)
{
cvThreshold(src, src, 100, 255, CV_THRESH_BINARY);
CvMemStorage * storage = cvCreateMemStorage(0);
CvSeq * contours;
cvFindContours(src, storage, &contours);
return contours;
}
int main()
{
IplImage *src1 = cvLoadImage("", 0);
CvSeq *contours1 = getImageContours(src1); // 得到src1的轮廓
IplImage *src2 = cvLoadImage("", 0);
CvSeq *contours2 = getImageContours(src2);
double result = cvMatchShapes(contours1, contours2, 1); // 根据输入的图像或轮廓来计算它们的hu矩的相似度
cout << result << endl;
cvReleaseMemStorage(&contours1->storage);
cvReleaseMemStorage(&contours1->storage);
cvReleaseImage(&src1);
cvReleaseImage(&src2);
return 0;
}