Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Vector Quantization

Vector Quantization

Sec 14.3.9 of ESL

Mahmood Amintoosi, Fall 2026

Computer Science Dept, Ferdowsi University of Mashhad

Vector Quantization (VQ) and K-means Clustering

Based on Page 533 of ESL

Vector quantization (VQ) is a powerful technique used in image and signal compression. This method is particularly effective when combined with the K-means clustering algorithm, which helps reduce the amount of data needed to represent an image.

Example: Grayscale Image Compression

Consider the grayscale coffee image with resolution of 400 x 600 pixels, meaning it contains 240,000 pixels in total. Each pixel represents a grayscale value between 0 and 255, requiring 8 bits of storage per pixel. Consequently, the full image occupies approximately 240 KB of storage.

VQ Compression Steps

The following steps demonstrate how VQ compression is performed on this image:

  1. Block Partitioning: The image is divided into 2x2 blocks of pixels. This means each block contains 4 pixel values, and the total number of blocks is 200 x 300.

  2. K-means Clustering: We apply the K-means clustering algorithm to the pixel blocks, treating each block as a vector in R4\mathbb{R}^4 (four-dimensional space).

  3. Choosing K = 4: This results in a significant reduction in quality, but a more significant reduction in storage.

  4. Encoding Step: Each block of pixels is approximated by its closest cluster centroid, known as a codeword. The identity of the closest codeword for each block needs to be stored. This requires log2(K)log_2(K) bits per block.

  5. Decoding Step: To reconstruct the approximated image, the centroids are used to create the final image. This step is called the decoding step.

Storage Obligation

When K is reduced to 4, the storage requirement the storage for the compressed image amounts to log2(K)/(4×8)=1/16=0.0625log_2(K)/(4 \times 8) = 1/16 = 0.0625 of the original image, equating to 0.50 bits per pixel.

The crucial steps in VQ involve encoding each block to its nearest codeword and then decoding the image using these codewords, illustrating how K-means can facilitate significant compression in image storage.

400 600 <class 'numpy.float64'>
0.0002827450980392157 1.0
<Figure size 640x480 with 1 Axes>
<Figure size 640x480 with 1 Axes>

Some utility functions

[[ 0  1  2  3  4  5]
 [ 6  7  8  9 10 11]
 [12 13 14 15 16 17]
 [18 19 20 21 22 23]]
(2, 3, 2, 2)
array([[[[ 0, 1], [ 6, 7]], [[ 2, 3], [ 8, 9]], [[ 4, 5], [10, 11]]], [[[12, 13], [18, 19]], [[14, 15], [20, 21]], [[16, 17], [22, 23]]]])
[[ 0  1  2  3  4  5]
 [ 6  7  8  9 10 11]
 [12 13 14 15 16 17]
 [18 19 20 21 22 23]]
[[ 0  2  4 12 14 16]
 [ 1  3  5 13 15 17]
 [ 6  8 10 18 20 22]
 [ 7  9 11 19 21 23]]
array([[ 0, 1, 2, 3, 4, 5], [ 6, 7, 8, 9, 10, 11], [12, 13, 14, 15, 16, 17], [18, 19, 20, 21, 22, 23]])
(4, 60000) 240000 60000.0
Output
C:\Users\m.amintoosi\AppData\Roaming\Python\Python310\site-packages\sklearn\cluster\_kmeans.py:1412: FutureWarning: The default value of `n_init` will change from 10 to 'auto' in 1.4. Set the value of `n_init` explicitly to suppress the warning
  super()._check_params_vs_input(X, default_n_init=10)
(4, 4)
(60000,)
array([[0.52268354, 0.52463973, 0.52423633, 0.52303693], [0.08968596, 0.08971989, 0.08917598, 0.08987512], [0.79994586, 0.80255419, 0.80365328, 0.80144409], [0.3172317 , 0.31510994, 0.31436142, 0.31667701]])
(60000, 4)
<Figure size 640x480 with 1 Axes>

Image Compression Using kmeans

C:\Users\m.amintoosi\AppData\Roaming\Python\Python310\site-packages\sklearn\cluster\_kmeans.py:1412: FutureWarning: The default value of `n_init` will change from 10 to 'auto' in 1.4. Set the value of `n_init` explicitly to suppress the warning
  super()._check_params_vs_input(X, default_n_init=10)
<Figure size 1000x500 with 2 Axes>
array([[0.52732396], [0.0897978 ], [0.80943031], [0.31605731]])