void DisplayRegion(int num, Mat& src, Mat& markers, const cv::String& winname)
{
RNG rng(123456);
vector<Vec3b> color(num);
for (size_t i = 1; i < num; i++)
{
color[i] = Vec3b(rng.uniform(0, 256), rng.uniform(0, 256), rng.uniform(0, 256)); //设置目标颜色
}
Mat markersColor = Mat::zeros(src.size(), src.type());
int w = src.cols;
int h = src.rows;
for (size_t row = 0; row < h; row++)
{
for (size_t col = 0; col < w; col++)
{
int label = markers.at<int>(row, col);
if (label == -1) continue;
markersColor.at<Vec3b>(row, col) = color[label];
}
}
imshow(winname, markersColor);
}
void connectedComponents_watershed(Mat& dist_binary, Mat& src)
{
//定义一个标记图像
Mat markers(src.size(), CV_32S);
//计算连通域
int num = connectedComponents(dist_binary, markers);
//基于标记的分水岭分割
watershed(src, markers);
//使用不同的颜色显示各个区域
DisplayRegion(num, src, markers, "result2");
}
void findContours_watershed(Mat& dist_binary, Mat& src)
{
//定义一个标记图像,并初始化为0
Mat markers(src.size(), CV_32S);
markers = Scalar::all(0);
cout << markers.channels() << endl;
//寻找轮廓
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
findContours(dist_binary, contours, hierarchy, RETR_CCOMP, CHAIN_APPROX_SIMPLE);
//绘制轮廓
for (int index = 0; index < contours.size(); index++)
drawContours(markers, contours, index, Scalar::all(index+1), -1, 8, hierarchy, INT_MAX);
/*Mat contourShow(dist_binary.size(), CV_8UC3, Scalar(0, 0, 0));
RNG rng(0);
for (size_t i = 0; i < contours.size(); i++)
{
Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
drawContours(contourShow, contours, i, color, -1, 8, hierarchy, INT_MAX);
}
imshow("contourShow", contourShow);*/
//基于标记的分水岭分割
watershed(src, markers);
//使用不同的颜色显示各个区域
int num = contours.size();
DisplayRegion(num, src, markers, "result1");
}
int main()
{
Mat src, gray, binary, open_img;
src = imread("..//beichen//00000.jpg");
cvtColor(src, gray, COLOR_BGR2GRAY);
threshold(gray, binary, 0, 255, THRESH_BINARY_INV + THRESH_OTSU);
cv::imshow("binary", binary);
//形态学操作
Mat k = Mat::ones(3, 3, CV_8U);
morphologyEx(binary, open_img, MORPH_OPEN, k);
erode(open_img, open_img, k, Point(-1, -1), 3);
cv::imshow("open_img", open_img);
//方式一
findContours_watershed(open_img, src);
//方式二
connectedComponents_watershed(open_img, src);
cv::imshow("原图", src);
waitKey(0);
}
#endif
基于图像标记的分水岭算法实现
于 2024-06-20 17:23:18 首次发布