二值图像分析—用几何矩计算轮廓中心与横纵比过滤

是描述图像特征的算子,如今矩技术已广泛应用于图像检索和识别 、图像匹配 、图像重建 、数字压缩 、数字水印及运动图像序列分析等领域。常见的矩描述子可以分为以下几种:几何矩、正交矩、复数矩和旋转矩。

从一幅图像计算出来的矩集,不仅可以描述图像形状的全局特征,而且可以提供大量关于该图像不同的几何特征信息,如大小,位置、方向和形状等。图像矩这种描述能力广泛应用于各种图像处理、计算机视觉和机器人技术领域的目标识别与方位估计中。

一阶矩:与形状有关;
二阶矩:显示曲线围绕直线平均值的扩展程度;
三阶矩:关于平均值的对称性测量;

由二阶矩和三阶矩可以导出7个不变矩。而不变矩是图像的统计特性,满足平移、伸缩、旋转均不变的不变性、在图像识别领域得到广泛的应用。

几何矩: 提出的时间最早且形式简单,对它的研究最为充分。几何矩对简单图像有一定的描述能力,他虽然在区分度上不如其他三种矩,但与其他几种算子比较起来,他极其的简单,一般只需用一个数字就可表达。所以,一般我们是用来做大粒度的区分,用来过滤显然不相关的文档。



数学中的矩

在这里插入图片描述

图像几何矩

图像的几何矩包含空间矩,中心矩和中心归一化矩。几何矩具有平移、旋转和尺度不变性,一般用于做大粒度的区分,用来过滤显然不相关的图像。

一阶矩、零阶矩用来计算某个形状的重心。
M 00 = ∑ I ∑ J V ( i , j ) ; M_{00}=\sum_I\sum_JV(i,j); M00=IJV(i,j);
M 10 = ∑ I ∑ J i ∗ V ( i , j ) ; M_{10}=\sum_I\sum_Ji*V(i,j); M10=IJiV(i,j);
M 01 = ∑ I ∑ J j ∗ V ( i , j ) ; M_{01}=\sum_I\sum_Jj*V(i,j); M01=IJjV(i,j);
i c = M 10 M 00 , j c = M 01 M 00 i_c=\frac{M_{10}}{M_{00}} , j_c=\frac{M_{01}}{M_{00}} ic=M00M10,jc=M00M01

其中, M 00 M_{00} M00是零阶矩, M 10 M_{10} M10 M 01 M_{01} M01是一阶矩。其中 i c i_c ic j c j_c jc是图像的重心坐标。

二阶矩用来计算形状的方向。
M 20 = ∑ i ∑ j i 2 V ( i , j ) M_{20}=\sum_i\sum_ji^2V(i,j) M20=iji2V(i,j)
M 02 = ∑ i ∑ j j 2 I ( i , j ) M_{02}=\sum_i\sum_jj^2I(i,j) M02=ijj2I(i,j)
M 11 = ∑ I ∑ J i ∗ j ∗ V ( i , j ) M_{11}=\sum_{I}\sum_{J}i*j*V(i,j) M11=IJijV(i,j)

那么物体的方向:
在这里插入图片描述

OpenCV中的API

在OpenCV中,可以很方便的计算多边形区域的3阶特征矩。opencv中的矩主要包括以下几种:

  1. 空间矩/几何矩
    空间矩的实质就是面积或者质量,可以通过一阶矩计算质心/重心。

    空间矩:spatial moments:
    double 	m00
    double 	m10
    double 	m01
    double 	m20
    double 	m11
    double 	m02
    double 	m30
    double 	m21
    double 	m12
    double 	m03
    

    各阶矩的物理意义:

    0阶矩( M 00 M_{00} M00)——————目标区域的质量
    1阶矩( M 01 , M 10 M_{01},M_{10} M01,M10)————目标区域的质心
    2阶矩( M 02 , M 11 , M 20 M_{02},M_{11},M_{20} M02,M11,M20)———表示旋转半径
    3阶矩( M 03 , M 12 , M 21 , m 30 M_{03},M_{12},M_{21},m_{30} M03,M12,M21m30)——描述目标方位和斜度,反映目标的扭曲程度

  2. 中心矩
    中心矩体现的是图像强度的最大和最小方向(中心矩可以构建图像的协方差矩阵),其只具有平移不变性,所以用中心矩做匹配效果不会很好。

    中心矩:构造平移不变形
    质心的坐标: x = m 10 m 00 , y = m 01 m 00 x=\frac{m_{10}}{m_{00}},y=\frac{m_{01}}{m_{00}} x=m00m10,y=m00m01

    中心矩central moments:
     double 	mu20
     double 	mu11
     double 	mu02
     double 	mu30
     double 	mu21
     double 	mu12
     double 	mu03
    
  3. 归一化的中心矩
    归一化后具有尺度不变性。

    中心归一化矩central normalized moments:
    double 	nu20
    double 	nu11
    double 	nu02
    double 	nu30
    double 	nu21
    double 	nu12
    double 	nu03
    
  4. Hu矩
    Hu矩由于具有尺度、旋转、平移不变性,可以用来做匹配

