前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >OpenCV | 二值图像分析的技巧都在这里

OpenCV | 二值图像分析的技巧都在这里

作者头像
OpenCV学堂
发布2020-02-21 13:31:27
1.7K0
发布2020-02-21 13:31:27
举报
轮廓属性

二值图像分析最常见的一个主要方式就是轮廓发现轮廓分析,其中轮廓发现的目的是为轮廓分析做准备,经过轮廓分析我们可以得到轮廓各种有用的属性信息、常见的如下:

  • 轮廓面积
  • 轮廓周长
  • 轮廓几何矩
  • 轮廓的最小外接矩形
  • 轮廓的最大外接矩形
  • 轮廓的最小外接圆
  • 轮廓的最小外接三角形
  • 轮廓拟合(支持拟合直线、椭圆、圆)
  • 轮廓的凸包
  • 轮廓层次信息提取
  • 多边形逼近
  • 计算欧拉数

函数介绍

OpenCV中提供大量轮廓分析函数,通过这些函数我们可以方便快捷的得到轮廓的各种有用属性信息、高效完成各种二值图像分析需求,下面是我总结的一些常用的函数列表与说明。

OpenCV中轮廓发现函数如下:

代码语言:javascript
复制
void cv::findContours(
InputArray      image,
OutputArrayOfArrays contours,
OutputArray hierarchy,
int   mode,
int   method,
Point       offset = Point()
)

参数解释如下:

image: 输入图像、八位单通道的,背景为黑色 contours: 得到的轮廓图像 hierarchy: 层次图像,根据需要提取轮廓层次信息 mode: 决定提取到层次信息内容,是多层还是单层 method: 每个轮廓的编码信息 offset: 表示轮廓偏移,默认为0

轮廓分析相关的常用函数

代码语言:javascript
复制
// 计算轮廓面积
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
)

灵活使用上述轮廓属性信息,可以实现对二值图像的几何形状判别、测量、面积过滤、获取每个对象的几何属性包括面积、周长、编码点、形状、层次/位置信息、欧拉数、中心位置、倾斜角度。

综合运用代码演示

2020年 以前我分享过一些综合使用的例子,列表如下(都看过你就赢了):

二值图像分析案例精选

OpenCV二值图像案例分析精选 | 第二期

OpenCV轮廓层次分析实现欧拉数计算

OpenCV寻找复杂背景下物体的轮廓

如何识别出轮廓准确的长和宽

OpenCV中几何形状识别与测量

OpenCV中BLOB特征提取与几何形状分类

OpenCV直线拟合检测

OpenCV中实现曲线与圆拟合

这里再分享一个硬币计数的例子!

原图如下:

代码如下:

代码语言:javascript
复制
// 加载图像
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<Vec4i> hireachy;
vector<vector<Point>> 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);

最终效果如下:

2020年少写废话,觉得不是废话就点赞,做好自己该做的事情就是对自己最好的交待!

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-01-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 OpenCV学堂 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档