OpenCV4入门教程097:用几何矩计算轮廓中心与横纵比过滤

索引地址:系列索引

矩:图像距(几何矩、中心矩、hu矩)

OpenCV中提供了:

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

Moments类

计算多边形3阶之前的所有矩。

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

contourArea函数

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

声明

1
double contourArea( InputArray contour, bool oriented = false );
  • contour 二维点(轮廓顶点)的输入向量,存储在std :: vector或Mat中。
  • oriented 定向区域标志。如果为true,则函数根据轮廓方向(顺时针或逆时针)返回带符号的区域值。使用此功能,您可以通过取一个区域的符号来确定轮廓的方向。默认情况下,该参数为false,表示返回绝对值。

arcLength函数

该函数计算曲线长度或闭合轮廓周长。

1
double arcLength( InputArray curve, bool closed );
  • curve 二维点的输入向量,存储在std :: vector或Mat中。
  • closed 指示曲线是否闭合的标志。

测试代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#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("circles.jpg");
if (src.empty()) {
cout << "input the image error!" << endl;
}
getCenterPoint(src);
waitKey(0);
return 0;
}

效果

moment

和上一篇相比就是多了一个纵横比约束。


OpenCV4入门教程097:用几何矩计算轮廓中心与横纵比过滤
https://blog.jackeylea.com/opencv/opencv-calc-center-moment/
作者
JackeyLea
发布于
2020年10月6日
许可协议