首页 > 解决方案 > 如何通过 kmeans 聚类加速颜色量化

问题描述

我正在尝试加快“kmeans”聚类的实现速度,以尽量减少图像中的颜色数量,同时保持它的美观。在 k=32 的图像 1000x1000 上非常慢。但是与其他经过测试的方法相比,该功能提供了完美的颜色/色调匹配(这是至关重要的),所以我找不到任何等效的替代品(如果有的话?)。

我有一个想法在聚类过程之前调整图像大小(例如制作 300x300),然后对原始图像使用减少的调色板,但我的 python 知识不足以在函数中实现。能否请你帮忙?

这是我原来的慢功能(我注释掉了我的实验尝试):

def color_quantize(image, K):
    (h, w) = image.shape[:2]

    img = cv2.cvtColor(image, cv2.COLOR_BGR2LAB)
    Z = img.reshape((-1, 3))

    # *** my attempt to resize to a smaller size for clustering
    #thumbnail = cv2.resize(img, (300, 300), cv2.INTER_CUBIC)             
    #​Z = thumbnail.reshape((-1, 3))

    Z = np.float32(Z)

    criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 15, 1.0)
    ret, label, center = cv2.kmeans(Z, K, None, criteria, 10, cv2.KMEANS_RANDOM_CENTERS)
    
    center = np.uint8(center)
    res = center[label.flatten()]

    # *** here should go some backward process to apply the reduced color palette to the original image...

    quantized_img = res.reshape(img.shape)

    quantized_img = cv2.cvtColor(quantized_img, cv2.COLOR_LAB2BGR)
    return quantized_img

更新

经过大量尝试找到一种可以提供良好着色和快速速度的解决方案后,我最终得到了以下结果:

def color_quantize_fast(image, K):
img = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
im_pil = Image.fromarray(np.uint8(img))
im_pil = im_pil.quantize(K, None, 0, None)
return cv2.cvtColor(np.array(im_pil.convert("RGB")), cv2.COLOR_RGB2BGR) 

它接受格式为 cv2.imread() 返回的图像。它返回一个类似格式的量化图像。K 是颜色的数量(1 <= K <= 255)

标签: pythonopencvk-means

解决方案


推荐阅读