在OpenCV中,可以很方便的计算多边形区域的3阶特征矩,opencv中的矩主要包括以下几种:空间矩,中心矩和中心归一化矩。

class Moments { public: ...... // 空间矩 double m00, m10, m01, m20, m11, m02, m30, m21, m12, m03; // 中心矩 double mu20, mu11, mu02, mu30, mu21, mu12, mu03; // 中心归一化矩 double nu20, nu11, nu02, nu30, nu21, nu12, nu03; }空间矩的公式为:

可以知道,对于01二值化的图像,m00即为轮廓的面积。中心矩的公式为:

其中:

归一化的中心矩公式为:

 

矩的基本概念可参考:

http://www.opencvchina.com/thread-509-1-1.html
 

在OpenCV中,还可以很方便的得到Hu不变距,Hu不变矩在图像旋转、缩放、平移等操作后,仍能保持矩的不变性,所以有时候用Hu不变距更能识别图像的特征。Hu不变矩的基本概念请参考paper:Hu. Visual Pattern Recognition by Moment Invariants, IRE Transactions on Information Theory, 8:2, pp. 179-187, 1962, 或者参考中文介绍:http://www.cnblogs.com/skyseraph/archive/2011/07/19/2110183.html

 

OpenCV中计算矩的函数为:Moments moments(InputArray array, bool binaryImage=false )

 

Hu不变矩主要是利用归一化中心矩构造了7个不变特征矩:

OpenCV中计算Hu矩的公式为:

HuMoments(const Moments& m, OutputArray hu)

void HuMoments(const Moments& moments, double hu[7])

下面的代码计算轮廓的矩,并根据1阶中心矩得到轮廓的质心,代码如下:

src = imread( "../star1.jpg" ,1 );

/// Convert image to gray and blur itcvtColor( src, src_gray, CV_BGR2GRAY );blur( src_gray, src_gray, Size(3,3) );

namedWindow( "image", CV_WINDOW_AUTOSIZE );imshow( "image", src );

Mat canny_output;vector<vector<Point> > contours;vector<Vec4i> hierarchy;

//利用canny算法检测边缘Canny( src_gray, canny_output, thresh, thresh*2, 3 );namedWindow( "canny", CV_WINDOW_AUTOSIZE );imshow( "canny", canny_output );//查找轮廓findContours( canny_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );

//计算轮廓矩vector<Moments> mu(contours.size() );for( int i = 0; i < contours.size(); i++ )    { mu[i] = moments( contours[i], false ); }

//计算轮廓的质心vector<Point2f> mc( contours.size() );for( int i = 0; i < contours.size(); i++ )    { mc[i] = Point2f( mu[i].m10/mu[i].m00 , mu[i].m01/mu[i].m00 ); }

//画轮廓及其质心Mat drawing = Mat::zeros( canny_output.size(), CV_8UC3 );for( int i = 0; i< contours.size(); i++ )    {    Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) );    drawContours( drawing, contours, i, color, 2, 8, hierarchy, 0, Point() );    circle( drawing, mc[i], 4, color, -1, 8, 0 );    }

namedWindow( "Contours", CV_WINDOW_AUTOSIZE );imshow( "Contours", drawing );

//打印轮廓面积和轮廓长度printf("\t Info: Area and Contour Length \n");for( int i = 0; i< contours.size(); i++ )    {    printf(" * Contour[%d] - Area (M_00) = %.2f - Area OpenCV: %.2f - Length: %.2f \n", i, mu[i].m00, contourArea(contours[i]), arcLength( contours[i], true ) );    Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) );    drawContours( drawing, contours, i, color, 2, 8, hierarchy, 0, Point() );    circle( drawing, mc[i], 4, color, -1, 8, 0 );    }

程序执行后效果图:

最后我们再利用matchShape函数比较两个轮廓,如果结果为0,表示两个轮廓完全相似,结果值越大,越不相似,但这个最大值好像并没有归一化,我曾经比较两个轮廓,结果值达到了10。

比较的代码为:

double comres;
comres = matchShapes(contours[0], contours[1],CV_CONTOURS_MATCH_I1, 0.0);
printf("CV_CONTOURS_MATCH_I1 比较结果是: %f\n", comres);
comres = matchShapes(contours[0], contours[1],CV_CONTOURS_MATCH_I2, 0.0);
printf("CV_CONTOURS_MATCH_I2 比较结果是: %f\n", comres);
comres = matchShapes(contours[0], contours[1],CV_CONTOURS_MATCH_I3, 0.0);
printf("CV_CONTOURS_MATCH_I3 比较结果是: %f\n", comres);

matchShapes函数其实比较的是两个轮廓的Hu不变矩,第三个参数决定比较的方式,下面是第三个参数的三个可选值。

  • CV_CONTOURS_MATCH_I1

  • CV_CONTOURS_MATCH_I2

  • CV_CONTOURS_MATCH_I3

这里:

分别是A,B的Hu矩。

程序代码:工程FirstOpenCV29

OpenCV学习(33) 轮廓的特征矩Moment相关推荐

