opencv中的图像矩(空间矩,中心矩,归一化中心矩,Hu矩)
严格来讲矩是概率与统计中的一个概念,是随机变量的一种数字特征。设 x 为随机变量,C为常数,则量E[(x−c)^k]称为X关于C点的k阶矩。比较重要的两种情况如下:
1.c=0,这时a_k=E(X^k)称为X的k阶原点矩;
2.c=E(X),这时μ_k=E[(X−EX)^k]称为X的k阶中心矩
一阶原点矩就是期望,一阶中心矩μ_1=0,二阶中心矩μ_2就是X的方差Var(X)。在统计学上,高于4阶的矩极少使用,μ_3可以去衡量分布是否有偏,μ_4可以衡量分布(密度)在均值拘谨的陡峭程度。
对于数学来说

矩、中心矩、质心、patch方向
一阶原点矩就是期望。二阶中心矩就是随机变量的的方差. 在统计学上,高于4阶的矩极少使用。三阶中心距可以去衡量分布是否有偏。四阶中心矩可以去衡量分布在均值附近的陡峭程度如何。
那针对一幅图像,我们把像素的坐标看成是一个二维随机变量(X, Y),那么一副灰度图可以用二维灰度图密度函数来表示,因此可以用矩来描述灰度图像的特征。

空间矩的实质为面积或者质量。可以通过一阶矩计算质心/重心。

重心(中心centers):
Hu矩




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 moments 空间矩
    double  m00, m10, m01, m20, m11, m02, m30, m21, m12, m03;
    // central moments 中心矩
    double  mu20, mu11, mu02, mu30, mu21, mu12, mu03;
    // central normalized moments 中心归一化矩
    double  nu20, nu11, nu02, nu30, nu21, nu12, nu03;
   }


#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp> using namespace cv;
using namespace std; //定义窗口名字的宏
#define WINDOW_NAME1 "【原始图】"
#define WINDOW_NAME2 "【图像轮廓】" //全局变量的声明 Mat g_srcImage, g_grayImage;
int g_nThresh = 100;
int g_nMaxThresh = 255;
RNG g_rng(12345);
Mat g_cannyMat_output;
vector<vector<Point> > g_vContours;
vector<Vec4i>g_vHierarchy; //全局函数声明
void on_ThreshChange(int, void*); //main()函数
int main()
{
//改变console字体颜色
system("color 1E");
//读入原图,返回3通道图像数据
g_srcImage = imread("E:\\VS2015Opencv\\vs2015\\project\\picture\\01.jpg", 1);
//源图像转化为灰度图像并平滑
cvtColor(g_srcImage, g_grayImage, COLOR_BGR2GRAY);
blur(g_grayImage, g_grayImage, Size(3, 3)); //创建新窗口
namedWindow(WINDOW_NAME1, WINDOW_AUTOSIZE);
imshow(WINDOW_NAME1, g_srcImage); //创建滚动条并进行初始化
createTrackbar("阈值:", WINDOW_NAME1, &g_nThresh, g_nMaxThresh, on_ThreshChange);
on_ThreshChange(0, 0);
waitKey(0);
return 0; } void on_ThreshChange(int, void *)
{
//使用canny检测边缘
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));
//计算矩
vector<Moments> mu(g_vContours.size());
for (unsigned int i = 0; i < g_vContours.size(); i++)
{
mu[i] = moments(g_vContours[i], false);
}
//计算中心矩
vector<Point2f>mc(g_vContours.size());
for (unsigned int i = 0; i < g_vContours.size(); 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 (unsigned int i = 0; i < g_vContours.size(); i++)
{
//随机生成颜色值
Scalar color = Scalar(g_rng.uniform(0, 255), g_rng.uniform(0, 255), g_rng.uniform(0, 255));
//绘制外层和内层轮廓
drawContours(drawing, g_vContours, i, color, 2, 8, g_vHierarchy, 0, Point());
//绘制圆
circle(drawing, mc[i], 4, color, -1, 8, 0);
}
//显示到窗口中
namedWindow(WINDOW_NAME2, WINDOW_AUTOSIZE);
imshow(WINDOW_NAME2, drawing);
//通过m00计算轮廓面积和Opencv函数比较
printf("\t输出内容:面积和轮廓长度\n");
for (unsigned int i = 0; i < g_vContours.size(); i++)
{
printf(">通过m00计算出轮廓[%d]的面积:(M_00) = %.2f \n Opencv函数计算出面积 = %.2f,长度:%.2f \n\n", i, mu[i].m00, contourArea(g_vContours[i]), arcLength(g_vContours[i], true));
Scalar color = Scalar(g_rng.uniform(0, 255), g_rng.uniform(0, 255), g_rng.uniform(0, 255));
drawContours(drawing, g_vContours, i, color, 2, 8, g_vHierarchy, 0, Point());
circle(drawing, mc[i], 4, color, -1, 8, 0);
}
}
本文参考:图像的形状特征——图像的矩
opencv中的图像矩(空间矩,中心矩,归一化中心矩,Hu矩)的更多相关文章
- 使用GDI+显示OpenCV中的图像IplImage
		
