也许对二进制图像进行操作更容易。在下面的代码中,我通过计算滑动窗口上的方差并对其进行阈值化来获得这样的图像。
from skimage import io, exposure, color, util
import matplotlib.pyplot as plt
image = color.rgb2gray(io.imread('tools.jpg'))
exposure.equalize_adapthist(image)
Z = util.view_as_windows(image, (5, 5))
Z = Z.reshape(Z.shape[0], Z.shape[1], -1)
variance_map = Z.var(axis=2)
plt.imshow(variance_map > 0.005, cmap='gray')
plt.savefig('tools_thresh.png')
plt.show()
更新:
该代码的扩展版本标识了 8 个工具。
from skimage import io, exposure, color, util, measure, morphology
from scipy import ndimage as ndi
import numpy as np
import matplotlib.pyplot as plt
image = color.rgb2gray(io.imread('tools.jpg'))
exposure.equalize_adapthist(image)
Z = util.view_as_windows(image, (5, 5))
Z = Z.reshape(Z.shape[0], Z.shape[1], -1)
variance_map = Z.var(axis=2)
tools_bw = variance_map > 0.005
tools_bw = morphology.binary_closing(tools_bw, np.ones((5, 5)))
tools_bw = ndi.binary_fill_holes(tools_bw)
labels = measure.label(tools_bw)
regions = measure.regionprops(labels)
regions = [r for r in regions if r.perimeter > 500 and r.major_axis_length > 200]
print(len(regions))
out = np.zeros_like(tools_bw, dtype=int)
for i, r in enumerate(regions):
out[labels == r.label] = i + 1
plt.imshow(out, cmap='spectral')
plt.savefig('tools_identified.png', bbox_inches='tight')
plt.show()