OpenCV-连通域标记

本文介绍了如何使用OpenCV进行连通域标记,通过闭运算优化二值图像,减少计数误差,以实现在计算机视觉中如细胞和硬币的计数任务。通过实例展示了从读取图像、二值化、闭运算到连通域标记的过程。
摘要由CSDN通过智能技术生成

目的

了解如何使用OpenCV进行连通域的标记以及计数,从而可以实现计算机视觉中的细胞计数、硬币计数等计数任务。

方法

Source:机器视觉技术与应用_中国大学MOOC(慕课) (icourse163.org)

函数介绍

连通域标记函数

绘制矩阵函数

状态矩阵stats解读:

 状态矩阵每一行代表一个连通域,每一列分别代表:连通域最小外接四边形的x坐标、连通域最小外接四边形的y坐标、连通域最小外接四边形的宽、连通域最小外接四边形的高以及连通域的面积;

 状态矩阵的第一行表示的是背景,一般不计入连通域的数量。

连通域中心矩阵centroids:

实践练习

代码(C++):

#include<opencv2/opencv.hpp>

using namespace std;

using namespace cv;

int main() {

void connectedWithStats();

connectedWithStats();

return 0;

}

void connectedWithStats() {

//读取图像并转为灰度图

Mat srcMat = imread("E:\\Projects\\C++\\morphology_practice\\test_data\\coins.png", 0);

//判断图像是否读取成功、

if (srcMat.empty()) {

cout << "fail to read pic!" << endl;

return;

}

//定义图像容器

Mat stats;

Mat centroids;

Mat labels;

Mat thresh_Mat;

Mat erode_Mat;

Mat close_Mat;

//大津法处理图像(图像二值化,大津法,类内方差最小,类间方差最大)

threshold(srcMat, thresh_Mat, 100, 255, THRESH_OTSU);

//使用闭运算

//定义结构元素

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

//闭运算

morphologyEx(thresh_Mat, close_Mat, MORPH_CLOSE, element);

//进行连通域标记

int nComp = connectedComponentsWithStats(close_Mat, labels, stats, centroids, 8, CV_32S);

//减去背景0,并输出连通域的个数

cout << "硬币个数为: " << nComp - 1 << endl;

//对识别出的连通域加最小外接边框

for (int i = 1;i < nComp;i++) {

//定义Rect类

Rect bandbox;

bandbox.x = stats.at<int>(i, 0); //表示stats状态矩阵的第i行的第0个元素;

bandbox.y = stats.at<int>(i, 1);

bandbox.width = stats.at<int>(i, 2);

bandbox.height = stats.at<int>(i, 3);

//使用rectangle函数绘制矩形

rectangle(thresh_Mat, bandbox, 255, 1, 8, 0);

}

imshow("thresh_Mat", thresh_Mat);

imshow("srcMat", srcMat);

waitKey(0);

}

实验图像

结果

讨论

如果直接对二值图像进行连通域标记,标记结果为11,这是错误的。所以这篇文章先对二值图像进行了闭运算的操作,将二值化不佳的硬币中的黑色部分填充起来,减少计数错误的概率。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值