OpenCV虽然自带了轻量级的界面库HighGUI,但是支持的图像化元素实在是太少了,一般只在前期算法测试时使用.实际产品还是使用MFC库.因此本文记录了如何在GDI+中显示OpenCV中的IplIm ...
 - opencv中的图像形态学——腐蚀膨胀
		
腐蚀膨胀是图像形态学比较常见的处理,腐蚀一般可以用来消除噪点,分割出独立的图像元素等. 一般腐蚀操作对二值图进行处理,腐蚀操作如下图,中心位置的像素点是否与周围领域的像素点颜色一样(即是否是白色点,即 ...
 - 【视频开发】OpenCV中Mat,图像二维指针和CxImage类的转换
		
在做图像处理中,常用的函数接口有OpenCV中的Mat图像类,有时候需要直接用二维指针开辟内存直接存储图像数据,有时候需要用到CxImage类存储图像.本文主要是总结下这三类存储方式之间的图像数据的转 ...
 - Numpy和OpenCV中的图像几何变换
		
介绍 上面的图像使它不言而喻什么是几何变换.它是一种应用广泛的图像处理技术.例如,在计算机图形学中有一个简单的用例,用于在较小或较大的屏幕上显示图形内容时简单地重新缩放图形内容. 它也可以应用于扭曲一 ...
 - OpenCV中对图像进行二值化的关键函数——cvThreshold()。
		
函数功能:采用Canny方法对图像进行边缘检测 函数原型: void cvThreshold( const CvArr* src, CvArr* dst, double threshold, doub ...
 - opencv中的图像区域复制
		
openCV作为已经成熟的开源库,很多操作它都已经有了高效,使用方便的方法.我的应用场景是这样的,从一张大图片中抠出一小部分,然后处理这一小部分后再放到大图像中.对于抠出来可以这样实现: Rect r ...
 - opencv中的图像复制、保存和显示
		
接下来几天会写一个opencv的基础系列,与各位相互学习! &1 图像操作 声明图像指针:IplImage* 读入图像: cvLoadImage 创建图像:cvCreateImage 复制图像 ...
 - opencv中对图像的像素操作
		
1.对灰度图像的像素操作: #include<iostream> #include<opencv2/opencv.hpp> using namespace std; using ...
 - OpenCV中的图像形态学转换
		
两个基本的形态学操作是腐蚀和膨胀.他们的变化构成了开运算,闭运算,梯度等.下面以这张图为例 1.腐蚀 这个操作会把前景物体的边界腐蚀掉. import cv2 import numpy as np i ...
 
随机推荐
- chrome  安装
			
Centos7 yum安装chrome浏览器 跟着这个教程安装的:Centos7安装chrome浏览器 (点击) 1. 配置yum源 在目录 /etc/yum.repos.d/ 下新建文件 goo ...
 - js----UTC时间于本地时间相差8小时问题
			
js----UTC时间于本地时间相差8小时问题 js获取周几有两个方法getDay() getUTCDay(),但是它们是有区别的,前者返回的本地时间,后者返回的UTC时间,一般情况下,两者相差8个小 ...
 - 【学习笔记】Linux基础(二):Linux的基本操作
			
二.Linux的基本操作 0.正确的开关机操作 开机和登陆: 安全起见,一般不使用最高权限的root账户登入系统,光立系统时再使用 登录时为login程序提供账户名和密码即可,密码不会被显示,登陆后显 ...
 - .net core3.1 web api中使用newtonsoft替换掉默认的json序列化组件
			
在微软的文档中,有着较为详细的替换教程 https://docs.microsoft.com/zh-cn/aspnet/core/web-api/advanced/formatting?view=as ...
 - PAT (Advanced Level) Practice 1001-1005
			
PAT (Advanced Level) Practice 1001-1005 PAT 计算机程序设计能力考试 甲级 练习题 题库:PTA拼题A官网 背景 这是浙大背景的一个计算机考试 刷刷题练练手 ...
 - ROS中的3D建模机器人(三)
			
一.利用xacro理解机器人建模 当我们创建复杂的机器人模型时,URDF的灵活性将会降低,URDF缺少的主要特性是简单的.可重用性,模块化和可编程性. URDF是一个单独的文件我们不能在它里面包含其他 ...
 - 通过域名直接访问Linux服务器中的项目
			
参考:https://blog.csdn.net/m0_37802616/article/details/87623077 https://blog.csdn.net/u013176571/artic ...
 - Java装箱和拆箱的基本概念及使用
			
Java装箱和拆箱的基本概念及使用 要理解装箱和拆箱的概念,就要理解Java数据类型 装箱:把基本类型用它们相应的引用类型包装起来,使其具有对象的性质.int包装成Integer.float包装成Fl ...
 - Github第三方登陆详细流程
			
一. 流程图 二.具体实现步骤 Ⅰ.创建OAuth App 我们首先需要创建一个OAuth App,根据下图的步骤点击即可 依次填写信息,然后点Register application 然后我们可以看 ...
 - Python logging记录日志
			
Python logging记录日志 调试的几种方法: 使用print()在控制台上输出 使用assert断言 使用logging模块 logging提供了一组便利的函数,用来做简单的日志,(当然也能 ...