OpenCV中提供了:

moments()来计算图像中的中心矩
HuMoments()用于由中心矩计算Hu矩
函数contourArea函数计算轮廓面积
arcLength来计算轮廓或者曲线长度

Moments类


class CV_EXPORTS_W_MAP Moments
{
public:
    //! the default constructor
    Moments();
    //! the full constructor
    Moments(double m00, 
            double m10, 
            double m01,
            double m20, 
            double m11,
            double m02, 
            double m30, 
            double m21, 
            double m12, 
            double m03 
           );
  

    //空间矩
    //! @{
    double  m00, m10, m01, m20, m11, m02, m30, m21, m12, m03;
    //! @}

    //中心矩
    //! @{
    CV_PROP_RW double  mu20, mu11, mu02, mu30, mu21, mu12, mu03;
    //! @}

    //中心归一化矩
    //! @{
    CV_PROP_RW double  nu20, nu11, nu02, nu30, nu21, nu12, nu03;
    //! @}
};
1、moments函数
  • 说明
    计算多边形3阶之前的所有矩。

  • 说明

    Moments moments( InputArray array, bool binaryImage = false );
    
  • 参数

    array像素图(单通道、8位或浮点二维数组)或二维的( 1 × N 1 \times N 1×N or N × 1 N \times 1 N×1 )的点。
    binaryImage如果为真,则所有非零图像像素视为1。该参数仅用于图像。

    仅适用于Python绑定的轮廓矩计算:注意numpy
    输入数组的类型应该是np.int32或np.float32。

2、contourArea函数
  • 说明
    该函数计算轮廓区域。与矩类似,使用格林公式计算面积。因此,如果使用drawContours或fillPoly绘制轮廓,则返回的区域和非零像素的数量可以不同。同样,对于带有自相交的轮廓,该功能肯定会给出错误的结果。

  • 声明

    double contourArea( InputArray contour, bool oriented = false );
    
    
  • 参数

    contour二维点(轮廓顶点)的输入向量,存储在std :: vector或Mat中。
    oriented定向区域标志。如果为true,则函数根据轮廓方向(顺时针或逆时针)返回带符号的区域值。使用此功能,您可以通过取一个区域的符号来确定轮廓的方向。默认情况下,该参数为false,表示返回绝对值。
3、arcLength函数
  • 说明
    计算轮廓周长或曲线长度。
    该函数计算曲线长度或闭合轮廓周长。

  • 函数

    double arcLength( InputArray curve, bool closed );
    
  • 参数

    curve二维点的输入向量,存储在std :: vector或Mat中。
    closed指示曲线是否闭合的标志。

应用

#include<iostream>
#include<opencv2/opencv.hpp>

using namespace std;
using namespace cv;

void getCenterPoint(Mat& src) {
	Mat binary, gray,dst;
	dst = src.clone();
	//1.将图片转化成灰度图像
	cvtColor(src, gray, COLOR_BGR2GRAY);
	imshow("gray", gray);

	//2.转化图片成为二值化
	threshold(gray, binary, 0, 255, THRESH_BINARY | THRESH_OTSU);
	imshow("binary", binary);
	//3.发现轮廓
	vector<vector<Point>> contours;
	findContours(binary, contours, RETR_TREE, CHAIN_APPROX_SIMPLE);

	//4.计算轮廓的矩
	vector<Moments> mu(contours.size());
	vector<Point2f> mc(contours.size());
	vector<double> mu_area(contours.size());
	for (size_t i = 0; i < contours.size(); i++)
	{
		int r = (i + 60) % 255;
		int g = (i + 20) % 255;
		int b = (i + 140) % 255;
		Scalar color = Scalar(r,g,b);
		//4.1面积过滤,过滤面积小于300的
		double area = contourArea(contours[i]);
		if (area < 300)
			continue;
		//4.2横纵比过滤
		Rect rect = boundingRect(contours[i]);
		float radio = float(rect.width) / float(rect.height);
		if (radio < 3 && radio>1) {
			//4.3计算矩
			mu[i] = moments(contours[i]);

			//5. 由矩计算轮廓的中心矩、面积
			double x = mu[i].m10 / mu[i].m00;
			double y = mu[i].m01 / mu[i].m00;
			//5.1中心矩
			mc[i] = Point2d(x, y);
			//5.2面积
			mu_area[i] = mu[i].m00;
			cout << "第" << i << "个轮廓的中心:(" << mc[i].x << "," << mc[i].y << "),面积为:" << mu_area[i] << endl;
            //5.3画出轮廓
			drawContours(dst, contours, i, color, 2);
			//5.4画出中心矩
			circle(dst, Point(mc[i]), 5, color, -1);

		}
	}
	imshow("contour", src);
	imshow("dst", dst);

}

int main() {
	Mat src = imread("D:/test/huahua.png");
	if (src.empty()) {
		cout << "input the image error!" << endl;
	}
	getCenterPoint(src);
	waitKey(0);
	return 0;
	
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
【图像处理】轮廓二阶矩计算目标中心-计算目标中心位置方法3

【图像算法】图像特征:几何不变矩–Hu矩

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值