  1. copyTo函数、随机数产生器 RNG、轮廓的特征矩 Moment、cvGet2D函数

    C++ byte 类型 在头文件 windows.h 中 OpenCV 中,IplImage 所在头文件为 #include<highgui/highgui_c.h> 文章目录 1.cop ...

  2. OpenCV学习(30) 轮廓defects

    https://www.cnblogs.com/mikewolf2002/p/3426652.html 上一篇教程中,我们学习了如何计算轮廓的凸包,其实对一个轮廓而言,可能它的凸包和它本身是重合的,也 ...

  3. 结合openCV学习DIP之传统图像特征与匹配

    前言 关于图像的预处理部分参考  结合opencv学习DIP​​​​​​​ 概述 该笔记主要是基于DIP理论➕openCV实现,学习该笔记首先要确保通读DIP理论,并由自己的话描述相关知识,并且掌握o ...

  4. OpenCV学习笔记(九)——图像轮廓(下)

    <OpenCV轻松入门:面向Python>学习笔记(九) 1-3 查找并绘制轮廓.矩特性及Hu矩 4-5 轮廓拟合及凸包 6. 利用形状场景算法比较轮廓 6.1 计算形状场景距离 6.2 ...

  5. OpenCV学习——轮廓检测

    前言 轮廓检测是传统视觉中非常常用的功能,这里简单记录一下opencv中的轮廓检测算法使用方法,至于理论,后续有机会再去细品. 国际惯例: OpenCV官方的轮廓检测教程python版 OpenCV中 ...

  6. 图像或轮廓的Hu矩的定义、优缺点、适用范围,并利用OpenCV的函数HuMoments()和matchShapes()实现Hu矩的计算和轮廓匹配

    本文承接博主的上一篇博文: 什么叫图像或轮廓的空间矩.中心矩.归一化中心矩?并利用OpenCV的类Moments计算轮廓的这几个矩和质心位置 继续介绍Hu矩的相关知识. Hu矩是由二阶和三阶中心距计算 ...

  7. 【OpenCV学习笔记】之图像轮廓特征与图像的矩

    一.图像的轮廓(Contours of Image) 轮廓可以说是一个很好的图像目标的外部特征,这种特征对于我们进行图像分析,目标识别和理解等更深层次的处理都有很重要的意义.那么,怎么取提取轮廓呢? ...

  8. OPENCV学习笔记 - SIFT 尺度不变特征变换 Python

    OPENCV学习笔记 - SIFT 尺度不变特征变换 Python 为什么我们需要SIFT尺度不变特征变换? 第一,建立高斯差分金字塔 第二,极值点的精确定位 第三,确定关键点的主方向 第四,构建关键 ...

  9. OpenCV学习笔记(四十六)——FAST特征点检测features2D OpenCV学习笔记(四十七)——VideoWriter生成视频流highgui OpenCV学习笔记(四十八)——PCA算

    OpenCV学习笔记(四十六)--FAST特征点检测features2D 特征点检测和匹配是计算机视觉中一个很有用的技术.在物体检测,视觉跟踪,三维常年关键等领域都有很广泛的应用.这一次先介绍特征点检 ...

最新文章

  1. 如何为jframe设置于右侧滑轮_如何为电脑设置屏保密码?
  2. ORACLE用户权限管理笔记整理
  3. Android内存分析和调优
  4. Windows XP \Windows 2003启动过程的学习及故障分析处理(四)
  5. Javascript 問題汇总(不定期更新)【一】
  6. [vc]如何对radio按钮分组
  7. linux下测试权限,Linux下进程权限分析
  8. Java之品优购课程讲义_day05(8)
  9. asp.net中DataList和Repeater的使用
  10. 持久层框架:Mybatis快速入门
  11. 解决联想笔记本电源选项 电源管理无效
  12. ES6 阮一峰阅读学习
  13. 网络拓扑图js插件——jTopo应用
  14. STM32配置全速USB与Python上位机传输数据步骤
  15. 系统架构图 云架构案例
  16. matlab中多项式拟合polyfit()和插值函数polyval()的基础使用方法和历程
  17. PHP叫号系统,排队叫号系统
  18. 服务器显示504,帮您解决win7系统访问nginx服务器提示504 Gateway Time-out错误的修复技巧...
  19. Spring Security 之 Remember-Me (记住我)
  20. BCG 使用之CBCGPProgressDlg进度条使用

热门文章

  1. 动态规划:二维费用背包
  2. SQL SERVER 如果判断text类型数据不为空
  3. Java程序员从笨鸟到菜鸟之(一)开发环境搭建,基本语法,字符串,数组
  4. 从frame跳转到一个新的页面
  5. 这样写交互说明,开发不会约你去爬山~
  6. 必要商城高级UED经理张不写:设计师如何规划职业方向
  7. 行业 | 调查:移动游戏盈利60%来源于0.23%付费玩家
  8. 如何高效输出移动app产品原型?
  9. io类游戏快速开发 2
  10. 工程师如何解决穿衣搭配烦恼?——滴搭平台与算法