|
| 1 | +# -*-coding:utf8-*-# |
| 2 | +__author__ = 'play4fun' |
| 3 | +""" |
| 4 | +create time:15-10-25 下午12:09 |
| 5 | +
|
| 6 | +任何一副灰度图像 可以 看成拓扑平面 |
| 7 | +灰度值 的区域可以 看成是 山峰 |
| 8 | +灰度值低的区域可以 看成是山谷。 |
| 9 | +我们向每一个山谷中灌不同颜色的水。随着水的位的升 不同山谷的水就会相遇汇合 |
| 10 | +为了防止不同山 的水 汇合 我们需要在水汇合的地方构建 堤坝。不停的灌水 不停的构建堤坝 |
| 11 | +直到所有的山峰都被水淹没。 |
| 12 | +我们构建好的堤坝就是对图像的分割。 |
| 13 | +这就是分水岭算法的背后哲理。 |
| 14 | +
|
| 15 | +每一次灌水 我们的标签就会 更新 当两个不同 色的标签相 时就构建堤 坝 直到将所有山峰淹没 最后我们得到的 界对 堤坝 的值为 -1 |
| 16 | +
|
| 17 | +""" |
| 18 | + |
| 19 | +import numpy as np |
| 20 | +import cv2 |
| 21 | +from matplotlib import pyplot as plt |
| 22 | + |
| 23 | +img = cv2.imread('../data/water_coins.jpg') |
| 24 | +gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) |
| 25 | +ret, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU) |
| 26 | +cv2.imshow('thresh', thresh) |
| 27 | + |
| 28 | +# noise removal |
| 29 | +kernel = np.ones((3, 3), np.uint8) |
| 30 | +opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=2) |
| 31 | + |
| 32 | +# sure background area |
| 33 | +sure_bg = cv2.dilate(opening, kernel, iterations=3) |
| 34 | +# Finding sure foreground area |
| 35 | +# 距离变换的基本含义是计算一个图像中非像素点到最近的零像素点的距离 |
| 36 | +# 也就是到零像素点的最短距离 |
| 37 | +# 个最常见的距离变换算法就是通过连续的腐蚀操作来实现, |
| 38 | +# 腐蚀操作的停止条件是所有前景像素都被完全腐蚀。 |
| 39 | +# 这样根据腐蚀的先后顺序,我们就得到各个前景像素点到前景中心骨架像素点的距离 |
| 40 | +# 根据各个像素点的距离值,设置为不同的灰度值。这样就完成了二值图像的距离变换 |
| 41 | +# cv2.distanceTransform(src, distanceType, maskSize) |
| 42 | +# 第二个参数 0,1,2 分别 示 CV_DIST_L1, CV_DIST_L2 , CV_DIST_C |
| 43 | +dist_transform = cv2.distanceTransform(opening, 1, 5) |
| 44 | +ret, sure_fg = cv2.threshold(dist_transform, 0.7 * dist_transform.max(), 255, 0) |
| 45 | +# Finding unknown region |
| 46 | +sure_fg = np.uint8(sure_fg) |
| 47 | +unknown = cv2.subtract(sure_bg, sure_fg) |
| 48 | +cv2.imshow('unknown', unknown) |
| 49 | +# 边界 |
| 50 | + |
| 51 | +# 腐蚀 |
| 52 | + |
| 53 | + |
| 54 | +# Marker labelling创建标签 |
| 55 | +ret, markers1 = cv2.connectedComponents(sure_fg) |
| 56 | +# Add one to all labels so that sure background is not 0, but 1 |
| 57 | +# 把将背景标 为 0 其他的对 使用从 1 开始的正整数标 |
| 58 | +markers = markers1 + 1 |
| 59 | +# Now, mark the region of unknown with zero |
| 60 | +markers[unknown == 255] = 0 |
| 61 | + |
| 62 | +# cv2.imshow('markers', markers1) |
| 63 | + |
| 64 | +# 到最后一步 实施分水岭算法了。标签图像将会 修 改 界区域的标 将变为 -1 |
| 65 | +markers3 = cv2.watershed(img, markers) |
| 66 | +img[markers3 == -1] = [255, 0, 0] |
| 67 | + |
| 68 | +cv2.imshow('watershed', img) |
| 69 | +cv2.waitKey(0) |
| 70 | +cv2.destroyAllWindows() |
0 commit comments