其他图像分割方法,如阈值,边缘检测等都不会考虑像素在空间关系上的相似性和封闭性这一概念,彼此像素间互相独立,没有统一性。分水岭算法较其他分割方法更具有思想性,更符合人眼对图像的印象。
kernel = cv.getStructuringElement(cv.MORPH_RECT, (3, 3)) opening = cv.morphologyEx(thresh, cv.MORPH_OPEN, kernel, iterations=2) cv.imshow('opening ', opening) sure_bg = cv.dilate(opening, kernel, iterations=3) cv.imshow('mor-opt', sure_bg)
剩下的区域我们不知道该如何区分了,这就是分水岭算法要做的。这些区域通常是前景与背景的交界处,我们称之为边界。从sure-bg里面减去surface-fg得到。
#距离变换 dist = cv.distanceTransform(opening, cv.DIST_L2, 3) dist_output = cv.normalize(dist, 0, 1.0, cv.NORM_MINMAX) cv.imshow('distance-t', dist_output * 50) ret, surface = cv.threshold(dist, dist.max()*0.6, 255, cv.THRESH_BINARY) cv.imshow('surface', surface) #Finding unknown region surface_fg = np.uint8(surface) cv.imshow('surface_bin', surface_fg) unknown = cv.subtract(sure_bg,surface_fg)
# Marker labelling ret, markers = cv.connectedComponents(surface_fg) # Add one to all labels so that sure background is not 0, but 1 markers = markers + 1 # now,make thre region of unknown with zero markers[unknown==255] = 0
markers = cv.watershed(img, markers) img[markers==-1] = [255, 0, 0]
import cv2 as cv import numpy as np from matplotlib import pyplot as plt def watershed_demo(img): print(img.shape) #去噪声 blurred = cv.pyrMeanShiftFiltering(img, 10, 100) # gray\binary image gray = cv.cvtColor(blurred, cv.COLOR_BGR2GRAY) ret, thresh = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU) cv.imshow('thresh', thresh) # 有很多的黑点,所以我们去黑点噪声 kernel = cv.getStructuringElement(cv.MORPH_RECT, (3, 3)) opening = cv.morphologyEx(thresh, cv.MORPH_OPEN, kernel, iterations=2) cv.imshow('opening ', opening) sure_bg = cv.dilate(opening, kernel, iterations=3) cv.imshow('mor-opt', sure_bg) #距离变换 dist = cv.distanceTransform(opening, cv.DIST_L2, 3) dist_output = cv.normalize(dist, 0, 1.0, cv.NORM_MINMAX) cv.imshow('distance-t', dist_output * 50) ret, surface = cv.threshold(dist, dist.max()*0.6, 255, cv.THRESH_BINARY) cv.imshow('surface', surface) #Finding unknown region surface_fg = np.uint8(surface) cv.imshow('surface_bin', surface_fg) unknown = cv.subtract(sure_bg,surface_fg) # Marker labelling ret, markers = cv.connectedComponents(surface_fg) # Add one to all labels so that sure background is not 0, but 1 markers = markers + 1 # now,make thre region of unknown with zero markers[unknown==255] = 0 markers = cv.watershed(img, markers) img[markers==-1] = [255, 0, 0] cv.imshow('result', img) img = cv.imread('img/target.jpg') cv.namedWindow('img',cv.WINDOW_AUTOSIZE) cv.imshow('img',img) watershed_demo(img) cv.waitKey(0) cv.destroyAllWindows()