OpenCV+python:分水岭算法

1,概念简介
现实中我们可以或者说可以想象有山有湖的景象,那么那一定是水绕 山,山围水的情形。当然在需要的时候,要人工构筑分水岭,以防集水盆之间的互相穿透。而区分高山(plateaus)与水的界线,以及湖与湖之间的间隔或 都是连通的关系,就是我们可爱的分水岭(watershed)

分水岭算法是在分割的过程中,它会把跟临近像素间的相似性作为重要的参考依据,从而将在空间位置上相近并且灰度值相近(求梯度)的像素点互相连接起来构成一个封闭的轮廓。

分水岭算法常用的操作步骤:彩色图像灰度化,然后再求梯度图,最后在梯度图的基础上进行分水岭算法,求得分段图像的边缘线。

OpenCV+python:分水岭算法_第1张图片

如果图像中的目标物体是连接在一起的,则分割起来会更困难,分水岭分割算法经常用于处理这类问题,通常会取得比较好的效果。分水岭分割算法把图像看成一幅“地形图”,其中亮度比较强的区域像素值较大,而比较暗的区域像素值较小,通过寻找“汇水盆地”和“分水岭界限”,对图像进行分割。
2,源代码

import cv2 as cv
import numpy as np


def watershed_demo():
   # print(src.shape)
    blurred = cv.pyrMeanShiftFiltering(src, 10, 100) #边缘保留滤波去噪
    # gray\binary image
    gray = cv.cvtColor(blurred, cv.COLOR_BGR2GRAY) #转化为灰度图
    ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU) #二值化
    cv.imshow("binary-image", binary)

    # morphology operation形态学操作
    kernel = cv.getStructuringElement(cv.MORPH_RECT, (3, 3)) #构造结构
    mb = cv.morphologyEx(binary, cv.MORPH_OPEN, kernel, iterations=2) #连续两次开操作(去除图像中的任何小的白噪声);闭运算(为了去除物体上的小洞)
    sure_bg = cv.dilate(mb, kernel, iterations=3)  #连续三次膨胀操作
    cv.imshow("mor-opt", sure_bg)

    # distance transform
    dist = cv.distanceTransform(mb, cv.DIST_L2, 3)#距离变化(提取出我们确信它们是硬币的区域)
    dist_output = cv.normalize(dist, 0, 1.0, cv.NORM_MINMAX)#归一化
    dist_output1 = np.uint8(dist_output)


    ret, surface = cv.threshold(dist, dist.max()*0.6, 255, cv.THRESH_BINARY)

    surface_fg = np.uint8(surface)#将float类型转化为uint
    cv.imshow("surface-bin", surface_fg)
    unknown = cv.subtract(sure_bg, surface_fg)#除种子以外的区域(剩下的区域是我们不知道的区域,无论是硬币还是背景.分水岭算法应该找到它)
    ret, markers = cv.connectedComponents(surface_fg) 
    #求连通区域(创建标记:它是一个与原始图像相同大小的数组,但使用int32数据类型,并对其内部的区域进行标记.)
    # watershed transform 分水岭变换
    markers = markers + 1 # Add one to all labels so that sure background is not 0, but 1
    markers[unknown==255] = 0 #  mark the region of unknown with zero
    markers = cv.watershed(src, markers=markers)
    src[markers==-1] = [0, 0, 255]#标记
    cv.imshow("result", src)



src = cv.imread("F:/images/coins.jpg")
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
watershed_demo()
cv.waitKey(0)

cv.destroyAllWindows()

OpenCV+python:分水岭算法_第2张图片OpenCV+python:分水岭算法_第3张图片OpenCV+python:分水岭算法_第4张图片OpenCV+python:分水岭算法_第5张图片OpenCV+python:分水岭算法_第6张图片

你可能感兴趣的:(OpenCV/基本图像处理算法)