#define MAXLABEL 500
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace std;
using namespace cv;
uchar parent[MAXLABEL] = { 0 };
//通过while循环查找根节点,因为标签为根节点时parent存放的值是0
int Find(uchar x, uchar parent[])
{
int i = x;
while (0 != parent[i])
i = parent[i];
return i;
}
//通过while循环找到i,j的根节点,在判断根节点是否一致,不一致,将值小的作为父节点,将关系存储到parent数组里面
void Union(uchar big, uchar small, uchar parent[])
{
uchar i = big;
uchar j = small;
while (0 != parent[i])
i = parent[i];
while (0 != parent[j])
j = parent[j];
if (i != j)
parent[i] = j;
}
Mat Label(Mat &I)
{
/// first pass
int label = 0;
Mat dst = Mat::zeros(I.size(), I.type());
for (int nY = 0; nY < I.rows; nY++)
{
for (int nX = 0; nX < I.cols;nX++)
{
if (I.at<uchar>(nY, nX) != 0)
{
uchar left = nX - 1<0 ? 0 : dst.at<uchar>(nY, nX - 1);//边界点注意
uchar up = nY - 1<0 ? 0 : dst.at<uchar>(nY - 1, nX);
if (left != 0 || up != 0)
{
if (left != 0 && up != 0)
{
dst.at<uchar>(nY, nX) = min(left, up);
if (left < up)
Union(up, left, parent);
else if (up<left)
Union(left, up, parent);
}
else
dst.at<uchar>(nY, nX) = max(left, up);
}
else
{
dst.at<uchar>(nY, nX) = ++label;
}
}
}
}
/// second pass
for (int nY = 0; nY < I.rows; nY++)
{
for (int nX = 0; nX < I.cols; nX++)
{
if (I.at<uchar>(nY, nX) == 1)
dst.at<uchar>(nY, nX) = Find(dst.at<uchar>(nY, nX), parent);
}
}
return dst;
}
int main()
{
Mat image = imread("d:/zimu.png",1);
Mat gray,thresh;
cvtColor(image,gray,CV_RGB2GRAY);
threshold(gray,thresh,40,1,THRESH_BINARY_INV);
imshow("erzhi", thresh);
Mat result = Label(thresh);
namedWindow("结果",0);
imshow("结果",result);
waitKey();
return 0;
}
OpenCV_连通区域分析----Two-Pass法
猜你喜欢
转载自blog.csdn.net/xiachong27/article/details/88937191
今日推荐
周排行