什么叫图像或轮廓的空间矩中心矩归一化中心矩?并利用OpenCV的类Moments计算轮廓的这几个矩和质心位置
Posted 昊虹图像算法
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了什么叫图像或轮廓的空间矩中心矩归一化中心矩?并利用OpenCV的类Moments计算轮廓的这几个矩和质心位置相关的知识,希望对你有一定的参考价值。
矩(moments)是描述图像特征的算子,被广泛应用于图像检索和识别,以及图像匹配、图像重建、图像压缩及运动图像分析等领域。
接下来介绍图像矩的原理。
在物理上,有个概念叫“力矩”,相信大家都有印象。力F对点O的矩,不仅决定于力的大小,同时与矩心的位置有关,矩心的位置不同,力矩随之不同。
借助于物理学上的这个概念,我们可以定义图像的矩。图像的矩有很多种,接下来介绍几个常用的图像矩并利用OpenCV的类Moments计算轮廓的这几个矩和质心位置。
目录
- 一、图像空间矩【spatial moments】
- 二、图像的中心矩【central moments】
- 三、图像归一化的中心矩【normalized central moments】
- 四、利用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)图像轮廓之形状匹配