Goal

在本教程中,您将学习如何:

使用 OpenCV 函数 cv::moments

使用 OpenCV 函数 cv::contourArea

使用 OpenCV 函数 cv::arcLength

Theory

Code

本教程代码如下所示。 你也可以从这里下载

https://github.com/opencv/opencv/tree/4.x/samples/cpp/tutorial_code/ShapeDescriptors/moments_demo.cpp

/*** @function moments_demo.cpp* @brief Demo code to calculate moments* @author OpenCV team*/#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include <iostream>
#include <iomanip>using namespace cv;
using namespace std;Mat src_gray;
int thresh = 100;//边缘检测阈值
RNG rng(12345);/// Function header
void thresh_callback(int, void* );/*** @function main*/
int main( int argc, char** argv )
{/// Load source imageCommandLineParser parser( argc, argv, "{@input | stuff.jpg | input image}" );Mat src = imread( samples::findFile( parser.get<String>( "@input" ) ) );if( src.empty() ){cout << "Could not open or find the image!\n" << endl;cout << "usage: " << argv[0] << " <Input image>" << endl;return -1;}/// Convert image to gray and blur itcvtColor( src, src_gray, COLOR_BGR2GRAY );blur( src_gray, src_gray, Size(3,3) );/// Create Windowconst char* source_window = "Source";namedWindow( source_window );imshow( source_window, src );const int max_thresh = 255;createTrackbar( "Canny thresh:", source_window, &thresh, max_thresh, thresh_callback );thresh_callback( 0, 0 );waitKey();return 0;
}/*** @function thresh_callback*/
void thresh_callback(int, void* )
{/// Detect edges using cannyMat canny_output;Canny( src_gray, canny_output, thresh, thresh*2, 3 );/// Find contoursvector<vector<Point> > contours;findContours( canny_output, contours, RETR_TREE, CHAIN_APPROX_SIMPLE );/// 计算矩Get the momentsvector<Moments> mu(contours.size() );for( size_t i = 0; i < contours.size(); i++ ){//https://zhuanlan.zhihu.com/p/101297923 mu[i] = moments( contours[i] );//多边形的矩}/// 获取质心 Get the mass centersvector<Point2f> mc( contours.size() );for( size_t i = 0; i < contours.size(); i++ ){//add 1e-5 to avoid division by zero 添加 1e-5 以避免被零除mc[i] = Point2f( static_cast<float>(mu[i].m10 / (mu[i].m00 + 1e-5)),static_cast<float>(mu[i].m01 / (mu[i].m00 + 1e-5)) );//计算多边形的质心:一阶矩/零阶矩cout << "mc[" << i << "]=" << mc[i] << endl;//输出质心坐标}/// 绘制轮廓Draw contoursMat drawing = Mat::zeros( canny_output.size(), CV_8UC3 );for( size_t i = 0; i< contours.size(); i++ ){Scalar color = Scalar( rng.uniform(0, 256), rng.uniform(0,256), rng.uniform(0,256) );//随机颜色drawContours( drawing, contours, (int)i, color, 2 );//绘制轮廓circle( drawing, mc[i], 4, color, -1 );//绘制质心}/// 在窗口显示 Show in a windowimshow( "Contours", drawing );/// Calculate the area with the moments 00 and compare with the result of the OpenCV function//计算矩为 00 的面积并与 OpenCV 函数的结果进行比较cout << "\t Info: Area and Contour Length \n";for( size_t i = 0; i < contours.size(); i++ ){cout << " * Contour[" << i << "] - Area (M_00) = " << std::fixed << std::setprecision(2) << mu[i].m00<< " - Area OpenCV: " << contourArea(contours[i]) << " - Length: " << arcLength( contours[i], true ) << endl;}
}

Explanation

Result

参考:

【从零学习OpenCV 4】图像矩的计算与应用 - 知乎 (zhihu.com)

OpenCV学习(33) 轮廓的特征矩Moment

OpenCV学习(33) 轮廓的特征矩Moment - 迈克老狼2012 - 博客园 (cnblogs.com)

在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即为轮廓的面积。

中心矩的公式为:

其中:

归一化的中心矩公式为:

OpenCV中计算矩的函数为:Moments

moments(InputArray array, bool binaryImage=false )

在OpenCV中,还可以很方便的得到Hu不变距,Hu不变矩在图像旋转、缩放、平移等操作后,仍能保持矩的不变性,所以有时候用Hu不变距更能识别图像的特征。Hu不变矩的基本概念请参考paper:Hu. Visual Pattern Recognition by Moment Invariants, IRE Transactions on Information Theory, 8:2, pp. 179-187, 1962, 或者参考中文介绍:【图像算法】图像特征:几何不变矩--Hu矩 - SkySeraph - 博客园

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

