2025-10-17 10:26:43

博主联系方式: QQ:1540984562 QQ交流群:892023501 群里会有往届的smarters和电赛选手,群里也会不时分享一些有用的资料,有问题可以在群里多问问。

目录

前言1、轮廓面积获取函数2、轮廓周长获取函数3、轮廓圆形度计算4、矩形度计算5、宽长比计算6、周径比计算总结:最终示例

前言

之前学习了连通域和轮廓的知识,其中要框定出自己想要的目标物体,我们往往需要用一些if,else语句用来筛选。 这里整理一下常用的筛选条件。 先验知识链接:

https://blog.csdn.net/qq_42604176/article/details/105588018

1、轮廓面积获取函数

输入当前轮廓点集,输出该轮廓点集的面积

area = contourArea(contours[t]);//计算轮廓面积

2、轮廓周长获取函数

输入当前轮廓点集,第二个参数:bool closed:表示轮廓是否封闭的 输出该轮廓点集的周长

len = arcLength(contours[t], true);//计算轮廓周长

3、轮廓圆形度计算

原本计算公式: 网上的公式一般是这个:e=(4π 面积)/(周长 * 周长); 这里将周长等价于2pi*r;

area = contourArea(contours[t]);//计算轮廓面积

len = arcLength(contours[t], true);//计算轮廓周长

roundness = (4 * CV_PI * area) / (len * len);//圆形度

4、矩形度计算

//先计算最小外接矩形的面积:

RotatedRect minrect = minAreaRect(contours[t]); //最小外接矩形

area = contourArea(contours[t]);//计算轮廓面积

int minrectmianji = minrect.size.height * minrect.size.width;

if (minrectmianji == 0)rectangularity = 0;

else rectangularity = area / minrectmianji;

注意点: minrect.size是个数组,表述的是尺寸即:width,height

5、宽长比计算

宽长比:最小外接矩形的长轴与短轴的比值

RotatedRect rbox = minAreaRect(contours[i]);

fabs(rbox.size.width * 1.0 / rbox.size.height - 1) < 0.1 //表示宽长比在1附近+-0.1内浮动

6、周径比计算

周径比的周即周长,径是指上面找到的轮廓最小外接矩形的长的一条边

lenratio = len / (minrect.size.height > minrect.size.width ? minrect.size.height : minrect.size.width);

总结:最终示例

#include

#include

#include "windows.h"

#include

#include

#include

//#include "My_ImageProssing_base.h"

#define WINDOW_NAME "【程序窗口】" //为窗口标题定义的宏

using namespace cv;

using namespace std;

RNG g_rng(12345);

int main()

{

//改变控制台字体颜色

system("color 02");

//读取图像

Mat src_image = imread("D:\\opencv_picture_test\\阈值处理\\硬币.png", 1);

//出错判断

if (!src_image.data)

{

cout << "src image load failed!" << endl;

return -1;

}

//显示原图

namedWindow("原图", WINDOW_NORMAL);

imshow("原图", src_image);

//高斯滤波去噪声

Mat blur_image;

GaussianBlur(src_image, blur_image, Size(3, 3), 0, 0);

imshow("GaussianBlur", blur_image);

//灰度变换与二值化

Mat gray_image, binary_image;

cvtColor(blur_image, gray_image, COLOR_BGR2GRAY);

threshold(gray_image, binary_image, 100, 255, THRESH_BINARY);

imshow("binary", binary_image);

//形态学闭操作(粘合断开的区域)

Mat morph_image;

Mat kernel = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));

morphologyEx(binary_image, morph_image, MORPH_CLOSE, kernel, Point(-1, -1), 1);

imshow("morphology", morph_image);

//查找所有外轮廓

vector< vector > contours;

vector hireachy;

findContours(binary_image, contours, hireachy, RETR_EXTERNAL, CHAIN_APPROX_NONE, Point());

//定义结果图

Mat result_image = Mat::zeros(src_image.size(), CV_8UC3);

//drawContours(result_image, contours, -1, Scalar(0, 0, 255), 1, 8, hireachy);//画出所有轮廓

//初始化周长、面积、圆形度、周径比

double len = 0, area = 0, roundness = 0, lenratio = 0;

float rectangularity;

//循环找出所有符合条件的轮廓

for (size_t t = 0; t < contours.size(); t++)

{

Scalar color = Scalar(g_rng.uniform(0, 255),

g_rng.uniform(0, 255), g_rng.uniform(0, 255));//任意值

//条件:过滤掉小的干扰轮廓

Rect rect = boundingRect(contours[t]); //垂直边界最小矩形

if (rect.width < 10)

continue;

//画出找到的轮廓

drawContours(result_image, contours,t,color,1, 8, hireachy);

//绘制轮廓的最小外结矩形

RotatedRect minrect = minAreaRect(contours[t]); //最小外接矩形

int minrectmianji = minrect.size.height * minrect.size.width;

Point2f P[4]; //四个顶点坐标

minrect.points(P);

for (int j = 0; j <= 3; j++)

{

line(result_image, P[j], P[(j + 1) % 4], color, 1);

}

cout << "最小外接矩形尺寸"<< minrect.size << endl;//最小外接矩形尺寸

cout << "最小外接矩形面积" << minrectmianji << endl;//最小外接矩形尺寸

//绘制轮廓的最小外结圆

Point2f center; float radius;

minEnclosingCircle(contours[t], center, radius); //最小外接圆

circle(result_image, center, radius, color,1);

//计算面积、周长、圆形度、周径比

area = contourArea(contours[t]);//计算轮廓面积

len = arcLength(contours[t], true);//计算轮廓周长

roundness = (4 * CV_PI * area) / (len * len);//圆形度

if (minrectmianji == 0)rectangularity = 0;

else rectangularity = area / minrectmianji;

//周径比,这里的周即周长,径是指上面找到的轮廓最小外接矩形的长的一条边

lenratio = len / (minrect.size.height > minrect.size.width ? minrect.size.height : minrect.size.width);

//输出结果

cout << "轮廓" << t << ":" << endl;

cout << "周长:" << len << endl;

cout << "面积:" << area << endl;

cout << "圆形度:" << roundness << endl;

cout << "矩形度:" << rectangularity << endl;

cout << "周径比:" << lenratio << endl;

}

//显示结果

namedWindow("轮廓图", WINDOW_NORMAL);

imshow("轮廓图", result_image);

waitKey(0);

return 0;

}

原图: 轮廓效果图: 参数一览:

参考链接:

https://blog.csdn.net/Lemon_jay/article/details/89519627 https://blog.csdn.net/qq_42604176/article/details/105588018 https://blog.csdn.net/duiwangxiaomi/article/details/92565308