什么叫图像或轮廓的空间矩中心矩归一化中心矩?并利用OpenCV的类Moments计算轮廓的这几个矩和质心位置

Posted 昊虹图像算法

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了什么叫图像或轮廓的空间矩中心矩归一化中心矩?并利用OpenCV的类Moments计算轮廓的这几个矩和质心位置相关的知识,希望对你有一定的参考价值。

矩(moments)是描述图像特征的算子,被广泛应用于图像检索和识别,以及图像匹配、图像重建、图像压缩及运动图像分析等领域。

接下来介绍图像矩的原理。

在物理上,有个概念叫“力矩”,相信大家都有印象。力F对点O的矩,不仅决定于力的大小,同时与矩心的位置有关,矩心的位置不同,力矩随之不同。

借助于物理学上的这个概念,我们可以定义图像的矩。图像的矩有很多种,接下来介绍几个常用的图像矩并利用OpenCV的类Moments计算轮廓的这几个矩和质心位置。

目录

一、图像空间矩【spatial moments】

我们先来看图像空间矩【spatial moments】的概念
这里插一句题外话,有些资料把空间矩也称为叫几何矩,博主觉得叫几何矩不准确,因为几何矩是几何图形的矩,而几何图形是不考虑每一点的像素值大小的。

图像空间矩【spatial moments】的计算公式如下:

其中, a r r a y ( x , y ) array(x,y) array(x,y)是像素(x,y)处的像素值。
注意:x代表的是像素的列号,而不是行号;y代表的是像素的行号,而不是列号。这一点可以在下面的示例代码的运行结果中看出。这也是为什么上面m的下标不是“ i j ij ij”而是“ j i ji ji”的原因。

从这个计算式我们可以看出,图像的空间矩不仅与像素值大小有关,还与像素的位置有关,这一点和物理学中力矩的概念是一致的。

j = i = 0 j=i=0 j=i=0时,有 m 00 = ∑ x , y a r r a y ( x , y ) x 0 y 0 = ∑ x , y a r r a y ( x , y ) m_00=\\sum_x,yarray(x,y)x^0y^0=\\sum_x,yarray(x,y) m00=x,yarray(x,y)x0y0=x,yarray(x,y)

此时 m 00 m_00 m00称为叫图像的零阶空间矩,从这个计算式我们可以看出,图像的零阶空间矩实际上就是所有像素值的累加,零阶矩的值与像素的位置无关。

j = 0 , i = 1 j=0,i=1 j=0,i=1 j = 1 , i = 0 j=1,i=0 j=1,i=0时, m 01 m_01 m01 m 10 m_10 m10称为图像的一阶空间矩,很明显,图像的一阶空间矩在空间位置上只与像素的行号或列号有关。以此类推,可以有图像的二阶空间矩,三阶空间矩等。比如以下三种情况都是图像的二阶空间矩:
① j=0,i=2,即 m 02 m_02 m02
② j=1,i=1,即 m 11 m_11 m11
③ j=2,i=0,即 m 20 m_20 m20

根据图像的零阶空间矩和一阶空间矩,我们可以定义出图像的质心的坐标计算式:

x ˉ = m 10 m 00 \\barx=\\fracm_10m_00 xˉ=m00m10 y ˉ = m 01 m 00 \\bary=\\fracm_01m_00 yˉ=m00m01 注意, x ˉ \\barx xˉ是列号, y ˉ \\bary yˉ是行号。

二、图像的中心矩【central moments】

图像的中心矩的计算式如下:

式中的 x ˉ \\barx xˉ y ˉ \\bary yˉ就是图像的质心位置坐标(上边已经介绍过了),即:

x ˉ = m 10 m 00 \\barx=\\fracm_10m_00 xˉ=m00m10 y ˉ = m 01 m 00 \\bary=\\fracm_01m_00 yˉ=m00m01 注意, x ˉ \\barx xˉ是列号, y ˉ \\bary yˉ是行号。

根据上面的计算式,容易得到:
  

三、图像归一化的中心矩【normalized central moments】

图像归一化的中心矩的计算式如下:

根据上面的计算式容易得到:
n u 00 = 1 nu_00=1 nu00=1   n u 10 = n u 01 = 0 nu_10=nu_01=0 nu10=nu01=0

四、利用OpenCV的类Moments计算图像或点集(轮廓)的空间矩、中心矩和归一化的中心矩

OpenCV提供了类Moments来计算图像或点集(轮廓)的空间矩、中心矩和归一化的中心矩。
下面介绍这个类Moments。
先说类Moments的成员函数moments(),这个成员函数的原型如下:

Moments cv::moments	(	InputArray 	array,
						bool 	binaryImage = false 
					)	

成员函数moments()用于计算多边形或像素图像的三阶(包含三阶)以下的空间矩、中心矩和归一化的中心矩。官方文档原话如下:
Calculates all of the moments up to the third order of a polygon or rasterized shape.
其参数意义如下:
array—Raster image (single-channel, 8-bit or floating-point 2D array) or an array ( 1×N or N×1 ) of 2D points (Point or Point2f )。
binaryImage—If it is true, all non-zero image pixels are treated as 1’s. The parameter is used for images only.
以上英文很简单,就不翻译了,不明白的再加博主的微信/QQ 2487872782交流吧。
再说类Moments的成员变量,它的成员变量和表示的意义分别如下:


注意:由于

所以上面的中心矩没有 m u 00 mu_00 mu00 m u 01 mu_01 mu01 m u 10 mu_10 mu10这几个。

注意:由于 n u 00 = 1 nu_00=1 nu00=1   n u 10 = n u 01 = 0 nu_10=nu_01=0 nu10=nu01=0

所以上面的归一化中心矩没有 n u 00 nu_00 nu00 n u 10 nu_10 nu10 n u 01 nu_01 nu01这几个。

接下来是使用类Moments计算图像轮廓的空间矩、质心位置、中心矩、归一化中心矩的示例代码。
代码中用到的图像下载链接:https://pan.baidu.com/s/1ZfOReFRyeMDLhk3PjJXGwA?pwd=aes8

//博主微信/QQ 2487872782
//有问题可以联系博主交流
//有图像处理需求也可联系博主
//图像处理技术交流QQ群 271891601

//OpenCV版本:3.0
//VS版本:2013

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include<opencv2/imgcodecs/imgcodecs.hpp>
#include <opencv2/imgproc/imgproc.hpp>

#include <iostream>

using namespace cv;
using namespace std;

int main()

	Mat srcGary = imread("F:/material/images/P0045-ellipse-02.jpg", 0);
	imshow("srcGary", srcGary);

	// 阈值化操作
	Mat threMat;
	int thresh = 128;
	threshold(srcGary, threMat, thresh, 255, THRESH_BINARY);


	vector<vector<Point>> contours;

	// find Contours
	findContours(threMat, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
	cout << "检测到的轮廓个数为:" << (int)contours.size() << endl << endl;

	// draw Contours
	Mat contours_img(srcGary.size(), CV_8U, Scalar(0));
	drawContours(contours_img, contours, -1, Scalar(255)图像轮廓之形状匹配

youcans 的 OpenCV 例程200篇198.基于不变矩的形状相似性检测

opencv —— moments

图像识别基于不变矩的数字验证码识别含GUI界面

图像的距

图像识别基于不变矩的数字验证码识别含GUI界面