Quantizing an image with KMeans clustering使用KMeans聚类量化图片

2020-04-24 12:02:11 浏览数 (1)

Image processing is an important topic in which clustering has some application.

It's worth pointing out that there are several very good image-processing libraries in Python. scikit-image is a "sister" project of scikit-learn. It's worth taking a look at if you want to do anything complicated.

图片处理是聚类方法应用中的一个重要的主题。

值得指出的是python中有很多很好的图片处理方法,scikit-image是scikit-learn的一个姐妹工程。如果你想知道些更复杂的知识,值得去学习一下。

Getting ready准备工作

We will have some fun in this recipe. The goal is to use cluster to blur an image.First, we'll make use of SciPy to read the image. The image is translated in a 3-dimensional array; the x and y coordinates describe the height and width, and the third dimension represents the RGB values for each image:

我们在这部分将要做些有趣的事情,目标是用聚类方法模糊化一张图片。首先,我们使用Scipy来读取图片,图片被转变为一个三维数组。其中x、y轴描述高和宽,第三个维度代表每个点的RGB值

How do it…怎么做

Now, let's read the image in Python:现在让我们使用python读取图片

代码语言:javascript复制
from scipy import misc
from scipy import ndimage
import matplotlib.pyplot as plt
face = misc.face()#face是测试图像之一
plt.figure()#创建图形
plt.imshow(face)#绘制测试图像
plt.show()#原始图像

The following image is seen:图片如下

Now that we have the image, let's check its dimensions:现在我们有了图片,让我们来检查下它的维度:

代码语言:javascript复制
face.shape
(768, 1024, 3)

To actually quantize the image, we need to convert it into a two-dimensional array, with the length being 420 x 420 and the width being the RGB values. A better way to think about this is to have a bunch of data points in three-dimensional space and cluster the points to reduce the number of distant colors in the image—a simple way to put quantization.

为了实际量化该图片,我们需要转换它为含有RGB值的768*1024,的二维数组,一个好的想法是,用一个三维空间上的数据和聚类点来所见图片中颜色点的距离,这是一个简单的量化方法。

First, let's reshape our array; it is a NumPy array, and thus trivial to work with:首先,我们重新定义数组的形状,这是一个numpy数组,因此先处理下:

代码语言:javascript复制
x, y, z = img.shape
long_img = img.reshape(x*y, z)
long_img.shape
(786432, 3)

Now we can start the clustering process. First, let's import the cluster module and create a KMeans object. We'll pass n_clusters=5 so that we have five clusters, or really, five distinct colors.This will be a good recipe to practice using silhouette distance that we reviewed in the Optimizing the number of centroids recipe:

现在我们开始聚类处理,首先我们导入cluster模型,并生成一个KMeans对象,我们将设置n_clusters=5以便我们有5个聚类的组,或者说5种不同的颜色。这是一个好的方法来练习使用轮廓距离,复习我们最优化形心点数量的方法。

代码语言:javascript复制
from sklearn import cluster
k_means = cluster.KMeans(n_clusters=5)
k_means.fit(long_img)

Now that we have our fit KMeans objects, let's take a look at our colors:现在我们已经拟合了KMeans对象,让我们看一下颜色

代码语言:javascript复制
centers = k_means.cluster_centers_
centers
array([[113.74738753, 122.97326527, 103.05911441],
       [196.61782414, 192.00963116, 205.4741469 ],
       [ 26.99832069,  30.91149013,  21.43255311],
       [155.92522469, 166.26557584, 140.45856403],
       [ 74.04835993,  84.06392931,  62.79821955]])

How it works…如何工作的:

Now that we have the centers, the next thing we need is the labels. This will tell us which points should be associated with which clusters:

现在我们有了中心点,下一步需要它的标签,这将告诉我们哪些点和哪个区域有联系。

代码语言:javascript复制
labels = k_means.labels_
labels[:5]
array([1, 1, 1, 1, 1], dtype=int32)

At this point, we require the simplest of NumPy array manipulation followed by a bit of reshaping, and we'll have the new image:

此时,我们需要用最简单的numpy数组操作紧接着做些改变,我们就会得到新的图片:

代码语言:javascript复制
plt.imshow(centers[labels].reshape(x, y, z).astype(int))
# Matplotlib显示图像,如果是01区间,值为float,如果是0255区间,值为int,需要转换,否则无法显示

The following is the resultant image:如下图所示:

0 人点赞