cover

26. Image Compression Using K-Means#

26.1. Introduction#

This challenge will target a picture of Jinli, a famous scenic spot in Chengdu. By using the Mini Batch K-Means method, similar pixels will be aggregated and replaced with the same pixel to achieve the effect of image compression.

26.2. Key Points#

  • Image compression

  • Mini Batch K-Means clustering

First, we download and import the sample picture named challenge-7-chengdu.png.

wget -nc "https://cdn.aibydoing.com/aibydoing/files/challenge-7-chengdu.png"
--2023-11-13 17:16:21--  https://cdn.aibydoing.com/aibydoing/files/challenge-7-chengdu.png
正在解析主机 cdn.aibydoing.com (cdn.aibydoing.com)... 198.18.7.59
正在连接 cdn.aibydoing.com (cdn.aibydoing.com)|198.18.7.59|:443... 已连接。
已发出 HTTP 请求,正在等待回应... 200 OK
长度:1057505 (1.0M) [image/png]
正在保存至: “challenge-7-chengdu.png”

challenge-7-chengdu 100%[===================>]   1.01M  1.54MB/s  用时 0.7s      

2023-11-13 17:16:23 (1.54 MB/s) - 已保存 “challenge-7-chengdu.png” [1057505/1057505])

Visualize the sample picture using Matplotlib.

import matplotlib.pyplot as plt 
import matplotlib.image as mpimg 
%matplotlib inline

chengdu = mpimg.imread('challenge-7-chengdu.png') # 将图片加载为 ndarray 数组
plt.imshow(chengdu) # 将数组还原成图像
<matplotlib.image.AxesImage at 0x11e371ea0>
../_images/adf5448f80130079d091f2649f426a56c57fd0a0bc0e56f25f7c6f3876ea7ae7.png
chengdu.shape
(516, 819, 3)

After reading the picture using the mpimg.imread function, what is actually returned is an array of the numpy.array type, which represents a matrix of pixel points and contains three elements: length, width, and height. For example, this picture of Jinli in Chengdu contains a total of 516 rows and 819 columns, that is, 516 * 819 = 422,604 pixel points. The height of each pixel point corresponds to the three primary colors RGB (red, green, blue) in computer color, which are composed of a total of 3 elements.

26.3. Data Preprocessing#

For the convenience of subsequent data processing, it is necessary to reduce the dimension of the data.

{exercise-start}
:label: chapter03_02_1

Challenge: Convert the data with shape \((516, 819, 3)\) to the data with shape \((422604, 3)\).

Hint: Use np.reshape to transform the data format.

{exercise-end}
"""数据格式变换
"""
## 代码开始 ### (≈ 1 行代码)
data = None
## 代码结束 ###
{solution-start} chapter03_02_1
:class: dropdown
"""Data format transformation
"""
### Start of code ###(≈ 1 line of code)
data = chengdu.reshape(516 * 819, 3)
### End of code ###
{solution-end}

Run tests

data.shape, data[10]

Expected output

((422604, 3), array([0.12941177, 0.13333334, 0.14901961], dtype=float32))

26.4. Calculation of the Number of Pixel Point Types#

Although there are 422604 pixel points, there are still many identical pixel points among them. Here we define that points with the same RGB values belong to one type, and points with any different values belong to different types.

Exercise 26.1

Challenge: Calculate the number of types among 422604 pixel points.

Hint: You can convert the data into a list type, then convert each element into a tuple type, and finally use the set() and len() functions for calculation. You can also complete it according to your own ideas.

"""计算像素点种类个数
"""
def get_variety(data):
    """
    参数:
    预处理后像素点集合

    返回:
    num_variety -- 像素点种类个数
    """

    ### 代码开始 ### (≈ 3 行代码)
    num_variety=None
    ### 代码结束 ###
    
    return num_variety

Run the test

get_variety(data), data[20]

Expected output

(100109, array([0.24705882, 0.23529412, 0.2627451 ], dtype=float32))

26.5. Mini Batch K-Means Clustering#

The number of pixel types is one of the main factors determining the image size. Here, the Mini Batch K-Means method is used to cluster the pixels of the image, replacing similar pixels with the same pixel value, thereby reducing the number of pixel types to achieve the effect of compressing the image.

{exercise-start}
:label: chapter03_02_3

Challenge: Use the Mini Batch K-Means clustering method to cluster the pixels and replace the pixels belonging to each category with the pixel at the center of each cluster.

Requirement: Set the number of clusters to 10.

Hint: Use the fit() and predict() functions in MiniBatchKMeans for clustering and the cluster_centers_() function for replacement. For this challenge, mostly use the default parameters. Read the official documentation

{exercise-end}
from sklearn.cluster import MiniBatchKMeans

## 代码开始 ### (≈ 4 行代码)
predict=None
## 代码结束 ###

new_colors = model.cluster_centers_[predict]
{solution-start} chapter03_02_3
:class: dropdown
from sklearn.cluster import MiniBatchKMeans

### Start of code ### (≈ 4 lines of code)
model = MiniBatchKMeans(10)
model.fit(data)
predict = model.predict(data)
### End of code ###

new_colors = model.cluster_centers_[predict]
{solution-end}

Run the test

# 调用前面实现计算像素点种类的函数,计算像素点更新后种类的个数
get_variety(new_colors)

Expected output

10

26.6. Comparison of the Image before and after Compression#

{exercise-start}
:label: chapter03_02_4

Challenge: Transform the pixel points that have been clustered and replaced with the category center point values back to the format before data processing, and draw pictures for comparison and display.

Hint: Use the reshape() function for format transformation and the imshow() function for drawing.

{exercise-end}
fig, ax = plt.subplots(1, 2, figsize=(16, 6))

## 代码开始 ### (≈ 3 行代码)

## 代码结束 ###
{solution-start} chapter03_02_4
:class: dropdown
fig, ax = plt.subplots(1, 2, figsize=(16, 6))

### Start of code ### (≈ 3 lines of code)
new_chengdu = new_colors.reshape(chengdu.shape)
ax[0].imshow(chengdu)
ax[1].imshow(new_chengdu)
### End of code ###
{solution-end}

Expected Output

image

By comparing the pictures, it is very easy to find that the picture quality has been compressed. In fact, because clustering is used, the colors of the compressed picture become 10 kinds.

Next, use the mpimg.imsave() function to store the compressed file and compare the volume changes of the images before and after compression.

# 运行对比
mpimg.imsave("new_chengdu.png", new_chengdu)
!du -h new_chengdu.png
!du -h challenge-7-chengdu.png

It can be seen that after compressing the image using the Mini Batch K-Means clustering method, the volume is significantly reduced.


○ Sharethis article link to your social media, blog, forum, etc. More external links will increase the search engine ranking of this site.