前言
OpenCV好像有自带的求连通域的函数,奈何自己用的版本里没有这个功能,只好自己写orz
求连通域,大概有两种方法:
Two-Pass(两遍扫描法)
Seed Filling(种子填充法)
两种算法原理可以到这位博主的博客看看。
实现过程
本文应该是采用了第二种方法,种子填充法。
- 参数 Mat & input 说明:这是一个二值图像,值为0或255,0(黑色)表示背景区域,255(白色)表示物料区域。
- 函数 labelmark 使用两层for循环遍历 Mat input 矩阵;
内层循环中两个串联的 if 语句块:
// 第一个防止 fill_4 函数递归次数太大,内存不够。
if((input.at<unsigned char>(i, j) != 255 && input.at<unsigned char>(i, j) != 0))
//(2)第二个就是实现四邻域的递归判断
if (input.at<unsigned char>(i,j)==255)
- int labelnum;
标签值。测试时为了便于区分,初始为1,每次递增10 - input.at(i, j) = labelnum + 50;
加50,也是为了使灰度值更大一点,所以并不重要。 - 其他的代码中注释应该够了。
代码实现
void fill_4(int x, int y, int count, Mat& input, int & jishu) {
//cout << "x = "<< x << ", y = " << y <<", count = "<< count << endl;
jishu++;
if (x-1<=0 || x+1 >=319 || y-1<=0 ||y+1>=319)