OpenCV图像处理开发实战(16) -- 图像的几何矩moments(测面积、测弧度长)

1、 矩的理解

(1)物理中的矩

在力学中,矩是表示距离和物理量乘积的物理量,表征物体的空间分布。原则上任何物理量和距离相乘都会产生力矩,质量,电荷分布等。单个点的力矩:,多个点则是积分的空间密度:,如果点表示质量,则第零矩是总质量,一阶矩是重心,二阶矩是转动惯量。

(2)数学中的矩

在统计学中,矩表征随机量的分布。如一个“二阶矩”在一维上可测量其“宽度”,,在更高阶的维度上由于其使用于橢球的空间分布。其他矩用来描述诸如与均值的偏差分布情况(偏态),或峰值的分布情况(峰态)。实数域的实函数相对于值c的n阶矩为:,如果点表示概率密度,则第零阶矩表示总概率(即1),1,2,3阶矩依次为以下三项。数学中的概念与物理学中矩的概念密切相关。
归一化n阶中心矩或者说标准矩,是n阶中心矩除以标准差,归一化n阶中心矩。

(3)图像中的矩

矩函数在图像分析中有着广泛的应用,如模式识别、目标分类、目标识别与方位估计、图像编码与重构等。一个从一幅数字图形中计算出来的矩集,通常描述了该图像形状的全局特征,并提供了大量的关于该图像不同类型的几何特性信息,比如大小、位置、方向及形状等。图像矩的这种特性描述能力被广泛的应用在各种图像处理、计算机视觉和机器人技术领域的目标识别与方位估计中。
一阶矩与形状有关,
二阶矩显示曲线围绕直线平均值的扩展程度,三阶矩则是关于平均值的对称性的测量。
由二阶矩和三阶矩可以导出一组共七个不变矩。
不变矩是图像的统计特性,满足平移、伸缩、旋转均不变的不变性,在图像识别领域得到了广泛的应用。

不变矩的物理含义:

如果把图像看成是一块质量密度不均匀的薄板,其图像的灰度分布函数f(x,y)就是薄板的密度分布函数,则其各阶矩有着不同的含义,如零阶矩表示它的总质量;一阶矩表示它的质心;二阶矩又叫惯性矩,表示图像的大小和方向。事实上,如果仅考虑阶次为2的矩集,则原始图像等同于一个具有确定的大小、方向和离心率,以图像质心为中心且具有恒定辐射率的椭圆。由三阶矩以下矩构成的七个矩不变量具有平移、旋转和尺度不变性等等。当密度分布函数发生改变时,图像的实质没有改变,仍然可以看做一个薄板,只是密度分布有所改变。虽然此时各阶矩的值可能发生变化,但由各阶矩计算出的不变矩仍具有平移、旋转和尺度不变性。这样 ,可对图像进行简化处理,保留最能反映目标特性的信息,再用简化后的图像计算不变矩特征,可减少计算量。

只有基于二阶矩的不变矩对二维物体的描述才是真正的与旋转、平移和尺度无关的。较高阶的矩对于成像过程中的误差,微小的变形等因素非常敏感,所以相应的不变矩基本上不能用于有效的物体识别。即使是基于二阶矩的不变矩也只能用来识别外形相差特别大的物理,否则他们的不变矩会因为很相似而不能识别。

2、 openCV中有关函数

(1)moments()求矩函数

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

(2)contourArea()计算轮廓面积函数

double contourArea(
InputArray contour, // 轮廓数据
bool oriented = false
);

(3)arcLength()求弧度长函数

double arcLength(
InputArray curve, // 输入曲线数据
bool closed // 是否同封闭的
)

3、 函数调用方法

(1)转化为灰度图
(2)图像平滑处理(模糊)
(3)边缘和轮廓提取
(4)计算轮廓的矩
(5)计算每中轮廓的中心、边长、面积。

4、 源代码

	
	// 第1步,灰度图
	cvtColor(srcImg1, grayImg, CV_BGR2GRAY);

	// 第2步, 高斯模糊
	GaussianBlur(grayImg, gausImg, Size(3, 3), 0); 

	// 第3步, 边缘提取
	Canny(gausImg, cannyImg, 150, 200);

	// 第4步, 轮廓提取
	vector<vector<Point>> ptContours;
	vector<Vec4i> hierarchy;
	findContours(cannyImg, ptContours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_NONE, Point(0, 0));

	// 第5步, 计算矩
	vector<Moments> contour_moment(ptContours.size());
	vector<Point2f> centerpos(ptContours.size());
	
	char text[1024];
	for (int i = 0; i < ptContours.size(); i++)
	{
		contour_moment[i] = moments(ptContours[i]);

		// 太小的区域不画出,太多的输出画面太乱。
		if (ptContours[i].size() < 500)
		{
			continue;
		}

		// 第6步, 计算中心点
		centerpos[i].x = contour_moment[i].m01 / contour_moment[i].m00;
		centerpos[i].y = contour_moment[i].m10 / contour_moment[i].m00;

		// 画轮廓线
		drawContours(srcImg1,
			ptContours,
			i,
			Scalar(0, 255, 0),
			1
			);

		// 画出中心的位置
		circle(srcImg1, centerpos[i],3,Scalar(0,0,255));

		// 第7步, 计算面积和弧度长
		double area = contourArea(ptContours[i]);
		double len = arcLength(ptContours[i], true);

		// 在图上显示面积和弧度长信息
		sprintf(text, "area=%.2f arclen=%.2f", area, len);
		putText(srcImg1, text, centerpos[i], 1, 1.0, Scalar(0,255,0));
	}


	imshow(src_file_name1, srcImg1);

5、 工程项目下载

本文源码在Debug–x64下编译运行。

ZIP包中包含开发环境,下载解压后可直接编译运行。

下载源码。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值