# 分水岭算法分割图像 # 1、图像预处理:对原始图像进行预处理,例如将彩色图像转换为灰度图像,平滑图像以去除噪声,增强图像对比度等。 # 2、计算图像的梯度:通过对图像应用梯度算子(如Sobel算子)来计算图像的梯度,梯度的变化反映了图像中的边缘信息。 # 3、确定种子点:根据预处理后的图像或者用户定义的标记信息,确定一些种子点。这些种子点可以代表分割的目标物体或者背景。 # 4、计算距离变换:使用距离变换算法,从种子点开始,计算每个像素点到最近种子点的距离。这样可以得到一个距离图像,表示每个像素点离最近种子点的距离。 # 5、计算梯度和距离变换的合并图像:将梯度图像和距离变换图像进行合并,得到一个新的图像。在合并图像中,水流将被认为是从梯度较高的区域向梯度较低的区域流去。 # 6、计算分水岭:根据合并图像,应用分水岭变换算法来计算分水岭,即将图像分割成不同的分水岭区域。 # 7、降噪和后处理:对分割结果进行降噪和后处理,例如去除小的分割区域、填充空洞等,以获得最终的分割结果。 import cv2 as cv import numpy as np img = cv.imread('test1.png', cv.IMREAD_GRAYSCALE) img = cv.blur(img, (5, 5)) img = cv.convertScaleAbs(img, alpha=1.0, beta=2.0) cv.imshow('origin', img) grad_x = cv.Sobel(img, cv.CV_32F, 1, 0, ksize=3) grad_y = cv.Sobel(img, cv.CV_32F, 0, 1, ksize=3) grad = cv.magnitude(grad_x, grad_y) ret, markers = cv.threshold(grad, 50, 255, cv.THRESH_BINARY) markers = np.uint8(markers) dist_transform = cv.distanceTransform(255 - markers, cv.DIST_L2, 5) combined = cv.subtract(dist_transform, grad) image_rgb = cv.cvtColor(cv.imread('test1.png'), cv.COLOR_BGR2RGB) markers = np.int32(markers) markers[grad == 0] = 0 markers += 1 cv.watershed(image_rgb, markers) markers = np.where(markers == -1, 255, markers) markers = np.uint8(markers) output = np.zeros_like(image_rgb) output[markers == 255] = [0, 0, 255] output[markers == 1] = [18, 0, 230] output[markers == 0] = [255, 255, 255] cv.imshow('Segmentation Result', output) cv.waitKey(0) cv.destroyAllWindows()