【Opencv3+Python3入门(20)分水岭算法】

版权声明:本文为博主原创文章,转载时须注明出处 https://blog.csdn.net/KID_yuan/article/details/89575361

分水岭算法

基于距离变换的分水岭分割算法一般流程:

1,输入图像

2,变换为灰度图像

3,二值化图像

4,距离变换

5,寻找种子点

6,生成marker

7,分水岭变换

8,输出图像

#20,分水岭算法
import cv2 as cv
import numpy as np

def image_Watershed(image):
    print(image.shape)
    #首先对原图像进行降噪处理
    image=cv.pyrMeanShiftFiltering(image,10,100)
    #将图像转化为灰度图像
    gray=cv.cvtColor(image,cv.COLOR_BGR2GRAY)
    #对灰度图像进行二值化处理
    ret,binary=cv.threshold(gray,0,255,cv.THRESH_BINARY | cv.THRESH_OTSU)
    #将二值化图像显示
    cv.imshow("binary",binary)
    #由于图像内部存在一些噪声点,因此先对图像进行形态学开操作
    #设置形态学结构处理的核
    kernel=cv.getStructuringElement(cv.MORPH_RECT,(3,3))
    #对二值图像进行开运算操作之后再进行膨胀操作
    open_image=cv.morphologyEx(binary,cv.MORPH_OPEN,kernel,iterations=2)
    dilate_image=cv.dilate(open_image,kernel,iterations=3)
    #显示图像
    cv.imshow("od_image",dilate_image)
    #距离变换
    dist=cv.distanceTransform(dilate_image,cv.DIST_L2,3)
    #将距离归一化处理
    dist_output=cv.normalize(dist,0,1.0,cv.NORM_MINMAX)
    #将距离变换的结果显示
    cv.imshow("dist_demo",dist_output*60)
    
    #根据阈值将marker选出并显示其二值化形式图像
    ret, surface = cv.threshold(dist, dist.max()*0.6, 255, cv.THRESH_BINARY)
    surface_fg = np.uint8(surface)
    cv.imshow("surface-bin", surface_fg)
    unknown = cv.subtract(dilate_image, surface_fg)
    ret, markers = cv.connectedComponents(surface_fg)
    #打印出边界个数为25,这里把最外面的图像矩形框也算成为一个边界了
    print(ret)
    # 对marker进行分水岭变换
    markers = markers + 1
    #将像素值为0的为分水岭
    markers[unknown==255] = 0
    markers = cv.watershed(src, markers=markers)
    #将分水岭边界设置为红色
    src[markers==-1] = [0, 0, 255]
    #显示结果
    cv.imshow("result", src)
src = cv.imread(r'F:\OutputResult\SrcImage\coins3.jpg')
cv.imshow("src",src)
image_Watershed(src)
cv.waitKey(0)
cv.destroyAllWindows()

先进行二值化,然后进行开运算之后加上膨胀操作消除内部白色斑点效果如下:

最终输出结果:边框数为25个,这里把最外面的矩形框也算成了一个边界了。

猜你喜欢

转载自blog.csdn.net/KID_yuan/article/details/89575361
今日推荐