[Stove AI] Machine Learning 021 — Использование K-средних для векторного квантования изображений

машинное обучение искусственный интеллект Python алгоритм

[Stove AI] Machine Learning 021 — Использование K-средних для векторного квантования изображений

(Библиотеки Python и номера версий, используемые в этой статье: Python 3.5, Numpy 1.14, scikit-learn 0.19, matplotlib 2.2)

В предыдущей статье мы объяснили метод определения алгоритма K-средних и использовали K-средние для выполнения простого кластерного анализа набора данных. Здесь мы объясняем векторное квантование изображений с использованием k-средних.


1. Введение в векторное квантование

Векторное квантование (VQ) — очень важный метод сжатия сигнала, который занимает очень важное место в области обработки изображений и обработки речевых сигналов.

Векторное квантование — это метод сжатия данных с потерями, основанный на правилах блочного кодирования.В формате сжатия изображения JPEG и формате сжатия видео MPEG-4 существует шаг векторного квантования.Основная идея состоит в том, чтобы сформировать вектор из нескольких групп скалярных данных. а затем дать общее квантование в векторном пространстве, чтобы сжать данные без потери большой информации.

Векторное квантование на самом деле является аппроксимацией.Его основная идея в основном такая же, как и "округление", которое заключается в использовании одного числа для замены другого числа или набора данных, таких как множество данных (6,235, 6,241, 6,238, 6,238954, 6.24205... ), если эти данные округлить, можно получить одни данные 6.24, то есть одни данные (6.24) можно использовать для представления многих данных.

Имея в виду эту основную идею, мы можем рассмотреть следующий пример одномерного векторного квантования:

一维矢量量化举例

В этой числовой строке много данных. Мы можем использовать -3 для представления всех данных меньше -2, -1 для представления данных от -2 до 0, 1 для представления данных от 0 до 2 и 3 для представления Данные больше 2, поэтому несколько беспроводных данных по всей числовой оси могут быть представлены этими четырьмя данными (-3, -1, 1, 3), мы можем закодировать эти четыре числа, нужны только два бита, например ( -3 = 00, -1 = 01, 1 = 10, 3 = 11), так что это 1-мерный, 2-битный VQ, и его скорость квантования = 2 бита на измерение.

Давайте взглянем на немного более сложный пример двумерного векторного квантования:

二维矢量量化的例子

Поскольку он двумерный, любая точка на плоскости может быть выражена как (x, y).На рисунке мы используем синюю сплошную линию, чтобы разделить всю двумерную плоскость на 16 областей, поэтому любые точки данных будут падать в одну из этих 16 областей. Мы можем использовать некоторые точки на плоскости, чтобыпредставлятьВ этой плоской области получается 16 красных точек, и координаты этих 16 красных точек представляют собой все двумерные точки в определенной области.

Кроме того, мы используем 4-битный двоичный код для кодирования этих 16 чисел, поэтому эта задача является 2-мерной, 4-битной VQ, и ее скорость квантования также равна скорости = 2 бит/размерность.

Красные звездочки, показанные на схеме здесь, или 16 представителей, называются кодовыми векторами, а области, ограниченные синими границами, называются областями кодирования, а совокупность всех этих кодовых векторов называется кодовой книгой (кодовой книгой), множество все области кодирования называется разделом пространства.

Для изображения можно считать, что каждый пиксель изображения представляет собой часть данных, и для выполнения кластерного анализа этих данных используется k-средних.Например, если все изображение сгруппировано в K категорий, то K различных будут получены центроиды (о Для понимания и интуитивного ощущения центроида можно обратиться к моей предыдущей статье[Stove AI] Машинное обучение 020-Использование алгоритма K-средних для кластерного анализа данных), или, вообще говоря, можно получить K различных представлений данных, и эти представления данных могут представлять значения пикселей всех точек на всем изображении, поэтому нам нужно знать только K представлений данных (подумайте о Национальном народном представлении). Конгресс. Представитель понимает эту истину), что может сильно уменьшить место для хранения картинки (например, изображение в формате bmp может иметь размер 2-3М, а после сжатия в jpg оно составляет всего несколько сотен К. Конечно, процесс сжатия в jpg все же Есть и другие методы сжатия, не только векторное квантование, но примерно того же значения), конечно, этот репрезентативный процесс вызовет определенные искажения пикселей изображения, а степень искажения - это число К. С картинками это можно выразить так:

