• 分水岭分割算法(watershed segmentation)的C++实现(法2)


    运行环境:ubuntu16.04+Qt+opencv2.4.13.3

    watershed.cpp

    #include "opencv2/imgproc/imgproc.hpp"
    #include "opencv2/highgui/highgui.hpp"
    
    #include <iostream>
    
    using namespace cv;
    using namespace std;
    
    Vec3b RandomColor(int value);  //生成随机颜色函数
    
    int main( char argc, char* argv[] )
    {
        Mat image=imread("/home/osksh/skin_c/06Apr03Face.jpg");
    
    //    Mat image=imread('/home/osksh/skin_c/family.jpg');    //载入RGB彩色图像
        imshow("Source Image",image);
    
        //灰度化,滤波,Canny边缘检测
        Mat imageGray;
        cvtColor(image,imageGray,CV_RGB2GRAY);//灰度转换
        GaussianBlur(imageGray,imageGray,Size(5,5),2);   //高斯滤波
        imshow("Gray Image",imageGray);
        Canny(imageGray,imageGray,80,150);
        imshow("Canny Image",imageGray);
    
        //查找轮廓
        vector<vector<Point>> contours;
        vector<Vec4i> hierarchy;
        findContours(imageGray,contours,hierarchy,RETR_TREE,CHAIN_APPROX_SIMPLE,Point());
        Mat imageContours=Mat::zeros(image.size(),CV_8UC1);  //轮廓
        Mat marks(image.size(),CV_32S);   //Opencv分水岭第二个矩阵参数
        marks=Scalar::all(0);
        int index = 0;
        int compCount = 0;
        for( ; index >= 0; index = hierarchy[index][0], compCount++ )
        {
            //对marks进行标记,对不同区域的轮廓进行编号,相当于设置注水点,有多少轮廓,就有多少注水点
            drawContours(marks, contours, index, Scalar::all(compCount+1), 1, 8, hierarchy);
            drawContours(imageContours,contours,index,Scalar(255),1,8,hierarchy);
        }
    
        //我们来看一下传入的矩阵marks里是什么东西
        Mat marksShows;
        convertScaleAbs(marks,marksShows);
        imshow("marksShow",marksShows);
        imshow("轮廓",imageContours);
        watershed(image,marks);
    
        //我们再来看一下分水岭算法之后的矩阵marks里是什么东西
        Mat afterWatershed;
        convertScaleAbs(marks,afterWatershed);
        imshow("After Watershed",afterWatershed);
    
        //对每一个区域进行颜色填充
        Mat PerspectiveImage=Mat::zeros(image.size(),CV_8UC3);
        for(int i=0;i<marks.rows;i++)
        {
            for(int j=0;j<marks.cols;j++)
            {
                int index=marks.at<int>(i,j);
                if(marks.at<int>(i,j)==-1)
                {
                    PerspectiveImage.at<Vec3b>(i,j)=Vec3b(255,255,255);
                }
                else
                {
                    PerspectiveImage.at<Vec3b>(i,j) =RandomColor(index);
                }
            }
        }
        imshow("After ColorFill",PerspectiveImage);
    
        //分割并填充颜色的结果跟原始图像融合
        Mat wshed;
        addWeighted(image,0.4,PerspectiveImage,0.6,0,wshed);
        imshow("AddWeighted Image",wshed);
    
        waitKey();
    }
    
    Vec3b RandomColor(int value)
    {
        value=value%255;  //生成0~255的随机数
        RNG rng;
        int aa=rng.uniform(0,value);
        int bb=rng.uniform(0,value);
        int cc=rng.uniform(0,value);
        return Vec3b(aa,bb,cc);
    }
    #include"opencv2/imgproc/imgproc.hpp"
    #include"opencv2/highgui/highgui.hpp"
    
    
    #include<iostream>
    
    
    usingnamespacecv;
    usingnamespacestd;
    
    
    Vec3bRandomColor(intvalue);//生成随机颜色函数
    
    
    intmain(charargc,char*argv[])
    {
    Matimage=imread("/home/osksh/skin_c/06Apr03Face.jpg");
    
    
    //Matimage=imread('/home/osksh/skin_c/family.jpg');//载入RGB彩色图像
    imshow("SourceImage",image);
    
    
    //灰度化,滤波,Canny边缘检测
    MatimageGray;
    cvtColor(image,imageGray,CV_RGB2GRAY);//灰度转换
    GaussianBlur(imageGray,imageGray,Size(5,5),2);//高斯滤波
    imshow("GrayImage",imageGray);
    Canny(imageGray,imageGray,80,150);
    imshow("CannyImage",imageGray);
    
    
    //查找轮廓
    vector<vector<Point>>contours;
    vector<Vec4i>hierarchy;
    findContours(imageGray,contours,hierarchy,RETR_TREE,CHAIN_APPROX_SIMPLE,Point());
    MatimageContours=Mat::zeros(image.size(),CV_8UC1);//轮廓
    Matmarks(image.size(),CV_32S);//Opencv分水岭第二个矩阵参数
    marks=Scalar::all(0);
    intindex=0;
    intcompCount=0;
    for(;index>=0;index=hierarchy[index][0],compCount++)
    {
    //对marks进行标记,对不同区域的轮廓进行编号,相当于设置注水点,有多少轮廓,就有多少注水点
    drawContours(marks,contours,index,Scalar::all(compCount+1),1,8,hierarchy);
    drawContours(imageContours,contours,index,Scalar(255),1,8,hierarchy);
    }
    
    
    //我们来看一下传入的矩阵marks里是什么东西
    MatmarksShows;
    convertScaleAbs(marks,marksShows);
    imshow("marksShow",marksShows);
    imshow("轮廓",imageContours);
    watershed(image,marks);
    
    
    //我们再来看一下分水岭算法之后的矩阵marks里是什么东西
    MatafterWatershed;
    convertScaleAbs(marks,afterWatershed);
    imshow("AfterWatershed",afterWatershed);
    
    
    //对每一个区域进行颜色填充
    MatPerspectiveImage=Mat::zeros(image.size(),CV_8UC3);
    for(inti=0;i<marks.rows;i++)
    {
    for(intj=0;j<marks.cols;j++)
    {
    intindex=marks.at<int>(i,j);
    if(marks.at<int>(i,j)==-1)
    {
    PerspectiveImage.at<Vec3b>(i,j)=Vec3b(255,255,255);
    }
    else
    {
    PerspectiveImage.at<Vec3b>(i,j)=RandomColor(index);
    }
    }
    }
    imshow("AfterColorFill",PerspectiveImage);
    
    
    //分割并填充颜色的结果跟原始图像融合
    Matwshed;
    addWeighted(image,0.4,PerspectiveImage,0.6,0,wshed);
    imshow("AddWeightedImage",wshed);
    
    
    waitKey();
    }
    
    
    Vec3bRandomColor(intvalue)
    {
    value=value%255;//生成0~255的随机数
    RNGrng;
    intaa=rng.uniform(0,value);
    intbb=rng.uniform(0,value);
    intcc=rng.uniform(0,value);
    returnVec3b(aa,bb,cc);
    }

  • 相关阅读:
    android 7.0带来的
    转 android 侧滑实现
    (转)30道面试题
    【转】关于手机号注册的一些思考
    一个美国人对"智能制造"的思考!
    【转】社区O2O的增量与存量,机会在哪?
    【转】30岁之前打好基础,无惧职场“35岁现象”! | 人力资源心理学
    Linux 复制、移动覆盖文件不提示
    使用DDMS测试安卓手机APP的性能(android)
    【转】测试思考——测试人员需要具备哪些素质?
  • 原文地址:https://www.cnblogs.com/wangyarui/p/8042866.html
Copyright © 2020-2023  润新知