opencv 距离变换与分水岭的图像分割

opencv 专栏收录该内容
24 篇文章 0 订阅

在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

//分水岭的图像分割

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);
}

在这里插入图片描述

  • 1
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

相关推荐
©️2020 CSDN 皮肤主题: 岁月 设计师:pinMode 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值