图像的几何不变矩

矩特征主要表征了图像区域的几何特征,又称为几何矩, 由于其具有旋转、平移、尺度等特性的不变特征,所以又称其为不变矩。在图像处理中,几何不变矩可以作为一个重要的特征来表示物体,可以据此特征来对图像进行分类等操作。

1.     HU矩

几何矩是由Hu(Visual pattern recognition by moment invariants)在1962年提出的,图像f(x,y)的(p+q)阶几何矩定义为

Mpq =∫∫(x^p)*(y^q)f(x,y)dxdy(p,q = 0,1,……∞)

矩在统计学中被用来反映随机变量的分布情况,推广到力学中,它被用作刻画空间物体的质量分布。同样的道理,如果我们将图像的灰度值看作是一个二维或三维的密度分布函数,那么矩方法即可用于图像分析领域并用作图像特征的提取。最常用的,物体的零阶矩表示了图像的“质量”:

Moo= ∫∫f(x,y )dxdy

一阶矩(M01,M10)用于确定图像质心( Xc,Yc):

Xc = M10/M00;Yc = M01/M00;

若将坐标原点移至 Xc和 Yc处,就得到了对于图像位移不变的中心矩。如

Upq =∫∫[(x-Xc)^p]*[(y-Yc)^q]f(x,y)dxdy。

Hu在文中提出了7个几何矩的不变量,这些不变量满足于图像平移、伸缩和旋转不变。如果定义

Zpq=Upq/(U20 + U02)^(p+q+2),

Hu 的7种矩为:

H1=Z20+Z02;H1=(Z20+Z02)^2+4Z11^2;......

矩是描述图像特征的算子,它在模式识别与图像分析领域中有重要的应用.迄今为止,常见的矩描述子可以分为以下几种:几何矩、正交矩、复数矩和旋转矩.其中几何矩提出的时间最早且形式简单,对它的研究最为充分。几何矩对简单图像有一定的描述能力,他虽然在区分度上不如其他三种矩,但与其他几种算子比较起来,他极其的简单,一般只需用一个数字就可表达。所以,一般我们是用来做大粒度的区分,用来过滤显然不相关的文档。

比如在图形库中,可能有100万幅图,也许只有200幅图是我们想要的。使用一维的几何矩的话,就可以对几何矩进行排序,建立索引,然后选出与目标图的几何矩最近的2000幅图作比较就好了。而对于其他的矩来说,由于一般是多维的关系,一般不好排序,只能顺序查找,自然速度有巨大的差别.所以。虽然几何矩不太能选出最像的,但可以快速排除不像的,提高搜索效率。

MATLAB代码:

img=

