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

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

//分水岭的图像分割

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

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值