分水岭算法的步骤,分水岭算法的基本思想
关于分水岭算法的原理介绍和原理,可以看看这个博客。上面有很多动图,非常生动有趣。我们先来看看opencv提供的分水岭算法的功能接口。
void分水岭(InputArray图像,InputOutputArray标记);输入图像必须是3通道RGB图像,最关键的是第二个参数markers,它包含了不同区域的轮廓,每个轮廓都有自己唯一的编号。轮廓的定位可以通过Opencv中的findContours方法来实现。然后分水岭算法会以标记引入的轮廓为种子(所谓注水点),根据分水岭算法规则判断图像中的其他像素,划定每个像素的区域归属,直到图像中的所有像素都处理完毕。并且在区域之间的边界处的值被设置为“-1”以进行区分。
算法步骤参考
使用Otsu法将RGB图像转换为二值图像,并进行形态学闭运算。形态学闭运算距离变换将距离变换结果归一化为[0-1],将图像取值范围改为8位(0-255)。然后用Otsu法将RGB图像转换成二值图像,并进行形态学闭运算。findContours用于查找标记,并对原始图像进行形态学腐蚀。分水岭算法用于随机分配颜色和显示码,实现//分水岭算法。
Mat WaterSegment(Mat src) {
int row=src.rows
int col=src.cols
//1.灰度RGB图像
mat gray image=speed _ RGB 2 gray(src);
//2.用Otsu法转换成二值图像,做形态学闭运算。
threshold(灰度图像,灰度图像,0,255,THRESH _ BINARY THRESH _ OTSU);
//3.形态学闭运算
mat kernel=getStructuringElement(MORPH _ RECT,Size(9,9),Point(-1,-1));
morphologyEx(灰度图像,灰度图像,MORPH_CLOSE,内核);
//4.距离变换
distanceTransform(灰度图像,灰度图像,DIST_L2,MASK _面具_3,5);
//5.将图像归一化到范围[0,1]
normalize(grayImage,grayImage,0,1,NORM _ MINMAX);
//6.将图像值范围更改为8位(0-255)
grayImage.convertTo(grayImage,CV _ 8uc 1);
//7.然后用Otsu法转换成二值图像,做形态学闭运算。
threshold(灰度图像,灰度图像,0,255,THRESH _ BINARY THRESH _ OTSU);
morphologyEx(灰度图像,灰度图像,MORPH_CLOSE,内核);
//8.使用查找轮廓来查找标记
向量向量点轮廓;
findContours(grayImage,Contours,RETR树,CHAIN_APPROX_SIMPLE,Point(-1,-1));
Mat marks=Mat:zeros(gray image . size(),CV _ 32 SC1);
for(size _ t I=0;I contours . size();我)
{
//static_cast int (i 1)用于分水岭的不同标记,区域1、2、3.这样就可以分了。
drawContours(marks,Contours,static_cast int (i),Scalar:all(static_cast int (i 1)),2);
}
//9.对原始图像执行形态学蚀刻操作。
mat k=getStructuringElement(MORPH _ RECT,Size(3,3),Point(-1,-1));
morphologyEx(src,src,MORPH_ERODE,k);
//10.调用opencv的分水岭算法
分水岭(src,marks);
//11.随机分配颜色
矢量Vec3b颜色;
for(size _ t I=0;I contours . size();i ) {
int r=theRNG()。制服(0,255);
int g=theRNG()。制服(0,255);
int b=theRNG()。制服(0,255);
colors . push _ back(Vec3b((uchar)b,(uchar)g,(uchar)r));
}
//12.显示
Mat dst=Mat:zeros(marks.size(),CV _ 8uc 3);
int index=0;
for(int I=0;我划船;i ) {
for(int j=0;j colj ) {
index=marks.at int (i,j);
if(index 0 index=contours . size()){
Vec3b (i,j)=colors[index-1];
}
else if (index==-1)
{
dst.at Vec3b (i,j)=Vec3b(255,255,255);
}
否则{
dst.at Vec3b (i,j)=Vec3b(0,0,0);
}
}
}
返回dst
}算法效果
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。