在opencv里,Moments定义如下(参考opencv官方文档)

class Moments{public:Moments();Moments(double m00, double m10, double m01, double m20, double m11,double m02, double m30, double m21, double m12, double m03 );Moments( const CvMoments& moments );operator CvMoments() const;// spatial momentsdouble  m00, m10, m01, m20, m11, m02, m30, m21, m12, m03;// central momentsdouble  mu20, mu11, mu02, mu30, mu21, mu12, mu03;// central normalized momentsdouble  nu20, nu11, nu02, nu30, nu21, nu12, nu03;}

我想可能初次接触的可能不太理解这些定义的变量是怎么回事.
spatial moments 的计算公式为:

其中的array即 密度函数f(x,y),当i,j都为0时,即m00,m00表示的就是质量,或者是面积;
文档中的mass center的计算公式是:

又参考质心(mass center)

就不难理解m00的含义以及m10和m01的含义

在opencv中又有函数 double contourArea(InputArray contour, bool oriented=false ) 计算轮廓的面积
可以用这个函数来和m00进行比较是否一致

有下述代码详细解释.

#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<iostream>
using namespace cv;
using namespace std;const string WINDOW_NAME1 = "[原始窗口]";
const string WINDOW_NAME2 = "[效果窗口]";Mat g_srcImage, g_grayImage;
Mat g_cannyMat_output;
int g_nThresh = 50;
int g_nThresh_max = 255;
RNG g_rng(12345);       //      随机数产生器
vector<vector<Point>>g_vContours;
vector<Vec4i>g_vHierarchy;void on_ThreshChange(int, void*);   int main(char* args, char* argc){
g_srcImage = imread("blind.jpg", 1);
cvtColor(g_srcImage, g_grayImage, COLOR_BGR2GRAY);
blur(g_grayImage, g_grayImage, Size(3, 3));namedWindow(WINDOW_NAME1, WINDOW_AUTOSIZE);
namedWindow(WINDOW_NAME2, WINDOW_AUTOSIZE);
imshow(WINDOW_NAME1, g_grayImage);createTrackbar("阈值", WINDOW_NAME2, &g_nThresh, g_nThresh_max, on_ThreshChange);
on_ThreshChange(0, 0);waitKey(0);
return 0;
}void on_ThreshChange(int, void*){
Canny(g_grayImage, g_cannyMat_output, g_nThresh, g_nThresh * 2, 3);
findContours(g_cannyMat_output, g_vContours, g_vHierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0));//计算矩moments    :随机变量的n阶矩就是它的n次方的数学期望。
//一阶原点矩:就是均值,数学期望
int cnt = g_vContours.size();
vector<Moments> mu(cnt);  //存储的是Moments对象
/* Moments(double m00, double m10, double m01, double m20, double m11,double m02, double m30, double m21, double m12, double m03 );*/
// m00  m01  m02 m03     m00就是轮廓的面积  对应着质心
// m10  m11  m12
// m20  m21
// m30
for (int i = 0; i < cnt;i++)mu[i]= moments(g_vContours[i],false);            //返回moments的计算结果
//计算图像的质心
//计算公式见API
vector<Point2f>mc(cnt);
for (int i = 0; i < cnt; i++)mc[i] = Point2f(static_cast<float>(mu[i].m10 / mu[i].m00),static_cast<float>(mu[i].m01 / mu[i].m00));   //质心//绘制轮廓
Mat drawing = Mat::zeros(g_cannyMat_output.size(), CV_8UC3);
for (int i = 0; i < cnt; i++){Scalar color = Scalar(255, 255, 255);drawContours(drawing, g_vContours, i, color, 1, 8, g_vHierarchy, 0, Point());circle(drawing, mc[i],4, color, 2, 8, 0);    //在质心处画圆                                                                                }
imshow(WINDOW_NAME2, drawing);
//通过m00计算轮廓面积和opencv函数进行比较
cout << '\t' << "输出内容:面积和轮廓长度\n";
for (int i = 0; i < cnt; i++){printf(">通过m00计算出轮廓[%d]的面积:(M_00)=%.2f\n   OPENCV函数计算出的面积=%.2f,长度:%.2f\n\n", i, mu[i].m02, contourArea(g_vContours[i]), arcLength(g_vContours[i], true));}
}

opencv里的Moments成员变量的理解相关推荐

  1. C++ 私有成员变量的理解