invariable_moment(imread('lena.jpg'));
function inv_m7 = invariable_moment(in_image)
% 功能:计算图像的Hu的七个不变矩
% 输入:in_image-RGB图像
% 输出:inv_m7-七个不变矩% 将输入的RGB图像转换为灰度图像
image=rgb2gray(in_image);
%将图像矩阵的数据类型转换成双精度型
image=double(image);
%%%=================计算 、 、 =========================
%计算灰度图像的零阶几何矩
m00=sum(sum(image));
m10=0;
m01=0;
[row,col]=size(image);
for i=1:rowfor j=1:colm10=m10+i*image(i,j);m01=m01+j*image(i,j);end
end
%%%=================计算 、 ================================
u10=m10/m00;
u01=m01/m00;
%%%=================计算图像的二阶几何矩、三阶几何矩============
m20 = 0;m02 = 0;m11 = 0;m30 = 0;m12 = 0;m21 = 0;m03 = 0;
for i=1:rowfor j=1:colm20=m20+i^2*image(i,j);m02=m02+j^2*image(i,j);m11=m11+i*j*image(i,j);m30=m30+i^3*image(i,j);m03=m03+j^3*image(i,j);m12=m12+i*j^2*image(i,j);m21=m21+i^2*j*image(i,j);end
end
%%%=================计算图像的二阶中心矩、三阶中心矩============
y00=m00;
y10=0;
y01=0;
y11=m11-u01*m10;
y20=m20-u10*m10;
y02=m02-u01*m01;
y30=m30-3*u10*m20+2*u10^2*m10;
y12=m12-2*u01*m11-u10*m02+2*u01^2*m10;
y21=m21-2*u10*m11-u01*m20+2*u10^2*m01;
y03=m03-3*u01*m02+2*u01^2*m01;
%%%=================计算图像的归格化中心矩====================n20=y20/m00^2;n02=y02/m00^2;n11=y11/m00^2;n30=y30/m00^2.5;n03=y03/m00^2.5;n12=y12/m00^2.5;n21=y21/m00^2.5;
%%%=================计算图像的七个不变矩======================
h1 = n20 + n02;
h2 = (n20-n02)^2 + 4*(n11)^2;
h3 = (n30-3*n12)^2 + (3*n21-n03)^2;
h4 = (n30+n12)^2 + (n21+n03)^2;
h5 = (n30-3*n12)*(n30+n12)*((n30+n12)^2-3*(n21+n03)^2)+(3*n21-n03)*(n21+n03)*(3*(n30+n12)^2-(n21+n03)^2);
h6 = (n20-n02)*((n30+n12)^2-(n21+n03)^2)+4*n11*(n30+n12)*(n21+n03);h7 = (3*n21-n03)*(n30+n12)*((n30+n12)^2-3*(n21+n03)^2)+(3*n12-n30)*(n21+n03)*(3*(n30+n12)^2-(n21+n03)^2);inv_m7= [h1 h2 h3 h4 h5 h6 h7];

c++代码:

