1.分水岭方法介绍
OpenCV 提供了分水岭算法(Watershed Algorithm)的实现, 使用分水岭算法对图像进行分割,将图像的不同区域分割成互不干扰的区域。分水岭算法模拟了水在图像中的扩散和聚集过程,将标记的边界被看作是阻挡水扩散的高山,通过模拟水的扩散和聚集,最终确定图像的分割边界。
如图所示:水从山低蔓延,而高山阻止水扩散。
2.分水岭法分割图像函数watershed()
void cv::watershed ( InputArray image,
InputOutputArray markers
)
- image:输入图像,数据类型为CV_8U的三通道图像
- markers:输入/输出CV_32S的单通道图像的标记结果,与原图像具有相同的尺寸
示例代码:
基于标记图像中画的线来对原图像进行分割。
void watershed_f(Mat mat,Mat mat2){//mat原图像 mat2含有标记的图像// 把四通道原图像转换成三通道Mat image;cv::cvtColor(mat, image, cv::COLOR_BGRA2BGR);Mat imgGray,imgMask,img_;Mat maskWaterShed;//watershed()函数的参数//对标记的图像进行灰度化Mat image2;cvtColor(mat2,imgGray,COLOR_BGR2GRAY);//对标记的图像二值化并开运算,可得到标记画的线threshold(imgGray,imgMask,250,255,THRESH_BINARY);Mat k= getStructuringElement(0,Size(3,3));morphologyEx(imgMask,imgMask,MORPH_OPEN,k);//显示二值化并开运算的结果imwrite("/sdcard/DCIM/imgMask2.png",imgMask);//对二值化后的标记图像进行轮廓检测,可得到画的线的轮廓vector<vector<Point>> contours;vector<Vec4i> hierarchy;findContours(imgMask,contours,hierarchy,RETR_TREE,CHAIN_APPROX_SIMPLE,Point());//在maskWaterShed上绘制出上面得到的轮廓maskWaterShed=Mat::zeros(imgMask.size(),CV_32S);for(int index=0;index<contours.size();index++){drawContours(maskWaterShed,contours,index,Scalar::all(index+1),2,8);}//分水岭算法 需要对原图像进行处理watershed(image,maskWaterShed);//显示分水岭算法分割的每个区域imwrite("/sdcard/DCIM/maskWaterShed2.png",maskWaterShed);//随机生成几种颜色vector<Vec3b> colors;for(int i=0;i<contours.size();i++){int b=theRNG().uniform(0,255);int g=theRNG().uniform(0,255);int r=theRNG().uniform(0,255);colors.push_back(Vec3b((uchar)b,(uchar)g,(uchar)r));}//给分水岭算法分割的每个区域添加颜色Mat resultImg=Mat(image2.size(),CV_8UC3);for(int i=0;i<imgMask.rows;i++){for(int j=0;j<imgMask.cols;j++){//绘制每个区域的颜色int index=maskWaterShed.at<int>(i,j);if(index==-1)//区域间的值被置为-1(边界){resultImg.at<Vec3b>(i,j)=Vec3b(255,255,255);}else if(index<=0||index>contours.size())//没有标记清楚的区域被置为0{resultImg.at<Vec3b>(i,j)=Vec3b(0,0,0);}else{resultImg.at<Vec3b>(i,j)=colors[index-1];}}}//显示给分水岭算法分割的每个区域添加颜色的结果imwrite("/sdcard/DCIM/resultImg2.png",resultImg);//分割的区域与原图像结合resultImg=resultImg*0.8+image*0.2;imwrite("/sdcard/DCIM/resultImg3.png",resultImg);}