OpenCV中计算Hu矩的公式为:

HuMoments(const Moments& m, OutputArray hu)

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

什么叫图像的矩,在数字图像处理中有什么作用? - 知乎 (zhihu.com)

矩用来抽取图像(块)特征。

本质上,Hu矩其实就是泰勒级数展开的对应项。其他类型的矩也是对应多项式展开的级数(如Legendre矩对应Legendre级数)。

所以在图像里,低阶矩反映低频(主要的)信息,高阶矩反映高频(细节)信息。

矩用来抽取图像(块)特征。

本质上,Hu矩其实就是泰勒级数展开的对应项。其他类型的矩也是对应多项式展开的级数(如Legendre矩对应Legendre级数)。

所以在图像里,低阶矩反映低频(主要的)信息,高阶矩反映高频(细节)信息。

普通几何矩是基于图像原点计算的,对于图像f(x),其p+q阶普通矩的计算公式为:

上式中C和R分别表征图像的列和行。

利用几何矩进行基于区域的特征描述时,不同的阶数表示了不同的特性。各阶矩的物理意义可以表述如下。

1)零阶矩

根据几何矩的定义,0阶矩m00表征目标区域面积

2)一阶矩

一阶矩m01和m10分别为图像关于x轴和y轴的矩,可以用来确定目标区域的质心,其坐标可表示为:

3)二阶矩

图像的二阶矩m20和m02分别表示目标区域在水平和垂直方向上的伸展均衡度,m20大于0表示目标区域下部的水平伸展度比上部大,小于0表示上部的水平伸展度比下部大;m02大于0表示图像右边的垂直伸展比左边大,小于0则正相反。m11表示目标区域的倾斜度,m11大于0表示图像向左上倾斜,小于0表示图像向右上倾斜。另外,m20和m02为对x轴和y轴的惯性矩,通过组合它们可以确定几个重要的特性,例如主轴比方向离心率圆形度等等。

4) 三阶矩

三阶矩或者三阶以上矩,是目标区域轮廓细节低阶矩变化的具体表现。其中,m30和m03描述了边界曲线投影的扭曲程度,即关于均值对称分布的偏差程度,分别表示轮廓在水平和垂直方向上的重心偏移度。m30大于0表示重心偏左,小于0表示重心偏右;m03大于0表示重心向上偏移,小于0表示重心向下偏移。m21和m12表示目标区域的水平和垂直伸展的均衡程度,m21大于0表示目标区域上部的水平伸展比下部大,小于零则相反,m12大于零表示目标区域右边的垂直伸展比左边大,小于零则相反。

上述图像矩为普通矩,其值随目标区域的旋转、平移、尺度变化而改变,在实际应用中,为了提高图像矩的适用能力,需要将普通矩转换为具有旋转、平移和尺度不变性的Hu矩。针对平移不变性、尺度不变性和旋转不变性,构造Hu矩。

平移不变性:根据目标区域质心坐标x0,y0,构造中心矩:

由于选择以目标质心为基准构造中心矩,因此矩的计算结果只与目标质心的相对位置有关,而与目标绝对位置无关,从而具有了平移不变性。

尺度不变性:已知零阶中心矩u00表征目标区域的面积,为在计算图像矩时剔除尺度因素影响,可以利用0阶中心矩u00对各阶中心矩做归一化处理,得到归一化中心矩:

旋转不变性:根据中心矩的二阶矩和三阶矩,构造出7个不变矩组,其再图像平移、尺度变化和旋转时保持不变。

对于图像的Hu矩特征,由于Hu矩包含低阶特征例如面积、以及高阶特征例如旋转半径、方位等其单帧静态数值和多帧的动态变化都可能对图像识别有效果。

Hu矩是描述目标区域形状特性的重要特征,一般在图像检测仿真中实现此特征,并通过有效的特征筛选方法评估此特征的有效性,再决定是否使用该特征。

【从零学习OpenCV 4】图像矩的计算与应用 - 知乎 (zhihu.com)

(6条消息) 图像中的矩概念_Edgar_U的博客-CSDN博客_图像块的矩

什么叫图像的矩,在数字图像处理中有什么作用? - 知乎 (zhihu.com)

图像的矩是用来描述图像形状特征的,以及形状的概率分布矩是统计学和概率论的一个概念,是均值、方差概念的扩展。所以可以用矩来描述和表征不同的形状,可以作为目标识别的一种特征来训练机器学习系统具体效果怎么样,我还不知道,但可以肯定的是,用矩来描述不同形状的图像的准确性肯定没有深度学习的特征好。只能算是表述形状的一个初等特征,类似圆形度,密实度这一水平的特征。

