opencv图像分割3-分水岭方法

#include<opencv2\opencv.hpp>
#include<iostream>
using namespace cv;
using namespace std;
int main5()
{
	Mat src = imread("E:\\vs2015\\opencvstudy\\2kmeans.jpg", 1);
	if (src.empty())
	{
		cout << "could not load the image!" << endl;
		return -1;  //返回-1代表函数执行失败
	}
	imshow("input", src);

	Mat gray, binary, shifted;
	pyrMeanShiftFiltering(src, shifted, 21, 51);
	imshow("shifted:", shifted);
	//imwrite("5分水岭算法shift.jpg", shifted);

	cvtColor(shifted, gray, COLOR_BGR2GRAY);
	threshold(gray, binary,0,255,THRESH_BINARY| THRESH_OTSU);
	//imshow("binary", binary);

	//distance transform
	Mat dist;
	distanceTransform(binary, dist, DistanceTypes::DIST_L2, 3, CV_32F);
	normalize(dist, dist, 0, 1, NORM_MINMAX);
	//imshow("distance result", dist);

	//binary
	threshold(dist, dist, 0.4, 1, THRESH_BINARY);
	//imshow("distance binary", dist);

	//markers
	Mat dist_m;
	dist.convertTo(dist_m, CV_8U);  //单通道图像
	vector<vector<Point>> contours;
	findContours(dist_m, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point(0, 0));  //找到所有轮廓

	//create markers
	Mat markers = Mat::zeros(src.size(), CV_32SC1);
	for (size_t i = 0; i < contours.size(); i++)
	{
		drawContours(markers, contours, static_cast<int>(i), Scalar::all(static_cast<int>(i) + 1), - 1);//-1表示填充

	}
	circle(markers, Point(5, 5), 3, Scalar(255), -1);
	imshow("markers", markers * 10000);

	//形态学操作,去掉干扰
	Mat k = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));
	morphologyEx(src, src, MORPH_RECT, k);


	//完成分水岭变换
	watershed(src, markers);
	Mat mark = Mat::zeros(markers.size(), CV_8UC1);
	markers.convertTo(mark, CV_8UC1);
	bitwise_not(mark, mark, Mat());  //此处mask为空
	imshow("watershedResult", mark);

	vector<Vec3b> colors;
	for (size_t i = 0; i < contours.size(); i++)
	{
		int r = theRNG().uniform(0, 255);
		int g = theRNG().uniform(0, 255);
		int b = theRNG().uniform(0, 255);
		colors.push_back(Vec3b((uchar)r, (uchar)g, (uchar)b));
	}
	//颜色填充与最终显示
	Mat dst = Mat::zeros(markers.size(), CV_8UC3);
	for (int row = 0; row < markers.rows; row++)
	{

		for (int col = 0; col < markers.cols; col++)
		{
			int index = markers.at<int>(row, col);
			if (index > 0 && index <= static_cast<int>(contours.size()))
			{
				dst.at<Vec3b>(row, col) = colors[index - 1];
			}
			else
			{
				dst.at<Vec3b>(row, col) = Vec3b(0, 0, 0);
			}
		}
	}

	imshow("dst", dst);
	cout << "轮廓个数:" << contours.size() << endl;
	waitKey(0);
	return 0;  //返回值为0表示成功执行此函数
}

运行结果:

 

猜你喜欢

转载自blog.csdn.net/weixin_38383877/article/details/89712958
今日推荐