分水岭分割算法(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);
}

原文地址:https://www.cnblogs.com/wangyarui/p/8042866.html