/*===============================================//
功能:不变矩匹配
时间:3/28/2011 SkySeraph HQU
参考:
//===============================================*/
#include "iostream"usingnamespace std;#include "cv.h"
#include "highgui.h"#include "math.h"#pragma comment(lib,"highgui.lib")
#pragma comment(lib,"cv.lib")
#pragma comment(lib,"cvaux.lib")
#pragma comment(lib,"cxcore.lib")constchar* filename ="D:\\My Documents\\My Pictures\\Images\\1.bmp";
constchar* filename2 ="D:\\My Documents\\My Pictures\\Images\\2.bmp";/*=============================================*/
double M[7] = {0}; //HU不变矩bool HuMoment(IplImage* img)
{int bmpWidth = img->width;
int bmpHeight = img->height;
int bmpStep = img->widthStep;
int bmpChannels = img->nChannels;
uchar*pBmpBuf = (uchar*)img->imageData;double m00=0,m11=0,m20=0,m02=0,m30=0,m03=0,m12=0,m21=0; //中心矩
double x0=0,y0=0; //计算中心距时所使用的临时变量(x-x')
double u20=0,u02=0,u11=0,u30=0,u03=0,u12=0,u21=0;//规范化后的中心矩
//double M[7]; //HU不变矩
double t1=0,t2=0,t3=0,t4=0,t5=0;//临时变量,
//double Center_x=0,Center_y=0;//重心
int Center_x=0,Center_y=0;//重心
int i,j; //循环变量// 获得图像的区域重心
double s10=0,s01=0,s00=0; //0阶矩和1阶矩 //注:二值图像的0阶矩表示面积
for(j=0;j<bmpHeight;j++)//y
{
for(i=0;i<bmpWidth;i++)//x
{
s10+=i*pBmpBuf[j*bmpStep+i];
s01+=j*pBmpBuf[j*bmpStep+i];
s00+=pBmpBuf[j*bmpStep+i];
}
}
Center_x=(int)(s10/s00+0.5);
Center_y=(int)(s01/s00+0.5);// 计算二阶、三阶矩
m00=s00;
for(j=0;j<bmpHeight;j++)
{
for(i=0;i<bmpWidth;i++)//x
{
x0=(i-Center_x);
y0=(j-Center_y);
m11+=x0*y0*pBmpBuf[j*bmpStep+i];
m20+=x0*x0*pBmpBuf[j*bmpStep+i];
m02+=y0*y0*pBmpBuf[j*bmpStep+i];
m03+=y0*y0*y0*pBmpBuf[j*bmpStep+i];
m30+=x0*x0*x0*pBmpBuf[j*bmpStep+i];
m12+=x0*y0*y0*pBmpBuf[j*bmpStep+i];
m21+=x0*x0*y0*pBmpBuf[j*bmpStep+i];
}
} // 计算规范化后的中心矩
u20=m20/pow(m00,2);
u02=m02/pow(m00,2);
u11=m11/pow(m00,2);
u30=m30/pow(m00,2.5);
u03=m03/pow(m00,2.5);
u12=m12/pow(m00,2.5);
u21=m21/pow(m00,2.5);// 计算中间变量。
t1=(u20-u02);
t2=(u30-3*u12);
t3=(3*u21-u03);
t4=(u30+u12);
t5=(u21+u03);// 计算不变矩
M[0]=u20+u02;
M[1]=t1*t1+4*u11*u11;
M[2]=t2*t2+t3*t3;
M[3]=t4*t4+t5*t5;
M[4]=t2*t4*(t4*t4-3*t5*t5)+t3*t5*(3*t4*t4-t5*t5);
M[5]=t1*(t4*t4-t5*t5)+4*u11*t4*t5;
M[6]=t3*t4*(t4*t4-3*t5*t5)-t2*t5*(3*t4*t4-t5*t5);/*cout<<M[0]<<endl;//<<二"<<M[0]<<"三"<<M[0]<<"四"<<M[0]<<"五"<<M[0]<<"六"<<M[0]<<"七"<<M[0]<<endl;
cout<<M[1]<<endl;
cout<<M[2]<<endl;
cout<<M[3]<<endl;
cout<<M[4]<<endl;
cout<<M[5]<<endl;
cout<<M[6]<<endl;
cout<<endl;*/
returntrue;
}int main(char argc,char** argv)
{
int i;
double Sa[7] = {0},Ta[7] ={0};///*源图像
IplImage*img = cvLoadImage(filename,0);//灰度
HuMoment(img);
for(i=0;i<7;i++)
{
Sa[i] = M[i];
M[i] =0;
}
cout<<Sa[0]<<endl;
cout<<Sa[1]<<endl;
cout<<Sa[2]<<endl;
cout<<Sa[3]<<endl;
cout<<Sa[4]<<endl;
cout<<Sa[5]<<endl;
cout<<Sa[6]<<endl;
cout<<endl;
//*////*模板图
IplImage*tpl = cvLoadImage(filename2,0);//灰度
HuMoment(tpl);
for(i=0;i<7;i++)
{
Ta[i] = M[i];
M[i] =0;
}
cout<<Ta[0]<<endl;
cout<<Ta[1]<<endl;
cout<<Ta[2]<<endl;
cout<<Ta[3]<<endl;
cout<<Ta[4]<<endl;
cout<<Ta[5]<<endl;
cout<<Ta[6]<<endl;
cout<<endl;// 计算相似度
double dbR =0; //相似度
double dSigmaST =0;
double dSigmaS =0;
double dSigmaT =0;
double temp =0; for(i=0;i<7;i++)
{
temp = Sa[i]*Ta[i];
dSigmaST+=temp;
dSigmaS+=pow(Sa[i],2);
dSigmaT+=pow(Ta[i],2);
}
dbR = dSigmaST/(sqrt(dSigmaS)*sqrt(dSigmaT));
printf("%lf\n",dbR);
//cout<<dbR<<endl;cvReleaseImage(&img);
cvReleaseImage(&tpl);return0;
}

其他几种矩的比较可以参考这篇文章:

点击打开链接

