//分水岭的图像分割
int main()
{
Mat src=imread("./1/12.png");
if(src.empty())
{
printf("could not load image...");
return;
}
imshow("src",src);
//1.把白色背景变为黑色
for(int row=0;row<src.rows;row++)
{
for(int col=0;col<src.cols;col++)
{
if(src.at<Vec3b>(row,col)==Vec3b(255,255,255))
{
src.at<Vec3b>(row,col)[0]=0;
src.at<Vec3b>(row,col)[1]=0;
src.at<Vec3b>(row,col)[2]=0;
}
}
}
imshow("black background",src);
//2.锐化 sharpen
Mat kernel=(Mat_<float>(3,3)<<1,1,1,1,-8,1,1,1,1);
Mat imgLaplanpe;
Mat sharpenImg=src;
filter2D(src,imgLaplanpe,CV_32F,kernel,Point(-1,-1),0,BORDER_DEFAULT);
src.convertTo(sharpenImg,CV_32F);
Mat result=sharpenImg-imgLaplanpe;
result.convertTo(result,CV_8UC3);
imgLaplanpe.convertTo(imgLaplanpe,CV_8UC3);
imshow("sharpen",result);
//3.二值距离变换 convert to binary
Mat binaryImg;
src=result;
cvtColor(src,result,CV_BGR2GRAY);
threshold(result,binaryImg,40,255,THRESH_BINARY|CV_THRESH_OTSU);
// imshow("binary",binaryImg);
//距离变化
Mat distImg;
distanceTransform(binaryImg,distImg,DIST_L1,3,5);
normalize(distImg,distImg,0,1,NORM_MINMAX);
// imshow("distance result",distImg);
//binary again
threshold(distImg,distImg,0.4,1,THRESH_BINARY);
//二值腐蚀
Mat k1=Mat::zeros(13,13,CV_8UC1);
erode(distImg,distImg,k1);
// imshow("distance binary result",distImg);
//markers
Mat dist_8u;
distImg.convertTo(dist_8u,CV_8U);
vector<vector<Point>> contours;
findContours(dist_8u,contours,RETR_EXTERNAL,CHAIN_APPROX_SIMPLE,Point(0,0));
//create markers
Mat markers=Mat::zeros(src.size(),CV_32SC1);
for(int i=0;i<contours.size();i++)
{
drawContours(markers,contours,static_cast<int>(i),Scalar(static_cast<int>(i)+1),-1);
}
circle(markers,Point(5,5),3,Scalar(255,255,255),-1);
imshow("markers",markers*1000);
//perfrom watershed
watershed(src,markers);
Mat mark=Mat::zeros(markers.size(),CV_8UC1);
markers.convertTo(mark,CV_8UC1);
bitwise_not(mark,mark,Mat());
imshow("marker",mark);
//随机颜色
vector<Vec3b> colors;
for(int 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)b,(uchar)g,(uchar)r));
}
//3通道输出
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);
}
opencv 距离变换与分水岭的图像分割
最新推荐文章于 2022-05-15 08:00:00 发布