    私有成员变量的概念,在脑海中的现象是,以private关键字声明,是类的实现部分,不对外公开,不能在对象外部访问对象的私有成员变量. 然而,在实现拷贝构造函数和赋值符函数时,在函数里利用对象直接访问了 ...

  2. 私有成员变量理解的补充

    在设计和实现当前类时,实现拷贝构造函数和赋值构造函数时,甚至在成员函数的内部是可以直接访问当前类的对象(以参数的形式)的私有成员变量的.考虑如下的代码: class Test { public:Tes ...

  3. final 修饰的成员变量必须手动初始化

    理解1: final关键字我们并不陌生,但是final修饰的属性变量为什么必须在定义的时候或者构造函数中被初始化呢? static final修饰的变量又为什么必须在定义的时候进行初始化呢? 首先要明 ...

  4. java实例变量成员变量_Java的类成员变量、实例变量、类变量,成员方法、实例方法、类方法...

    总是被这些相似的概念搞晕,查阅了资料后做个小总结,以变量为例,方法辨析类似. 1.多胞胎名字汇总辨析 成员变量和成员方法是范围最大的定义,提到成员变量就可以理解成你所定义在一个类体中的各类变量的统称, ...

  5. java什么是局部变量,什么是java的局部变量,成员变量,全局变量?

    public class Test { private String name;//成员变量,也是全局变量 public void changeName() { String n = "to ...

  6. Java为枚举类创建成员变量_Java学习——枚举类

    Java学习--枚举类 摘要:本文主要介绍了Java的枚举类. 部分内容来自以下博客: https://www.cnblogs.com/sister/p/4700702.html https://bl ...

  7. 理解java和python类变量以及类的成员变量

    最可怕的不是犯错而是一直都没发现错误,直到现在我才知道自己对类变量的理解有问题. 大概可能也许是因为不常用类变量的原因吧,一直没有发现这个问题**.最近在看C++时才知道了类变量到底是什么**? 以前 ...

  8. 如何理解Java的类变量、成员变量、常量、类属性、实例属性、字段(field)、成员方法、类方法

    文章目录 变量相关概念 变量/常量 类变量/静态变量 成员变量/实例变量 类属性/实例属性/对象属性 什么是 field 成员变量和类变量的区别 两个变量的生命周期不同 访问方式不同 数据存储位置不同 ...

  9. 如何理解成员变量在堆内,局部变量在栈内?

    成员变量在堆内存里,局部变量在栈内存里.(基础类型) 我有疑惑: 既然成员变量存在于对象中,对象存在于堆中,所以成员变量存在于堆中.那么按照这样的推理,局部变量存在于方法中,而方法存在于对象中,对象存 ...

最新文章

  1. VC++实现Turbo码
  2. python pip管理工具
  3. linux配置一个ip san存储服务器,网络存储服务ip-san搭建
  4. C#调用C++DLL传递结构体数组的终极解决方案
  5. spring boot 单元测试_spring-boot-plus1.2.0-RELEASE发布-快速打包-极速部署-在线演示
  6. html5-svg和Two.js的使用方法(附案例)
  7. canny算子_Canny边缘检测算法
  8. javascript控制开始日期,和结束日期在同一个月
  9. 【转载】全球天然气探明储量
  10. 小程序页面之间的跳转方法
  11. vue-router的简单理解
  12. STL---栈和队列
  13. 教你轻松删除PDF文件中的空白页
  14. java生成pdf合同
  15. Could not locate zlibwapi.dll. Please make sure it is in your library path
  16. mysql分组查询学生平均年龄_那些年我们一起做过的[分组查询]_MySQL
  17. vue css 拖拽,vue----拖拽小方块
  18. 均匀分布(Uniform distribution)
  19. nodemcu刷鸿蒙系统,mac开发nodemcu, 通过terminal刷固件
  20. Win PE 是什么?

热门文章

  1. 域名在微信中被拦截、封杀、屏蔽的原因以及解决方案
  2. 技术报告 | 罗汉堂:理解大数据:数字时代的数据和隐私2021.pdf(附下载链接)
  3. 智能手术机器人技术与原理(二)
  4. swoole基础之http-server
  5. 【Linux】入门介绍
  6. Java接口 和 接口
  7. Java之父求职被嫌年纪大:程序员只能吃青春饭?
  8. 天天链n1 与电脑连接Samba win10 教程
  9. Day3—HTML个人简历制作及五彩导航练习
  10. 10倍杠杆炒股是什么意思