opencv中Hu矩的学习心得
Hu矩的确很神奇,它具有平移不变性、旋转不变性和缩放不变性,是图形匹配的一个不错的工具。
通过大致对Hu矩的学习,我认为对Hu矩的学习应该有一下几步,第一步要了解什么是矩;第二步再开始了解Hu矩。为了方便大家的使用,先简单介绍下Hu矩用于模板匹配的用法。
用法:
其实Hu矩用于匹配已经在opencv中的cvMatchShape函数中应用了,下面是cvMatchShape的源代码(可以跳过):
cvMatchShapes( const void* contour1, const void* contour2,
int method, double )
{
CvMoments moments;
CvHuMoments huMoments;
double ma[7], mb[7];
int i, sma, smb;
double eps = 1.e-5;
double mmm;
double result = 0;
CV_FUNCNAME( "cvMatchShapes" );
__BEGIN__;
if( !contour1 || !contour2 )
CV_ERROR( CV_StsNullPtr, "" );
CV_CALL( cvMoments( contour1, &moments ));
CV_CALL( cvGetHuMoments( &moments, &huMoments ));
ma[0] = huMoments.hu1;
ma[1] = huMoments.hu2;
ma[2] = huMoments.hu3;
ma[3] = huMoments.hu4;
ma[4] = huMoments.hu5;
ma[5] = huMoments.hu6;
ma[6] = huMoments.hu7;
CV_CALL( cvMoments( contour2, &moments ));
CV_CALL( cvGetHuMoments( &moments, &huMoments ));
mb[0] = huMoments.hu1;
mb[1] = huMoments.hu2;
mb[2] = huMoments.hu3;
mb[3] = huMoments.hu4;
mb[4] = huMoments.hu5;
mb[5] = huMoments.hu6;
mb[6] = huMoments.hu7;
switch (method)
{
case 1:
{
for( i = 0; i < 7; i++ )
{
double ama = fabs( ma[i] );
double amb = fabs( mb[i] );
if( ma[i] > 0 )
sma = 1;
else if( ma[i] < 0 )
sma = -1;
else
sma = 0;
if( mb[i] > 0 )
smb = 1;
else if( mb[i] < 0 )
smb = -1;
else
smb = 0;
if( ama > eps && amb > eps )
{
ama = 1. / (sma * log10( ama ));
amb = 1. / (smb * log10( amb ));
result += fabs( -ama + amb );
}
}
break;
}
case 2:
{
for( i = 0; i < 7; i++ )
{
double ama = fabs( ma[i] );
double amb = fabs( mb[i] );
if( ma[i] > 0 )
sma = 1;
else if( ma[i] < 0 )
sma = -1;
else
sma = 0;
if( mb[i] > 0 )
smb = 1;
else if( mb[i] < 0 )
smb = -1;
else
smb = 0;
if( ama > eps && amb > eps )
{
ama = sma * log10( ama );
amb = smb * log10( amb );
result += fabs( -ama + amb );
}
}
break;
}
case 3:
{
for( i = 0; i < 7; i++ )
{
double ama = fabs( ma[i] );
double amb = fabs( mb[i] );
if( ma[i] > 0 )
sma = 1;
else if( ma[i] < 0 )
sma = -1;
else
sma = 0;
if( mb[i] > 0 )
smb = 1;
else if( mb[i] < 0 )
smb = -1;
else
smb = 0;
if( ama > eps && amb > eps )
{
ama = sma * log10( ama );
amb = smb * log10( amb );
mmm = fabs( (ama - amb) / ama );
if( result < mmm )
result = mmm;
}
}
break;
}
default:
CV_ERROR_FROM_STATUS( CV_BADCOEF_ERR );
}
__END__;
return result;
}
因此,我们只需要传入两个轮廓或两幅图片,再选择一种评价的方式,就可以用这个函数进行匹配了,至于hu矩,在这个函数中已经帮我们计算好了,我们只需要选择一种匹配的方法就可以的到一个评价相似性的值了,该函数提供了三种方法来评价这两幅图的相似性,值越小越相似。
如果我们要单独计算hu矩怎么办??
opencv中有一个结构体叫CvMoments,他的定义是
typedef struct CvMoments
{
double m00, m10, m01, m20, m11, m02, m30, m21, m12, m03;
double mu20, mu11, mu02, mu30, mu21, mu12, mu03;
double inv_sqrt_m00;
}
CvMoments;
这个结构体是用来保存矩的数据的,其中第一行是普通矩,第二行是中心距。接着有一个函数叫做CVAPI(void) cvMoments( const CvArr* arr, CvMoments* moments, int binary CV_DEFAULT(0));,这个函数是用来计算矩的,其中第一个参数是传入的图像,第二个参数是之前创建的CvMoments变量,第三个参数是是否二值化(如果是0的话,那么原图像是什么值就是什么值,如果大于0,就二值化,其中阀值我也不知道怎么确定的,但是和这个参数是没有关系的)。
同样,要计算Hu矩也有一个结构体叫CvHuMoments,他的定义是
typedef struct CvHuMoments
{
double hu1, hu2, hu3, hu4, hu5, hu6, hu7;
}
CvHuMoments;
这里用于储存计算出来的七个值,同时又有一个函数叫CVAPI(void) cvGetHuMoments( CvMoments* moments, CvHuMoments* hu_moments );用来计算Hu矩,其中第一个参数就是上面所计算好的moments,第二个参数就是刚创建的CvHuMoments hu_moments,计算的结果就保存的这个变量中。
以上就是我认为用hu矩进行模板匹配的方法了。
接下来我按照第二段所述的步骤介绍下我对Hu矩的理解:
第一步什么是矩:个人认为,矩的理解可以从力矩上,在高中物理上力矩的定义是力乘以力臂,所以在图像中的矩也可以这么认为,它的定义参照http://www.cnblogs.com/skyseraph/archive/2011/07/19/2110183.html中所述,其中Xpq中p+q的值称为矩的阶数。
第二步什么是hu矩:hu矩就是利用矩里边的1阶矩、二阶矩和三阶矩经过算术运算构造出来的具有平移、缩放和旋转不变性的七个矩,在上面的网址中也有讲到,我也是从上面的那个网址中学习过。
本人初学opencv,以上仅是本人学习Hu矩的一点心得,如有发现错误,请回复,我将尽快更改,同时也希望对和我一样的初学者有一丝丝的帮助。
最后非常感谢以下作品及其作者:
http://www.cnblogs.com/skyseraph/archive/2011/07/19/2110183.html
http://v.youku.com/v_show/id_XNDcyOTE3MzQ4.html
opencv中Hu矩的学习心得相关推荐
- OpenCV 中的矩(moments)和 Hu不变矩(HuMoments)
文章目录 引言 矩的定义 OpenCV中的矩(moments) OpenCV中的Hu不变矩(HuMoments) 矩的应用 代码示例 参考链接 引言 我们在图像处理的任务中,常常需要对某些形状区域进行 ...
- 中科大高级软件工程学习心得体会
中科大高级软件工程学习心得体会 在本门课程中,首先我对一些基本开发工具,如VSCode.Git.Vim.正则表达式等,重新审视了自己的认知,顺便学了一手shell编程,并在课程的基础上又自定义了很多配 ...
- 学习OpenCV:hu矩
hu矩为描述整体图像特征的一种方法,零阶矩表示它的总质量:一阶矩表示它的质心:二阶矩又叫惯性矩,表示图像的大小和方向. 通过计算普通矩可以知道图像的重心坐标.形状方向等: Moments 中的数据类型 ...
- android opencv hu moment,学习OpenCV:hu矩
hu矩为描述整体图像特征的一种方法,零阶矩表示它的总质量:一阶矩表示它的质心:二阶矩又叫惯性矩,表示图像的大小和方向. 通过计算普通矩可以知道图像的重心坐标.形状方向等: Mat imgSrc = i ...
- Hu矩的学习,图像轮廓特征识别(二,c#实现)
不变矩介绍: 先看教课书上的公式: 再看网上很认真的论文: 最后看冈萨雷斯的: Hu矩5,7的公式有争议,我采用数字图像处理冈萨雷斯三版的公式,不过,感到还是不满意,有问题. 我们获取轮廓的特征,在此 ...
- OpenCV中parallel_for 和 parallel_for_学习笔记
OpenCV 从2.4.3开始加入了并行计算的函数parallel_for和parallel_for_(更准确地讲,parallel_for以前就存在于tbb模块中,但是OpenCV官网将其列在2.4 ...
- java中finalizer终结方法学习心得
最近在看java的中finalizer终结方法,也就是用来释放内存的,但这绝对和C++中的析构函数不相同 C++中的析构函数是用来回收对象所占用的资源的方法,而在java中,当一个对象不可到达时(也就 ...
- 在OpenCV中基于深度学习的边缘检测
点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 本文转自:AI算法与图像处理 导读 分析了Canny的优劣,并给出 ...
- 深入学习OpenCV中图像相似度的算法
最近一段时间学习并做的都是对图像进行处理,其实自己也是新手,各种尝试,所以我这个门外汉想总结一下自己学习的东西,图像处理的流程.但是动起笔来想总结,一下却不知道自己要写什么,那就把自己做过的相似图片搜 ...
最新文章
- 深入浅出K-Means算法
- Git之Stash(储藏)备份当前的工作区的内容
- 日期与时间(C/C++)
- Java面试题2021,文末有福利
- Linux系统编程7:入门篇之Linux项目自动化构建工具-Make/Makefile的超强使用指南
- Java网络编程之Socket和ServerSocket详解
- angular日期输入框html,html5 – Angular2:日期格式文本框ngModel不起作用
- java socket中的方法_Java中关于Socket的方法与作用详解
- JVM监控及诊断工具命令行篇之jstatd
- python程序设计基础
- LM358芯片中文资料(搬运)
- 【谷粒商城】【认证服务】验证码、社交登录、分布式session、单点登录
- PCB板材及生产流程详述
- 网络攻击术语(Technical terms of the attacks)
- 用eviews做svar模型_SVAR模型制作过程
- CVE-2013-5211漏洞整改方法
- 什么情况下选用mysql_在MySQL中,‘%’可以用在什么情况下?
- Android 强制设置横屏或竖屏 设置全屏
- 模拟动态登录,获取cookie和图片验证码登录(AcFun和豆瓣)
- 关于DEJA_VU3D - Cesium功能集专栏说明
热门文章
- 使用了flink官方示例,尽然提交任务后报错了
- 永信至诚蔡晶晶:用有温度的技术培育信息时代的安全感
- 【数电】(组合逻辑电路)组合逻辑电路的分析和设计方法
- java 中char占了几个字节
- B2 - H - Historic Exhibition(二分图匹配+优化建图)
- Android数据库与ContentProvider
- 同花顺趋势启动,低位启动 趋势指导指标源码
- 计算机领域经典故事,[转载]计算机的工作原理(1):一个经典的故事
- 如何生成和使用CLIPS动态链接库
- #python #jupyter notebook# to_excel将多个表格写入EXCEL一个sheet中