点击上方“小白学视觉”,选择加"星标"或“置顶”
重磅干货,第一时间送达
本文转自:opencv学堂
轮廓模型
二值图像分析最常见的一个主要方式就是轮廓发现与轮廓分析,其中轮廓发现的目的是为轮廓分析做准备,经过轮廓分析我们可以得到轮廓各种有用的属性信息、常见的如下:
轮廓面积
轮廓周长
轮廓几何矩
轮廓的最小外接矩形
轮廓的最大外接矩形
轮廓的最小外接圆
轮廓的最小外接三角形
轮廓拟合(支持拟合直线、椭圆、圆)
轮廓的凸包
轮廓层次信息提取
多边形逼近
计算欧拉数
函数介绍
OpenCV中提供大量轮廓分析函数,通过这些函数我们可以方便快捷的得到轮廓的各种有用属性信息、高效完成各种二值图像分析需求,下面是我总结的一些常用的函数列表与说明。
OpenCV中轮廓发现函数如下:
void cv::findContours(
InputArray image,
OutputArrayOfArrays contours,
OutputArray hierarchy,
int mode,
int method,
Point offset = Point()
)
参数解释如下:
image: 输入图像、八位单通道的,背景为黑色
contours: 得到的轮廓图像
hierarchy: 层次图像,根据需要提取轮廓层次信息
mode: 决定提取到层次信息内容,是多层还是单层
method: 每个轮廓的编码信息
offset: 表示轮廓偏移,默认为0
轮廓分析相关的常用函数
// 计算轮廓面积
double cv::contourArea(
InputArray contour,
bool oriented = false
)
// 计算轮廓周长
double cv::arcLength(
InputArray curve,
bool closed
)
// 计算几何矩与中心距
Moments cv::moments(
InputArray array,
bool binaryImage = false
)
// 计算最小外接矩形
RotatedRect cv::minAreaRect(
InputArray points
)
// 计算最大外接矩形
Rect cv::boundingRect(
InputArray array
)
// 计算最小外接圆/拟合圆
void cv::minEnclosingCircle(
InputArray points,
Point2f & center,
float & radius
)
// 计算最小外接三角形/拟合三角形
double cv::minEnclosingTriangle(
InputArray points,
OutputArray triangle
)
// 拟合直线
void cv::fitLine(
InputArray points,
OutputArray line,
int distType,
double param,
double reps,
double aeps
)
// 拟合椭圆
RotatedRect cv::fitEllipse(
InputArray points
)
// 计算凸包
void cv::convexHull(
InputArray points,
OutputArray hull,
bool clockwise = false,
bool returnPoints = true
)
// 多边形逼近-逼近真实形状
void cv::approxPolyDP(
InputArray curve,
OutputArray approxCurve,
double epsilon,
bool closed
)
灵活使用上述轮廓属性信息,可以实现对二值图像的几何形状判别、测量、面积过滤、获取每个对象的几何属性包括面积、周长、编码点、形状、层次/位置信息、欧拉数、中心位置、倾斜角度。
这里再分享一个硬币计数的例子!
原图如下:
代码如下:
// 加载图像
Mat img = imread("D:/CoinsB.png");
imshow("Original Image", img);
// 阈值化操作
Mat gray, binary;
cvtColor(img, gray, COLOR_BGR2GRAY);
float t = threshold(gray, binary, 0, 255, THRESH_BINARY|THRESH_OTSU);
imshow("binary", binary);
imwrite("D:/binary1.png", binary);
// 形态学操作
Mat se = getStructuringElement(MORPH_RECT, Size(3, 3));
morphologyEx(binary, binary, MORPH_OPEN, se, Point(-1, -1));
// 轮廓发现
vector hireachy;
vector> contours;
bitwise_not(binary, binary);
findContours(binary, contours, hireachy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point());
Mat result = img.clone();
Point2f center;
float radius;
// 轮廓分析
for (size_t t = 0; t < contours.size(); t++) {
double area = contourArea(contours[t]);
if (area < 1000) {
continue;
}
RotatedRect rrt = fitEllipse(contours[t]);
radius = min(rrt.size.width, rrt.size.height)/2.0;
circle(result, rrt.center, radius, Scalar(0, 0, 255), 4, 8, 0);
Moments mm = moments(contours[t]);
double cx = mm.m10 / mm.m00;
double cy = mm.m01 / mm.m00;
circle(result, Point(cx, cy), 2, Scalar(255, 0, 0), 2, 8, 0);
}
// 显示结果
imshow("result", result);
imwrite("D:/drawing.png", result);
waitKey(0);
最终效果如下:
下载1:OpenCV-Contrib扩展模块中文版教程
在「小白学视觉」公众号后台回复:扩展模块中文教程,即可下载全网第一份OpenCV扩展模块教程中文版,涵盖扩展模块安装、SFM算法、立体视觉、目标跟踪、生物视觉、超分辨率处理等二十多章内容。
下载2:Python视觉实战项目52讲
在「小白学视觉」公众号后台回复:Python视觉实战项目,即可下载包括图像分割、口罩检测、车道线检测、车辆计数、添加眼线、车牌识别、字符识别、情绪检测、文本内容提取、面部识别等31个视觉实战项目,助力快速学校计算机视觉。
下载3:OpenCV实战项目20讲
在「小白学视觉」公众号后台回复:OpenCV实战项目20讲,即可下载含有20个基于OpenCV实现20个实战项目,实现OpenCV学习进阶。
交流群
欢迎加入公众号读者群一起和同行交流,目前有SLAM、三维视觉、传感器、自动驾驶、计算摄影、检测、分割、识别、医学影像、GAN、算法竞赛等微信群(以后会逐渐细分),请扫描下面微信号加群,备注:”昵称+学校/公司+研究方向“,例如:”张三 + 上海交大 + 视觉SLAM“。请按照格式备注,否则不予通过。添加成功后会根据研究方向邀请进入相关微信群。请勿在群内发送广告,否则会请出群,谢谢理解~