图像边界查找和填充

时间:2015-04-11 01:49:17

标签: numpy scipy scikit-image

我有一个单波段二进制图像(仅包含0和1像素值),如下图所示。

我必须将外部白色边界内的所有黑色像素转换为白色。 外部白色边界外的黑色像素应保持黑色。

你会怎么做?

enter image description here

1 个答案:

答案 0 :(得分:5)

以下代码产生以下结果:

enter image description here

我已经对内联代码进行了评论,以解释我的所作所为。

from skimage import io, img_as_bool, measure, morphology
from scipy import ndimage

import numpy as np
import matplotlib.pyplot as plt

# Read the image, convert the values to True or False;
# discard all but the red channel (since it's a black and
# white image, they're all the same)
image = img_as_bool(io.imread('borders.png'))[..., 0]

# Compute connected regions in the image; we're going to use this
# to find centroids for our watershed segmentation
labels = measure.label(image)
regions = measure.regionprops(labels)

# Marker locations for the watershed segmentation; we choose these to
# be the centroids of the different connected regions in the image
markers = np.array([r.centroid for r in regions]).astype(np.uint16)
marker_image = np.zeros_like(image, dtype=np.int64)
marker_image[markers[:, 0], markers[:, 1]]  = np.arange(len(markers)) + 1

# Compute the distance map, which provides a "landscape" for our watershed
# segmentation
distance_map = ndimage.distance_transform_edt(1 - image)

# Compute the watershed segmentation; it will over-segment the image
filled = morphology.watershed(1 - distance_map, markers=marker_image)

# In the over-segmented image, combine touching regions
filled_connected = measure.label(filled != 1, background=0) + 1

# In this optional step, filter out all regions that are < 25% the size
# of the mean region area found
filled_regions = measure.regionprops(filled_connected)
mean_area = np.mean([r.area for r in filled_regions])
filled_filtered = filled_connected.copy()
for r in filled_regions:
    if r.area < 0.25 * mean_area:
        coords = np.array(r.coords).astype(int)
        filled_filtered[coords[:, 0], coords[:, 1]] = 0

# And display!
f, (ax0, ax1, ax2) = plt.subplots(1, 3)
ax0.imshow(image, cmap='gray')
ax1.imshow(filled_filtered, cmap='spectral')
ax2.imshow(distance_map, cmap='gray')
plt.savefig('/tmp/labeled_filled_regions.png', bbox_inches='tight')
相关问题