【opencv 450 Image Processing】Image Moments 图像矩相关推荐

  1. 【opencv 450 Image Processing】Periodic Noise Removing Filter周期性去噪滤波器

    Periodic Noise Removing Filter 周期性去噪滤波器 OpenCV: Periodic Noise Removing Filter Goal 在本教程中,您将学习:    如 ...

  2. 【opencv 450 Image Processing】Hit-or-Miss

    Goal 在本教程中,您将学习如何使用 Hit-or-Miss 变换(也称为 Hit-and-Miss 变换)在二进制图像中找到给定的配置或模式(-1对应背景,1对应前景.找到邻域与内核模式一样的像素 ...

  3. 【opencv 450 Image Processing】Anisotropic image segmentation by a gradient structure tensor

    Anisotropic image segmentation by a gradient structure tensor 梯度结构张量的各向异性图像分割 Goal 在本教程中,您将学习: 梯度结构张 ...

  4. 【OpenCV 4开发详解】图像修复

    本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社发行所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4 ...

  5. (五)OpenCV | 斑点中心检测(图像矩)

    文章目录 1. 图像矩 2. Canny边缘检测 2.1 高斯平滑 2.2 图像梯度 2.3 非极大值抑制 2.4 双阈值 2.5 边缘跟踪 参考 1. 图像矩 前一文介绍了斑点的检测,本文将介绍斑点 ...

  6. Opencv之图像矩(晦涩难懂,用到再看吧)

    转载相关资料: 1.计算图像矩,图像中心,面积,弧长 2.图像的矩

  7. Android OpenCV(六十四):图像矩

    图像矩 矩(英文:moment),亦被称作动差,其概念最初应该来自于物理学,例如我们熟知的力矩.在物理学中,矩用来表示物体形状的物理量,为重要参数指标.定义在实数域上的实函数相对于值 c c c 的 ...

  8. OpenCV 编程简单介绍(矩阵/图像/视频的基本读写操作)

    PS. 因为csdn博客文章长度有限制,本文有部分内容被截掉了. 在OpenCV中文站点的wiki上有可读性更好.而且是完整的版本号,欢迎浏览. OpenCV Wiki :<OpenCV 编程简 ...

  9. 使用Python,OpenCV和Scikit-Image检测低对比度图像

    使用Python,OpenCV和Scikit-Image检测低对比度图像 1. 效果图 2. 原理 3. 源码 参考 这篇博客将介绍如何使用Python,OpenCV和Scikit-Image检测低对 ...

最新文章

  1. 使用Android studio完成”仿QQ的头像选择弹出的对话框“步骤及知识梳理
  2. python爬虫教程 百度云-如何使用python编程【python爬虫教程 百度云】
  3. 【ThinkPHP系列篇】Thinkphp框架的CURD操作(三)
  4. 5、删除用户(DROP/DELETE USER)
  5. array(2019CCPC网络预选赛 hdu6703主席树+set)主席树求大于等于k的最小值
  6. js php 数据类型判断,【js基础】变量类型判断
  7. 数据结构期末复习之排序
  8. java中来获取UUID
  9. opencv python 多帧降噪算法_实战 | OpenCV实现视频防抖
  10. android targetapi版本低,Android应用开发之Android @TargetAPI版本兼容性解析
  11. Codeforces 455B A Lot of Games 字典树上博弈
  12. 从源码的角度分析ViewGruop的事件分发
  13. 【web前端特效源码】使用HTML5+CSS3+JavaScript制作一个进度条动画效果~适合初学者~超简单~ |前端开发|IT软件
  14. 大学“电路分析基础”试题合集第八章
  15. 360WiFi2怎么在linux下使用,360随身wifi2怎么用 360随身wifi2使用方法【图文】
  16. 解密古代五大美男的凄惨结局
  17. java过滤_java 过滤list的几种方式
  18. 如何将弹幕嵌入视频中,合成一个文件
  19. 关联数据赋能智能化业务
  20. 2016年清华特等奖答辩(观后感)

热门文章

  1. rls lms 对比 matlab,自适应均衡器的LMS和RLS两种算法的特性与仿真分析
  2. 计算机移动硬盘的一般作用,移动硬盘有什么用处
  3. DAMA数据管理知识体系指南之数据安全管理
  4. 因数最多的数(DFS,质因数分解,剪枝)
  5. 正则表达式:回车和换行的区别
  6. Docker commit 联系
  7. 【机器学习】某工19级智科专业机器学习期末复习资料
  8. 数据分析|SQL面试题集锦
  9. CentOS报错:There are no enabled repos
  10. android敏感api函数,基于敏感API调用的Android应用程序动态监控