这里的主要问题在于你的closest
method:
def closest(colors, color):
colors = np.array(colors)
color = np.array(color)
distances = np.sqrt(np.sum((colors - color) ** 2, axis=1))
Both colors
and color
成为 NumPy 类型的数组uint8
。现在,当减去uint8
值,你不会得到负值,但会发生整数下溢,导致值接近255
。因此,随后计算出distances
都是错误的,最终导致颜色选择错误。
因此,最快的解决方法是将这两个变量转换为int32
:
def closest(colors, color):
colors = np.array(colors).astype(np.int32)
color = np.array(color).astype(np.int32)
distances = np.sqrt(np.sum((colors - color) ** 2, axis=1))
此外,利用 NumPy 的矢量化功能可能很有用。为您考虑以下方法closest
method:
def closest(colors, image):
colors = np.array(colors).astype(np.int32)
image = image.astype(np.int32)
distances = np.argmin(np.array([np.sqrt(np.sum((color - image) ** 2, axis=2)) for color in colors]), axis=0)
return colors[distances].astype(np.uint8)
因此,不要迭代所有像素
for y in np.arange(image_nd.shape[0]):
for x in np.arange(image_nd.shape[1]):
image_nd[y, x] = closest(four_major_colors, image_nd[y, x])
你可以简单地传递整个图像:
image_nd = closest(four_major_colors, image_nd)
使用给定的图像,我的机器速度提高了 100 倍。当然,查找 RGB 直方图值也可以进行优化。 (不幸的是,我对 Python 字典的体验还不是很好......)
不管怎样——希望有帮助!