文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Python+OpenCV中如何利用K-Means 聚类进行色彩量化

2023-06-21 22:48

关注

小编给大家分享一下Python+OpenCV中如何利用K-Means 聚类进行色彩量化,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

利用 K-Means 聚类进行色彩量化

色彩量化问题可以定义为减少图像中颜色数量的过程。色彩量化对于某些设备显示图像非常关键,这些设备可能由于内存限制等原因只能显示有限颜色,因此,在这些设备上显示色彩通常需要在准确性和减少颜色数量之间进行权衡,在利用 K-Means 聚类进行色彩量化时,权衡两者是通过正确设置 K 参数来进行的。

利用 K-Means 聚类算法来执行色彩量化,簇中心数据由 3 个特征组成,它们对应于图像每个像素的 B、G 和 R 值。因此,关键是将图像转换为数据:

data = np.float32(image).reshape((-1, 3))

为了观察如何权衡准确性和颜色数,我们使用不同 K 值 (3 、 5 、 10 、 20 和 40) 执行聚类过程,以查看生成的图像如何变化,如果我们想要只有 3 种颜色 (K = 3) 的结果图像,需要执行以下操作:

加载 BGR 图像:

img = cv2.imread('example.jpg')

使用 color_quantization() 函数执行色彩量化:

def color_quantization(image, k):    # 将图像转换为数据    data = np.float32(image).reshape((-1, 3))    # 算法终止条件    criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 20, 1.0)    # K-Means 聚类    ret, label, center = cv2.kmeans(data, k, None, criteria, 10, cv2.KMEANS_RANDOM_CENTERS)    # 簇中心    center = np.uint8(center)    # 将具有 k 颜色中心的图像转换为 uint8    result = center[label.flatten()]    result = result.reshape(img.shape)    return resultcolor_3 = color_quantization(img, 3)

color_quantization() 函数中,关键点是利用 cv2.kmeans() 方法。最后,可以用 k 种颜色来构建图像,用它们对应的中心值替换每个像素值,程序的运行结果如下所示:

Python+OpenCV中如何利用K-Means 聚类进行色彩量化

Python+OpenCV中如何利用K-Means 聚类进行色彩量化

完整代码

利用 K-Means 聚类进行色彩量化的完整代码如下所示:

import numpy as npimport cv2from matplotlib import pyplot as pltdef show_img_with_matplotlib(color_img, title, pos):    img_RGB = color_img[:, :, ::-1]    ax = plt.subplot(2, 4, pos)    plt.imshow(img_RGB)    plt.title(title, fontsize=8)    plt.axis('off')def color_quantization(image, k):    # 将图像转换为数据    data = np.float32(image).reshape((-1, 3))    # 算法终止条件    criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 20, 1.0)    # K-Means 聚类    ret, label, center = cv2.kmeans(data, k, None, criteria, 10, cv2.KMEANS_RANDOM_CENTERS)    # 簇中心    center = np.uint8(center)    # 将具有 k 颜色中心的图像转换为 uint8    result = center[label.flatten()]    result = result.reshape(img.shape)    return resultfig = plt.figure(figsize=(16, 8))plt.suptitle("Color quantization using K-means clustering algorithm", fontsize=14, fontweight='bold')# 图片加载img = cv2.imread('example.png')show_img_with_matplotlib(img, "original image", 1)# 使用不同 K 值进行色彩量化for i in range(7):    color = color_quantization(img, (i+1) * 10)    show_img_with_matplotlib(color, "color quantization (k = {})".format((i+1) * 10), i+2)plt.show()

显示色彩量化后的色彩分布

可以扩展以上程序使其显示色彩量化后的色彩分布,该色彩分布显示了分配给每个聚类中心的像素数。只需扩展 color_quantization() 函数已被修改为包含所需功能:

import collectionsdef color_quantization(image, k):    # 将图像转换为数据    data = np.float32(image).reshape((-1, 3))    # 算法终止条件    criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 20, 1.0)    # K-Means 聚类    ret, label, center = cv2.kmeans(data, k, None, criteria, 10, cv2.KMEANS_RANDOM_CENTERS)    # 簇中心    center = np.uint8(center)    # 将具有 k 颜色中心的图像转换为 uint8    result = center[label.flatten()]    result = result.reshape(img.shape)    # 统计分配给每个聚类中心的像素数    counter = collections.Counter(label.flatten())    print(counter)    # 计算输入图像的总像素数    total = img.shape[0] * img.shape[1]    # 为色彩分布图像指定宽度和高度:    desired_width = img.shape[1]        desired_height = 70    desired_height_colors = 50    # 初始化色彩分布图像    color_distribution = np.ones((desired_height, desired_width, 3), dtype='uint8') * 255    start = 0    for key, value in counter.items():        # 归一化        value_normalized = value / total * desired_width        end = start + value_normalized        # 绘制与当前颜色对应的矩形        cv2.rectangle(color_distribution, (int(start), 0), (int(end), desired_height_colors), center[key].tolist(), -1)        start = end    return np.vstack((color_distribution, result))

上述代码中,使用 collections.Counter() 来统计分配给每个聚类中心的像素数:

counter = collections.Counter(label.flatten())

例如,如果 K = 10,则可以得到如下结果:

Counter({7: 37199, 3: 36302, 0: 29299, 5: 23987, 6: 23895, 1: 20077, 9: 19814, 8: 18427, 4: 16221, 2: 14779})

构建色彩分布图像后,将其与色彩量化后的图像连接在一起:

np.vstack((color_distribution, result))

程序的输出如下所示:

Python+OpenCV中如何利用K-Means 聚类进行色彩量化

从上图可以看出,使用 K-Means 聚类算法应用色彩量化后改变参数 k (10、20、30、40、50、60 和 70) 的结果,k 值越大产生的图像越逼真。

Note:除了 color_quantization() 函数外,由于其他代码并未修改,因此不再另外给出。 

以上是“Python+OpenCV中如何利用K-Means 聚类进行色彩量化”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注编程网行业资讯频道!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