KBinsDiscretizer を使ったベクトル量子化

Beginner

This tutorial is from open-source community. Access the source code

はじめに

この実験では、Scikit-learn ライブラリの KBinsDiscretizer を使用して、アライグマの顔のサンプル画像に対してベクトル量子化を行う方法を示します。ベクトル量子化は、画像を表すために使用されるグレーレベルの数を減らす技術です。我々は、アライグマの顔画像に対して KBinsDiscretizer を使用してベクトル量子化を行います。画像を表すために 8 つのグレーレベルを使用し、1 ピクセル当たり 3 ビットのみを使用して圧縮することができます。ピクセル値を 8 つのグレーレベルにマッピングするために、一様および k-means クラスタリング戦略を比較します。

VM のヒント

VM の起動が完了したら、左上隅をクリックしてノートブックタブに切り替え、Jupyter Notebook を使用して練習します。

時々、Jupyter Notebook が読み込み終了するまで数秒待つ必要がある場合があります。Jupyter Notebook の制限により、操作の検証を自動化することはできません。

学習中に問題に遭遇した場合は、Labby にお問い合わせください。セッション後にフィードバックを提供してください。そうすれば、迅速に問題を解決します。

元の画像を読み込んで表示する

まず、Scipy からアライグマの顔画像を読み込みます。画像を表示し、その形状、データ型、メモリ使用量を確認します。

from scipy.misc import face
import matplotlib.pyplot as plt

raccoon_face = face(gray=True)

print(f"The dimension of the image is {raccoon_face.shape}")
print(f"The data used to encode the image is of type {raccoon_face.dtype}")
print(f"The number of bytes taken in RAM is {raccoon_face.nbytes}")

fig, ax = plt.subplots(ncols=2, figsize=(12, 4))
ax[0].imshow(raccoon_face, cmap=plt.cm.gray)
ax[0].axis("off")
ax[0].set_title("Original Image")
ax[1].hist(raccoon_face.ravel(), bins=256)
ax[1].set_xlabel("Pixel value")
ax[1].set_ylabel("Count of pixels")
ax[1].set_title("Distribution of the pixel values")
_ = fig.suptitle("Original Image of a Raccoon Face")

KBinsDiscretizer を使ったベクトル量子化

ここでは、KBinsDiscretizer を使ってアライグマの顔画像に対してベクトル量子化を行います。画像を表すために 8 つのグレーレベルを使用し、1 ピクセル当たり 3 ビットのみを使用して圧縮することができます。ピクセル値を 8 つのグレーレベルにマッピングするために、一様および k-means クラスタリング戦略を使用します。

一様サンプリング戦略

まず、一様サンプリング戦略を使ってピクセル値を 8 つのグレーレベルにマッピングします。

from sklearn.preprocessing import KBinsDiscretizer

n_bins = 8
encoder = KBinsDiscretizer(
    n_bins=n_bins, encode="ordinal", strategy="uniform", random_state=0
)
compressed_raccoon_uniform = encoder.fit_transform(raccoon_face.reshape(-1, 1)).reshape(
    raccoon_face.shape
)

fig, ax = plt.subplots(ncols=2, figsize=(12, 4))
ax[0].imshow(compressed_raccoon_uniform, cmap=plt.cm.gray)
ax[0].axis("off")
ax[0].set_title("Uniform Sampling")
ax[1].hist(compressed_raccoon_uniform.ravel(), bins=256)
ax[1].set_xlabel("Pixel value")
ax[1].set_ylabel("Count of pixels")
ax[1].set_title("Distribution of the pixel values")
_ = fig.suptitle("Raccoon face compressed using 3 bits and a uniform strategy")
k-means クラスタリング戦略

次に、k-means クラスタリング戦略を使ってピクセル値を 8 つのグレーレベルにマッピングします。

encoder = KBinsDiscretizer(
    n_bins=n_bins, encode="ordinal", strategy="kmeans", random_state=0
)
compressed_raccoon_kmeans = encoder.fit_transform(raccoon_face.reshape(-1, 1)).reshape(
    raccoon_face.shape
)

fig, ax = plt.subplots(ncols=2, figsize=(12, 4))
ax[0].imshow(compressed_raccoon_kmeans, cmap=plt.cm.gray)
ax[0].axis("off")
ax[0].set_title("K-Means Clustering")
ax[1].hist(compressed_raccoon_kmeans.ravel(), bins=256)
ax[1].set_xlabel("Pixel value")
ax[1].set_ylabel("Count of pixels")
ax[1].set_title("Distribution of the pixel values")
_ = fig.suptitle("Raccoon face compressed using 3 bits and a K-means strategy")

メモリ使用量

ここでは、圧縮された画像のメモリ使用量を確認します。圧縮された画像は、元の画像よりも 8 分の 1 のメモリを使用することが期待されます。

print(f"The number of bytes taken in RAM is {compressed_raccoon_kmeans.nbytes}")
print(f"Compression ratio: {compressed_raccoon_kmeans.nbytes / raccoon_face.nbytes}")

まとめ

この実験では、Scikit-learn の KBinsDiscretizer を使って、アライグマの顔のサンプル画像に対してベクトル量子化を行いました。画像を表すために 8 つのグレーレベルを使用し、1 ピクセル当たり 3 ビットのみを使用して圧縮することができます。ピクセル値を 8 つのグレーレベルにマッピングするために、一様および k-means クラスタリング戦略を比較しました。k-means クラスタリング戦略が、ピクセル値のよりバランスの良い分布を提供することがわかりました。また、圧縮された画像のメモリ使用量を確認したところ、圧縮された画像が 64 ビット浮動小数点数表現を使用しているため、元の画像よりも 8 倍のメモリを消費することがわかりました。

まとめ

おめでとうございます!あなたは KBinsDiscretizer を使ったベクトル量子化の実験を完了しました。あなたの技術を向上させるために、LabEx でさらに多くの実験を行って練習することができます。