矢量量化压缩图像的简单说明

(Часть вышеуказанного контента взята из блогаВекторное квантование)


2. Используйте K-средние для векторизации изображения.

В соответствии с введением векторного квантования в первой части выше, мы можем выполнять векторное квантование и сжатие определенного изображения, мы можем извлечь из изображения представителей K пикселей, а затем использовать эти представители для представления изображения. Конкретный код:

from sklearn.cluster import KMeans
# 构建一个函数来完成图像的矢量量化操作
def image_VQ(image,K_nums): # 貌似很花时间。。
    # 构建一个KMeans对象
    kmeans=KMeans(n_clusters=K_nums,n_init=4)
    # 用这个KMeans对象来训练数据集,此处的数据集就是图像
    img_data=image.reshape((-1,1))
    kmeans.fit(img_data)
    centroids=kmeans.cluster_centers_.squeeze() # 每一个类别的质心
    labels=kmeans.labels_ # 每一个类别的标记
    return np.choose(labels,centroids).reshape(image.shape)

Выше мы сначала создаем функцию для завершения операции сжатия векторного квантования изображения.Эта операция сначала создает объект Kmeans, затем использует этот объект KMeans для обучения данных изображения, а затем поднимает центроиды и метки каждой категории после классификации, и использует эти центроиды. Чтобы напрямую заменить исходные пиксели изображения, можно получить сжатое изображение.

Чтобы увидеть исходное изображение и сжатое изображение, мы наносим оба изображения на одну строку, функция графика:

# 将原图和压缩图都绘制出来,方便对比查看效果
def plot_imgs(raw_img,VQ_img,compress_rate):
    assert raw_img.ndim==2 and VQ_img.ndim==2, "only plot gray scale images"
    plt.figure(12,figsize=(25,50))
    plt.subplot(121)
    plt.imshow(raw_img,cmap='gray')
    plt.title('raw_img')
    
    plt.subplot(122)
    plt.imshow(VQ_img,cmap='gray')
    plt.title('VQ_img compress_rate={:.2f}%'.format(compress_rate))
    plt.show()

Для удобства использования мы можем напрямую инкапсулировать функцию сжатого изображения и функцию отображения изображения в функцию более высокого уровня, которую нам удобно вызывать и запускать напрямую, как показано ниже:

import cv2
def compress_plot_img(img_path,num_bits):
    assert 1<=num_bits<=8, 'num_bits must be between 1 and 8'
    K_nums=np.power(2,num_bits)
    
    # 计算压缩率
    compression_rate=round(100*(8-num_bits)/8,2)
#     print('compression rate is {:.2f}%'.format(compression_rate))
    
    image=cv2.imread(img_path,0) # 读取为灰度图
    VQ_img=image_VQ(image,K_nums)
    plot_imgs(image,VQ_img,compression_rate)

После подготовки различных рабочих функций мы можем напрямую вызвать функцию compress_plot_img() для сжатия и отображения изображения.Ниже показано изображение, полученное с использованием трех разных битов для сжатия, вы можете сравнить эффект.

图像压缩率50%的效果对比图

图像压缩率75%的效果对比图

图像压缩率87.5%的效果对比图

########################резюме########################## ######

1. Суть векторного квантования и сжатия изображений состоит в том, чтобы разделить данные изображения на К различных аналогий.Эта идея согласуется с идеей К-средних.Поэтому векторное квантование изображений является важным приложением К- означает алгоритм.

2. После того, как центроиды K категорий изображения получены с помощью алгоритма K-средних, можно использовать K различных центроидов для замены пикселей изображения, а затем можно получить сжатое изображение с небольшим искажением.

3. Из сравнения трех приведенных выше изображений видно, что чем больше степень сжатия изображения, тем сильнее искажено изображение.Об изображении, когда последний бит равен 1, можно сказать, что оно является двоичным изображением, а его значение пикселя равно 0 или 1. Либо 1, либо 0.

#################################################################


Примечание. Эта часть кода была загружена в (мой гитхаб), добро пожаловать на скачивание.

Использованная литература:

1. Классические примеры машинного обучения Python, Пратик Джоши, перевод Тао Цзюньцзе и Чена Сяоли.