图像概率密度分布函数为f(x,y)的二维连续随机函数的p+q阶原点矩mpq
各阶矩的物理意义:
0阶矩(m00)为目标区域的质量
1阶矩(m01, m10)表示目标区域的质心
2阶矩(m02, m20, m11)表示旋转半径
3阶矩(m03, m30, m12, m21)描述目标的方位和斜度,反应目标的扭曲程度
但矩要能够作为和种特征描述方法得到应用,其要与目标的空间变换(平移,尺度,旋转)无关。因此在几何矩的基本定义基本上,进一步构造平移不变、尺度不变和旋转不变矩组。
为了使矩具有平移不变性,利用质心坐标,构造中心矩:
为抵消尺度变化对中心矩的影响,用零阶中心矩u00对其余各阶中心矩进行归一化处理,得到归一化中心矩为
这样七个矩(可以理解为七个数值)构成了一个七维向量,即:我们可以用一个七维向量来描述一个图像或轮廓,这个向量具有以上三种不变性。
由Hu矩组成的特征量对图片进行识别,优点就是速度很快,缺点是识别率比较低,Hu不变矩一般用来识别图像中大的物体,对于物体的形状描述得比较好,图像的纹理特征不能太复杂,像识别水果的形状,或者对于车牌中的简单字符的识别效果会相对好一些。
void cvMoments(const CvArr* arr, CvMoments*moments, int binary=0);
//arr: 图像(1-通道或3-通道,有COI设置)或多边形(点的CvSeq或一族点的向量)
//moments: 返回的矩状态接口的指针
/*binary: (仅对图像)如果标识为非零,则所有零像素点被当成零,其它的被看成1 */
/*函数cvMoments计算最高达三阶的空间和中心矩,并且将结果存在结构moments中。矩用来计算形状的重心,面积,主轴和其它的形状特征,如7Hu不变量等。*/
void cvGetHuMoments(CvMoments* moments,CvHumoments* hu_moments);
//moments: 矩状态结构的指针
//hu_moments: 矩结构的指针
#include "stdafx.h"
#include "cv.h"
#include "highgui.h"
#include "cxcore.h"
#include "cvaux.h"
int main(int argc, char* argv[])
{
//产生一幅图像
IplImage*src;
src= cvCreateImage(cvSize(10,10),8,1);
//图像初始值清零
cvZero(src);
//图像的前面5行5列赋值为255
for(intyy=0;yy<5;yy++)
{
for(intxx=0;xx<5;xx++)
{
cvSetReal2D(src,yy,xx,255);
}
}
doublem00,m10,m01;
//定义矩变量
CvMomentsmoment;
//计算原始矩和中心矩
cvMoments(src,&moment,2);
m00= cvGetSpatialMoment(&moment,0,0);
m10= cvGetSpatialMoment(&moment,1,0);
m01= cvGetSpatialMoment(&moment,0,1);
//计算质心坐标
floatx = (float)(m10/m00);
floaty = (float)(m01/m00);
//定义hu矩变量
CvHuMomentshumoment;
//计算hu矩
cvGetHuMoments(&moment,&humoment);
return0;
}
double cvMatchShapes( const void* object1,const void* object2,
int method, double parameterCV_DEFAULT(0));
//object1:第一个轮廓或灰度图像
//object2:第二个轮廓或灰度图像
//method:比较方法
//parameter:比较方法的参数
#include "stdafx.h"
#include "highgui.h"
#include "cv.h"
#include "cxcore.h"
/*
*函数功能:获取输入图像 的轮廓
*输入:
*srcIn : 单通道图像
*返回:
*CvSeq* : 存储轮廓信息
*/
CvSeq* getImageContour(IplImage* srcIn)
{
IplImage*src;
src= cvCreateImage(cvGetSize(srcIn),8,1);
//拷贝图像
cvCopy(srcIn,src);
//创建空间
CvMemStorage*mem = cvCreateMemStorage(0);
CvSeq*seq;
if(!mem)
{
printf("memis null");
}
//二值化图像
cvThreshold(src,src,100,255,0);
//计算图像轮廓
cvFindContours(src,mem,&seq);//,sizeof(CvContour),CV_RETR_CCOMP);
//释放图像空间
cvReleaseImage(&src);
//返回轮廓信息
returnseq;
}
int main(int argc, char* argv[])
{
//加载图像1
IplImage*src1 = cvLoadImage("lena.jpg", 0);
//获取图像1的轮廓
CvSeq*contour1;
contour1= getImageContour(src1);
//加载图像2
IplImage*src2 = cvLoadImage("char2.png",CV_LOAD_IMAGE_GRAYSCALE);
//获取图像2的轮廓
CvSeq*contour2;
contour2= getImageContour(src2);
//进行比对
doubleresult;
result= cvMatchShapes(contour1,contour2,1);
//输出结果
printf("resultis %f \n",result);
getchar();
//释放轮廓存储空间
cvReleaseMemStorage(&contour1->storage);
cvReleaseMemStorage(&contour2->storage);
//释放图像空间
cvReleaseImage(&src1);
cvReleaseImage(&src2);
return0;
}