python - 使用 K-Nearest 聚类颜色的有效方法

标签 python opencv numpy machine-learning

我正在尝试将图像上的颜色聚类到预定义的类(黑色、白色、蓝色、绿色、红色)。我正在使用以下代码:

import numpy as np
import cv2

src = cv2.imread('objects.png')

colors = np.array([[0x00, 0x00, 0x00],
                   [0xff, 0xff, 0xff],
                   [0xff, 0x00, 0x00],
                   [0x00, 0xff, 0x00],
                   [0x00, 0x00, 0xff]], dtype=np.float32)
classes = np.array([[0], [1], [2], [3], [4]], np.float32)
dst = np.zeros(src.shape, np.float32)

knn = cv2.KNearest()
knn.train(colors, classes)

# This loop is very inefficient!
for i in range(0, src.shape[0]):
    for j in range(0, src.shape[1]):
        sample = np.reshape(src[i,j], (-1,3)).astype(np.float32)
        retval, result, neighbors, dist = knn.find_nearest(sample, 1)
        dst[i,j] = colors[result[0,0]]

cv2.imshow('src', src)
cv2.imshow('dst', dst)
cv2.waitKey()

代码运行良好,结果如下所示。左边的图像是输入,右边的图像是输出。

src dst

但是上面的循环效率非常低并且使得转换很慢。替代上述循环的最有效的 Numpy 操作是什么?

最佳答案

如果您想要一个简单的平方差度量(“这是欧几里得最接近的数字),这将起作用。

计算差异

diff = ((src[:,:,:,None] - colors.T)**2).sum(axis=2)

(假设src的形状为y,x,3)

选择最接近的颜色索引:

index = diff.argmin(axis=2)

新图像:

out = colors[index]

如果您的颜色确实具有 0 或 0xff 的分量值,您可以使用类似的内容

out = np.where(src>0x88, 0xff, 0)

关于python - 使用 K-Nearest 聚类颜色的有效方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24685436/

相关文章:

python - 在 MacOS Sierra 上安装 Pillow

python-3.x - 计算特定暗区的平均宽度

python - 如何用白色填充闭合轮廓区域

python - 尝试安装 Numpy 时出错

python - 如何以编程方式停止 multiprocessing.Pool 映射函数

python - ECOS 求解器在 CVXPY 1.0 版本中停止工作

python - python 私有(private)变量是否可以在不使用 object._className__attributeName 的情况下更改?

python OCR : ignore signatures in documents

numpy - 在 numpy 中优雅地生成结果数组

python - 合并数组和绘图