zoukankan      html  css  js  c++  java
  • A way to compress picture by KMeans algorithm

    conception

    https://scikit-learn.org/stable/auto_examples/cluster/plot_color_quantization.html#sphx-glr-auto-examples-cluster-plot-color-quantization-py

         图片中的每一个像素都对应一个 tuple (R G B)值,

        由于R G B  值的范围是 0-255, 导致像素的色彩的变化范围比较大, 从肉眼的角度, 可能相邻像素的值, 差别很小, 无法差别。

        但是图像色彩要求比较高的场景, 相邻像素的RGB值是有差异的, 所以对于图片存储格式的压缩算法,不能奏效, 压缩算法例如:相邻区域RGB值相同,只存储一份,并且存储相邻位置范围。

        KMeans聚类压缩, 就是基于这个思想, 将所有像素的 RGB值得范围空间, 缩小为目标聚类的数目。

        例如 正常 RGB 值空间 为  256 * 256 * 256

        如果聚类中心数目为64, 则RGB值空间则锐减为 64

    Color Quantization using K-Means

    Performs a pixel-wise Vector Quantization (VQ) of an image of the summer palace (China), reducing the number of colors required to show the image from 96,615 unique colors to 64, while preserving the overall appearance quality.

    In this example, pixels are represented in a 3D-space and K-means is used to find 64 color clusters. In the image processing literature, the codebook obtained from K-means (the cluster centers) is called the color palette. Using a single byte, up to 256 colors can be addressed, whereas an RGB encoding requires 3 bytes per pixel. The GIF file format, for example, uses such a palette.

    For comparison, a quantized image using a random codebook (colors picked up randomly) is also shown.

    • Original image (96,615 colors)
    • Quantized image (64 colors, K-Means)
    • Quantized image (64 colors, Random)

    Code

    https://github.com/fanqingsong/code_snippet/blob/master/sklearn/plot_color_quantization.ipynb

    # Authors: Robert Layton <robertlayton@gmail.com>
    #          Olivier Grisel <olivier.grisel@ensta.org>
    #          Mathieu Blondel <mathieu@mblondel.org>
    #
    # License: BSD 3 clause
    
    print(__doc__)
    import numpy as np
    import matplotlib.pyplot as plt
    from sklearn.cluster import KMeans
    from sklearn.metrics import pairwise_distances_argmin
    from sklearn.datasets import load_sample_image
    from sklearn.utils import shuffle
    from time import time
    
    n_colors = 64
    
    # Load the Summer Palace photo
    china = load_sample_image("china.jpg")
    
    
    # Convert to floats instead of the default 8 bits integer coding. Dividing by
    # 255 is important so that plt.imshow behaves works well on float data (need to
    # be in the range [0-1])
    china = np.array(china, dtype=np.float64) / 255
    
    # Load Image and transform to a 2D numpy array.
    w, h, d = original_shape = tuple(china.shape)
    assert d == 3
    image_array = np.reshape(china, (w * h, d))
    
    print("Fitting model on a small sub-sample of the data")
    t0 = time()
    image_array_sample = shuffle(image_array, random_state=0)[:1000]
    kmeans = KMeans(n_clusters=n_colors, random_state=0).fit(image_array_sample)
    print("done in %0.3fs." % (time() - t0))
    
    # Get labels for all points
    print("Predicting color indices on the full image (k-means)")
    t0 = time()
    labels = kmeans.predict(image_array)
    print("done in %0.3fs." % (time() - t0))
    
    
    codebook_random = shuffle(image_array, random_state=0)[:n_colors]
    print("Predicting color indices on the full image (random)")
    t0 = time()
    labels_random = pairwise_distances_argmin(codebook_random,
                                              image_array,
                                              axis=0)
    print("done in %0.3fs." % (time() - t0))
    
    
    def recreate_image(codebook, labels, w, h):
        """Recreate the (compressed) image from the code book & labels"""
        d = codebook.shape[1]
        image = np.zeros((w, h, d))
        label_idx = 0
        for i in range(w):
            for j in range(h):
                image[i][j] = codebook[labels[label_idx]]
                label_idx += 1
        return image
    
    # Display all results, alongside original image
    plt.figure(1)
    plt.clf()
    plt.axis('off')
    plt.title('Original image (96,615 colors)')
    plt.imshow(china)
    
    plt.figure(2)
    plt.clf()
    plt.axis('off')
    plt.title('Quantized image (64 colors, K-Means)')
    plt.imshow(recreate_image(kmeans.cluster_centers_, labels, w, h))
    
    plt.figure(3)
    plt.clf()
    plt.axis('off')
    plt.title('Quantized image (64 colors, Random)')
    plt.imshow(recreate_image(codebook_random, labels_random, w, h))
    plt.show()

    Effect

    相比原始图片, 压缩后的图片能减少100K

  • 相关阅读:
    POJ 1077 Eight(单向搜索)
    HDU 1943 Ball bearings(简单数学问题)
    POJ 2632 Crashing Robots(水模拟)
    HDU 1047 Integer Inquiry(高精度加法)
    POJ 1068 Parencodings(模拟)
    [转]修改 ibatis 分页机制(ORACLE物理分页)
    实现判断机器大小端的两种方法
    linux环境下库的制作和升级
    fork函数的理解1
    如何求一个文件的行数?
  • 原文地址:https://www.cnblogs.com/lightsong/p/14150388.html
Copyright © 2011-2022 走看看