ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

OpenCV使用分水岭算法实现图像分割

2022-04-12 22:03:57  阅读:190  来源: 互联网

标签:index int finalResult OpenCV 算法 marker 255 分水岭 row


一、概述

  案例:使用分水岭算法实现图像的分割实现

  API:介绍参考上一遍

  实现步骤:

    1.输入图像

    2.灰度化

    3.二值化

    4.执行距离变换

    5.归一化

    6.二值化

    7.生成marker:通过findContours+drawContours来创建一个marker

    8.将7生成的marker放入分水岭函数:watershed

    9.给marker着色

    10.输出着色后的图像

  ps:此算法关键点在于生成marker。生成marker之后其实已经完成了算法,后面的着色只是为了让输出更加好看。

 

 

二、代码样例

 Mat src = imread(filePath);//输入原图
    if(src.empty()){
        //
        qDebug()<<"图像为空";
        return;
    }
    //图像灰度化
    Mat gray;
    cvtColor(src,gray,COLOR_BGR2GRAY);
    //图像二值化
    Mat binary;
    threshold(gray,binary,0,255,THRESH_BINARY|cv::THRESH_OTSU);
    imshow("binary",binary);
    qDebug()<<"binary....";
    //执行距离变换
    Mat dist;
    distanceTransform(binary,dist,DistanceTypes::DIST_L2,3,CV_32F);
    qDebug()<<"distanceTransform....";
    normalize(dist,dist,0.0,1.0,NORM_MINMAX);//归一化0~1之间
    qDebug()<<"normalize....";
    //重新二值化预值
    threshold(dist,dist,0.1,1.0,THRESH_BINARY);
    qDebug()<<"threshold....";
    normalize(dist,dist,0,255,NORM_MINMAX);
    qDebug()<<"normalize....";
    dist.convertTo(dist,CV_8UC1);//
    qDebug()<<"convertTo....";

    //开始生成marker并绘制出来
    vector<vector<Point>> contours;
    vector<Vec4i> heri;
    findContours(dist,contours,RETR_CCOMP,CHAIN_APPROX_SIMPLE);
    qDebug()<<"findContours....";

    Mat marker = Mat::zeros(dist.size(),CV_32S);
    for(size_t i = 0;i<contours.size();i++){
        drawContours(marker,contours,i,Scalar(i+1),-1, 8, heri, INT_MAX);
    }
    qDebug()<<"drawContours...."<<contours.size();
    circle(marker, Point(5, 5), 3, Scalar(255), -1);
    watershed(src,marker);
    qDebug()<<"watershed....";
//    marker.convertTo(marker,CV_8UC1);//ps:此处需要注意(到这里实际上已经完成了算法)。一旦不转换就不能用imshow,一旦转换了后面的marker着色就会出现异常
//    imshow("marker",marker);
    qDebug()<<"imshow(marker,marker);....";
    //生成颜色数组
    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)b, (uchar)g, (uchar)r));
    }

    //给marker着色
    Mat finalResult = Mat::zeros(dist.size(),CV_8UC3);//三通道彩色图像
    int index = 0;
    for(int row = 0;row<marker.rows;row++){
        for(int col = 0;col<marker.cols;col++){
            index = marker.at<int>(row,col);
            if(index>0&&index<=contours.size()){
                finalResult.at<Vec3b>(row,col)  = colors[index-1];
            }else{
                finalResult.at<Vec3b>(row,col) = Vec3b(255,255,255);
            }
        }
    }
    imshow("finalResult",finalResult);

 

三、图片演示

案例1:分割蚕茧

 

案例二:分割任意图像

 

 

标签:index,int,finalResult,OpenCV,算法,marker,255,分水岭,row
来源: https://www.cnblogs.com/tony-yang-flutter/p/16137735.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有