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表示成功执行此函数
}
运行结果: