Python+OpenCV实战之利用 K-Means 聚类进行色彩量化

目录
  • 前言
  • 利用 K-Means 聚类进行色彩量化
    • 完整代码
  • 显示色彩量化后的色彩分布

前言

K-Means 聚类算法的目标是将 n 个样本划分(聚类)为 K 个簇,在博文《OpenCV与机器学习的碰撞》中,我们已经学习利用 OpenCV 提供了 cv2.kmeans() 函数实现 K-Means 聚类算法,该算法通过找到簇的中心并将输入样本分组到簇周围,同时通过简单的示例了解了 K-Means 算法的用法。在本文中,我们将学习如何利用 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 result
color_3 = color_quantization(img, 3)

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

完整代码

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

import numpy as np
import cv2
from matplotlib import pyplot as plt

def 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 result

fig = 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 collections
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)
    # 统计分配给每个聚类中心的像素数
    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))

程序的输出如下所示:

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

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

到此这篇关于Python+OpenCV实战之利用 K-Means 聚类进行色彩量化的文章就介绍到这了,更多相关OpenCV  K-Means 内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 利用python实现聚类分析K-means算法的详细过程

    K-means算法介绍 K-means算法是很典型的基于距离的聚类算法,采用距离作为相似性的评价指标,即认为两个对象的距离越近,其相似度就越大.该算法认为簇是由距离靠近的对象组成的,因此把得到紧凑且独立的簇作为最终目标. 算法过程如下: 1)从N个文档随机选取K个文档作为中心点: 2)对剩余的每个文档测量其到每个中心点的距离,并把它归到最近的质心的类: 3)重新计算已经得到的各个类的中心点: 4)迭代2-3步直至新的质心与原质心相等或小于指定阈值,算法结束. 算法优缺点: 优点: 原理简单 速度

  • python中K-means算法基础知识点

    能够学习和掌握编程,最好的学习方式,就是去掌握基本的使用技巧,再多的概念意义,总归都是为了使用服务的,K-means算法又叫K-均值算法,是非监督学习中的聚类算法.主要有三个元素,其中N是元素个数,x表示元素,c(j)表示第j簇的质心,下面就使用方式给大家简单介绍实例使用. K-Means算法进行聚类分析 km = KMeans(n_clusters = 3) km.fit(X) centers = km.cluster_centers_ print(centers) 三个簇的中心点坐标为: [

  • Python实现K-means聚类算法并可视化生成动图步骤详解

    K-means算法介绍 简单来说,K-means算法是一种无监督算法,不需要事先对数据集打上标签,即ground-truth,也可以对数据集进行分类,并且可以指定类别数目 牧师-村民模型 K-means 有一个著名的解释:牧师-村民模型: 有四个牧师去郊区布道,一开始牧师们随意选了几个布道点,并且把这几个布道点的情况公告给了郊区所有的村民,于是每个村民到离自己家最近的布道点去听课. 听课之后,大家觉得距离太远了,于是每个牧师统计了一下自己的课上所有的村民的地址,搬到了所有地址的中心地带,并且在海

  • Python使用OpenCV和K-Means聚类对毕业照进行图像分割

    图像分割是将图像分割成多个不同区域(或片段)的过程.目标是将图像的表示变成更容易和更有意义的图像. 在这篇博客中,我们将看到一种图像分割方法,即K-Means Clustering. K-Means 聚类是一种无监督机器学习算法,旨在将N 个观测值划分为K 个聚类,其中每个观测值都属于具有最近均值的聚类.集群是指由于某些相似性而聚合在一起的数据点的集合.对于图像分割,这里的簇是不同的图像颜色. 我们使用的环境是pip install opencv-python numpy matplotlib

  • Python K-means实现简单图像聚类的示例代码

    这里直接给出第一个版本的直接实现: import os import numpy as np from sklearn.cluster import KMeans import cv2 from imutils import build_montages import matplotlib.image as imgplt image_path = [] all_images = [] images = os.listdir('./images') for image_name in images

  • Python+OpenCV实战之利用 K-Means 聚类进行色彩量化

    目录 前言 利用 K-Means 聚类进行色彩量化 完整代码 显示色彩量化后的色彩分布 前言 K-Means 聚类算法的目标是将 n 个样本划分(聚类)为 K 个簇,在博文<OpenCV与机器学习的碰撞>中,我们已经学习利用 OpenCV 提供了 cv2.kmeans() 函数实现 K-Means 聚类算法,该算法通过找到簇的中心并将输入样本分组到簇周围,同时通过简单的示例了解了 K-Means 算法的用法.在本文中,我们将学习如何利用 K-Means 聚类进行色彩量化,以减少图像中颜色数量.

  • Python OpenCV实战之与机器学习的碰撞

    目录 0. 前言 1. 机器学习简介 1.1 监督学习 1.2 无监督学习 1.3 半监督学习 2. K均值 (K-Means) 聚类 2.1 K-Means 聚类示例 3. K最近邻 3.1 K最近邻示例 4. 支持向量机 4.1 支持向量机示例 小结 0. 前言 机器学习是人工智能的子集,它为计算机以及其它具有计算能力的系统提供自动预测或决策的能力,诸如虚拟助理.车牌识别系统.智能推荐系统等机器学习应用程序给我们的日常生活带来了便捷的体验.机器学习的蓬勃发展,得益于以下三个关键因素:1) 海

  • Python+Opencv实战之人脸追踪详解

    目录 前言 人脸追踪技术简介 使用基于 dlib DCF 的跟踪器进行人脸跟踪 使用基于 dlib DCF 的跟踪器进行对象跟踪 小结 前言 人脸处理是人工智能中的一个热门话题,人脸处理可以使用计算机视觉算法从人脸中自动提取大量信息,例如身份.意图和情感:而目标跟踪试图估计目标在整个视频序列中的轨迹,其中只有目标的初始位置是已知的,将这两者进行结合将产生许多有趣的应用.由于外观变化.遮挡.快速运动.运动模糊和比例变化等多种因素,人脸追踪非常具有挑战性. 人脸追踪技术简介 基于判别相关滤波器 (d

  • Python Opencv实战之印章提取的实现

    目录 前言 源码展示 效果展示 前言 这期分享的是使用opencv提取印章,很多时候我们需要电子版的章,所以今天就带大家使用代码提取出来! Photoshop虽然强大,但是奈何小编不会使啊,昨天就有一个小伙伴问我能不能帮忙,这不? PS虽然我不会,但是我会写代码呀!这可难不倒我!安排安排~ (特别提醒:所有爱好设计和喜欢做图的小伙伴们,切记千万不要帮着老板或者朋友PS伪造公章,刑法第280条特别指出,伪造证件印章,是可以追究刑事责任的,违法的事情不要做哦.) 源码展示 import cv2 im

  • Python+OpenCV实战之拖拽虚拟方块的实现

    目录 一.项目效果 二.核心流程 三.代码流程 1. 读取摄像头视频,画矩形 2. 导入mediapipe处理手指坐标 3. 位置计算 完整代码 一.项目效果 学校宿舍今天搬家,累麻了,突然发现展示处理的也很粗糙,就这样吧嘿嘿~~~ 二.核心流程 1.openCV读取视频流.在每一帧图片上画一个矩形. 2.使用mediapipe获取手指关键点坐标. 3.根据手指坐标位置和矩形的坐标位置,判断手指点是否在矩形上,如果在则矩形跟随手指移动. 三.代码流程 环境准备: python: 3.8.8 op

  • Python+OpenCV实战之实现文档扫描

    目录 1.效果展示 2.项目准备 3.代码的讲解与展示 4.项目资源 5.项目总结与评价 1.效果展示 网络摄像头扫描: 图片扫描: 最终扫描保存的图片: (视频) (图片) 2.项目准备 今天的项目文件只需要两个.py文件,其中一个.py文件是已经写好的函数,你将直接使用它,我不会在此多做讲解,因为我们将会在主要的.py文件import 导入它,如果想了解其中函数是如何写的,请自行学习. utlis.py,需要添加的.py文件 import cv2 import numpy as np # T

  • Python Opencv实战之文字检测OCR

    目录 1.相关函数的讲解 2.代码展示 Detecting Words Detecting ONLY Digits 3.问题叙述 4.image_to_data()配置讲解 5.项目拓展 6.总结与评价 1.相关函数的讲解 image_to_data()的输出结果是表格形式,输出变量的类型依旧是字符串. 你会得到一个这样的列表['level', 'page_num', 'block_num', 'par_num', 'line_num', 'word_num', 'left', 'top', '

  • Python-OpenCV实战:利用 KNN 算法识别手写数字

    目录 前言 手写数字数据集 MNIST 介绍 基准模型--利用 KNN 算法识别手写数字 改进模型1--参数 K 对识别手写数字精确度的影响 改进模型2--训练数据量对识别手写数字精确度的影响 改进模型3--预处理对识别手写数字精确度的影响 改进模型4--使用高级描述符作为图像特征提高 KNN 算法准确率 完整代码 相关链接 前言 K-最近邻 (k-nearest neighbours, KNN) 是监督学习中最简单的算法之一,KNN 可用于分类和回归问题,在博文<Python OpenCV实战

  • python机器学习实战之K均值聚类

    本文实例为大家分享了python K均值聚类的具体代码,供大家参考,具体内容如下 #-*- coding:utf-8 -*- #!/usr/bin/python ''''' k Means K均值聚类 ''' # 测试 # K均值聚类 import kMeans as KM KM.kMeansTest() # 二分K均值聚类 import kMeans as KM KM.biKMeansTest() # 地理位置 二分K均值聚类 import kMeans as KM KM.clusterClu

  • python中opencv K均值聚类的实现示例

    目录 K均值聚类 K均值聚类的基本步骤 K均值聚类模块 简单例子 K均值聚类 预测的是一个离散值时,做的工作就是“分类”. 预测的是一个连续值时,做的工作就是“回归”. 机器学习模型还可以将训练集中的数据划分为若干个组,每个组被称为一个“簇(cluster)”.这种学习方式被称为“聚类(clusting)”,它的重要特点是在学习过程中不需要用标签对训练样本进行标注.也就是说,学习过程能够根据现有训练集自动完成分类(聚类). 根据训练数据是否有标签,可以将学习划分为监督学习和无监督学习. K近邻.

随机推荐