Python OpenCV应用K均值聚类进行颜色量化

Python OpenCV应用K均值聚类进行颜色量化

    • 1. 效果图
    • 2. 颜色量化是什么?
    • 3. MiniBatchKMeans & KMeans
    • 4. 源码
    • 参考

在这篇博客文章中,我将向您展示如何使用K-means聚类和颜色量化在图像中创建“ A Scanner Darkly”效果。

1. 效果图

左侧原始图像,右侧颜色量化图像
Python OpenCV应用K均值聚类进行颜色量化_第1张图片Python OpenCV应用K均值聚类进行颜色量化_第2张图片Python OpenCV应用K均值聚类进行颜色量化_第3张图片Python OpenCV应用K均值聚类进行颜色量化_第4张图片
可以看到 k= 12 基本可以跟原始图像一致;

随着量化聚类数量的增加,我们能够更好地模仿原始色彩空间。

在聚簇数和量化图像的质量之间存在明显的权衡。类似于时间换空间,空间换时间;
(1)随着聚簇数量的增加,执行聚簇所需的时间也随之增加。
(2)随着聚簇数量的增加,存储输出图像所需的内存量也随之增加。但是,在两种情况下,由于您使用的调色板要小得多,因此内存占用量仍将小于原始图像。

2. 颜色量化是什么?

颜色量化(Color Quantization)是减少图像中不同颜色数量的过程。通常,目的是尽可能保留图像的颜色外观,同时减少颜色数量,无论是用于内存限制还是压缩。

在我自己的工作中,我发现在构建基于内容的图像检索(CBIR)系统,即“图像搜索引擎”时,最好使用色彩量化。

任何给定的24位RGB图像都有256 x 256 x 256种可能的颜色,我们可以基于这些强度值构建标准的颜色直方图;也可以显式量化图像并减少颜色的数量,例如16或64。这会产生明显较小的空间,并且会减少噪声和差异。

我们可以使用颜色量化构造更严格的颜色直方图,也可以利用二次距离中的量化颜色直方图来计算相似度。

3. MiniBatchKMeans & KMeans

MiniBatchKMeans的速度明显快于普通K均值,尽管质心可能不那么稳定。这是因为MiniBatchKMeans在数据集的较小“批次”上进行操作,而K-Means在数据集的总体上进行操作,因此使每个质心以及质心更新循环的平均值计算要慢得多。

通常,可以从MiniBatchKMeans开始,如果(且仅当)结果不佳时,再切换到普通K-Means。

4. 源码

# USAGE
# python quant.py --image images/cactus.jpg --clusters 10

import argparse  # 命令行参数解析

import cv2
# 导入必要的类
from sklearn.cluster import MiniBatchKMeans  # K-Means实现


def show_image(title, image, width=300):
    # resize图像以使得图像具有固定的大小,以便整个屏幕都可以展示
    r = width / float(image.shape[1])
    dim = (width, int(image.shape[0] * r))
    resized = cv2.resize(image, dim, interpolation=cv2.INTER_AREA)

    # 展示缩放后的图像
    cv2.imshow(title, resized)


# 构建命令行参数及解析
# --image 原始图像
# --cluster 输出图像将要具有的颜色数
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", required=True, help="Path to the image")
ap.add_argument("-c", "--clusters", required=True, type=int,
                help="# of clusters")
args = vars(ap.parse_args())

# 加载图像获取宽度和高度
image = cv2.imread(args["image"])
(h, w) = image.shape[:2]

# 转换图像空间 BGR--> LAB颜色空间
# 为什么转换呢? 因为在L * a * b 颜色空间中,颜色之间的欧几里德距离具有实际的感知意义-RGB颜色空间不是这种情况
# 鉴于k均值聚类也假设了一个欧式空间,因此最好使用L * a * b *而不是RGB;
image = cv2.cvtColor(image, cv2.COLOR_BGR2LAB)

# 为了聚类像素强度,reshape图像为(M*N,3)特征向量
image = image.reshape((image.shape[0] * image.shape[1], 3))

# 根据预先设置的期望颜色数,应用MiniBatchKMeans算法聚类
# 真正执行聚类操作
# 基于预测结果来生成量化图像
clt = MiniBatchKMeans(n_clusters=args["clusters"])
labels = clt.fit_predict(image)
quant = clt.cluster_centers_.astype("uint8")[labels]

# 将特征向量重塑为图像
quant = quant.reshape((h, w, 3))
image = image.reshape((h, w, 3))

# 转换颜色空间 L*a*b* ---> RGB
quant = cv2.cvtColor(quant, cv2.COLOR_LAB2BGR)
image = cv2.cvtColor(image, cv2.COLOR_LAB2BGR)

# 展示图像
show_image("origin", image, 300)
show_image("quant", quant, 300)
cv2.waitKey(0)

参考

  • https://www.pyimagesearch.com/2014/07/07/color-quantization-opencv-using-k-means-clustering/

你可能感兴趣的:(Python,OpenCV,图像处理,Python,python,计算机视觉,图像处理,颜色量化,K均值聚类)