图像的七个不变矩 可用于图像的匹配相关推荐

  1. 图像语义分割_图像语义分割(9)-DeepLabV3: 再次思考用于图像语义分割的空洞卷积...

    论文地址 :Rethinking Atrous Convolution for Semantic Image Segmentation 论文代码:Github链接 1. 摘要 文章主要的工作: 使用空 ...

  2. 输电线路巡检红外图像与可见光图像融合数据集(含分割标签,1700多张图像),可见光图像,红外灰度图像,一一对应可用于图像配准

    下载地址 :输电线路巡检红外图像与可见光图像融合数据集

  3. 【Gated Context Aggregation Network for Image Dehazing and Deraining用于图像去雾和去雨的门控上下文聚合网络】,个人笔记,勿喷

    摘要 图像去雾旨在从模糊图像中恢复未损坏的内容.我们没有利用传统的低级或手工图像先验作为恢复约束,例如暗通道和增加的对比度,而是提出了一个端到端的门控上下文聚合网络来直接恢复最终的无雾图像.在这个网络 ...

  4. 视觉进阶 | 用于图像降噪的卷积自编码器

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 本文转自:磐创AI 作者|Dataman 编译|Arno 来源|A ...

  5. Siamese Network (应用篇2) :孪生网络用于图像块匹配 CVPR2015

    参考论文:Zagoruyko S, Komodakis N. Learning to compare image patches via convolutional neural networks[J ...

  6. Facebook推出Pythia 开源 可用于图像及语言分析

    Facebook在人工智能方面投入了大量资源,成果也陆续开源的.最近,其深度学习框架Pythia是开源的,可用于图像和语言分析,以便于相关人工智能模型的建立,复制和测试. 根据Facebook,Pyt ...

  7. SIFT算法总结:用于图像搜索

    原始文章链接:http://bubblexc.com/y2011/163/ 原文链接:http://blog.csdn.net/cserchen/article/details/5606859 关于三 ...

  8. flask渲染图像_用于图像推荐的Flask应用

    flask渲染图像 After creating a Python-based machine learning application you might want to get it runnin ...

  9. 【图像处理】——Python OpenCV实现形态学膨胀、腐蚀开闭操作(可以用于图像滤波、图像分割等)

    转载博客请注明详细地址,谢谢 本文讲了形态学基本操作膨胀腐蚀开闭操作的原理 本文讲解了用OpenCV-Python实现形态学操作 目录 一.形态学简述 1.简介 2.一些基本定义 3.结构元素 (1) ...

最新文章

  1. no output in console for unittests in pycharm 2017
  2. 《美团点评编程题》整数加法
  3. Java 类的特性1
  4. java 输入流关闭顺序_Java IO流中先关闭输出流还是先关闭输入流?为什么?
  5. php hash代码下载,PHP中的哈希表 hash_insert
  6. C语言程序设计预报作业
  7. 多媒体音频格式解析WMA WAV OGG AAC APE FLAC
  8. 云化要求下,数据库架构如何演进?
  9. SQL Server 2019中的行模式内存授予反馈
  10. 病毒防疫管理系统基于VS2017 .netcore2.2
  11. 使用rundll32.exe绕过应用程序白名单(多种方法)
  12. QML 环形进度条canvas 98行代码实现
  13. html浮窗音乐播放器插件,墨涩网 - WordPress浮窗音乐播放器Floating Window Music Player V3.2.6——墨涩网...
  14. Golang defer、panic和recover
  15. latex编辑公式好用的在线网址
  16. 对登录验证功能进行GUI设计
  17. 2022年最新上海机动车签字授权人模拟考试及答案
  18. 聚合架构-晓岩企业架构系列讲座整理(0-19)
  19. 新手在IDEA如何创建一个Web项目
  20. 了解iPhone OS框架

热门文章

  1. 在WINCE5.0中应用CMD(比如运行PING命令)
  2. Pat乙级 1045 快速排序
  3. 检测数据类型的几种方式
  4. IDC:全球物联网支出将在2019年达到1.3万亿美元
  5. eclipse配置tomcat8.5
  6. 我的Android进阶之旅------gt;Android中MediaRecorder.stop()报错 java.lang.RuntimeException: stop failed....
  7. 探秘推荐引擎之协同过滤算法小综述
  8. jquery easyui 弹出对话框被activex控件遮挡问题
  9. 学习《Hardware-Efficient Bilateral Filtering for Stereo Matching》一文笔记。
  10. ntp时间服务器配置