Pythonのプログラムで画質を変化させよう②

Pythonで画像データの情報を変えて確認してみよう。

画像ファイルを読み込もう

先ほどのアクティビティの続きです。

アクティビティのノートブックがそのままであれば、下のプログラムを実行する必要はありません。

ブラウザを閉じてしまったり、更新ボタンを押して初期化された場合は、以下のプログラムを実行してください。

次のプログラムをGoogle Colabの次の入力領域に貼り付けて実行してください。

from PIL import Image
import matplotlib.pyplot as plt
import numpy as np
import io

# 画像をアップロードする場合
from google.colab import files
uploaded = files.upload()

以下のように表示されたら成功です。

「ファイルを選択」をクリックして、最初にダウンロードした「ip01-06-01.png」をアップロードしましょう。

アップロードに成功したら、下のように表示されます。

※ファイル名の後ろについている(3)は、アップロード回数です。無視して構いません。

カラー画像の階調を変えてみよう

すでにアップロードされている「ip01-06-01.png」を読み込み、加工します。

ここ以降は、全員実行してください。

Google Colabの新しいプログラム記入部分を作成し、次のプログラムを貼り付けて実行してください。

from PIL import Image
import matplotlib.pyplot as plt
import numpy as np

img_array = np.array(img)

# 量子化関数(階調数を指定)
def quantize(img_array, levels):
    step = 256 // levels
    return (img_array // step) * step

# 量子化段階(階調数)
levels = [256, 16, 4]
quantized_images = [quantize(img_array, l) for l in levels]

# 表示
plt.figure(figsize=(12, 4))
for i, (qimg, level) in enumerate(zip(quantized_images, levels)):
    plt.subplot(1, len(levels), i + 1)
    plt.imshow(qimg)
    plt.title(f"{level}")
    plt.axis("off")

plt.tight_layout()
plt.show()

実行結果

階調が低くなると、色の種類が少なくなるんだよね。

確かに、色の数が減っているように見えるね。リアルさがなくなってきているね。

一番右の画像は4階調です。

元の画像が256階調で8ビットだったけど、4階調だと2ビットで表現できることになります。

ってことは、それがRGBの3色分だから、合計6ビットか!!

元の画像の4分の1のサイズになったんですね。

カラー画像をグレースケールに変えてみよう

すでにアップロードされている「ip01-06-01.png」を読み込み、加工します。

Google Colabの新しいプログラム記入部分を作成し、次のプログラムを貼り付けて実行してください。

# グレースケールに変換
gray_img = img.convert("L")  # img は課題①で読み込んだ画像を使用
gray_array = np.array(gray_img)

# 量子化段階(階調数)
levels = [256, 16, 4]
quantized_images = [quantize(gray_array, l) for l in levels]

# 表示
plt.figure(figsize=(12, 4))
for i, (qimg, level) in enumerate(zip(quantized_images, levels)):
    plt.subplot(1, len(levels), i + 1)
    plt.imshow(qimg, cmap="gray", vmin=0, vmax=255)
    plt.title(f"{level}")
    plt.axis("off")

plt.tight_layout()
plt.show()

実行結果

グレースケールにした上で、階調も変えてみました!!

すごい、白黒の写真ってこんな感じなんだね。

白黒になって、さらに階調も落としたから、

一番右の画像は、1画素あたり2ビットですね!!

元の画像の12分の1です。

そうですね!!画像は随分サイズが小さくなりましたね。

実際はさらに圧縮されたりするので、正確に12分の1にはなりませんが、おおよそ12分の1位ですね。

今回、階調の変更やグレースケールの変更を行うことで、画像の綺麗さと引き換えにデータのサイズを大きく減らすことができました。

今後画像を扱う上で、画像のデータサイズを小さくするべき場面やその理由を考えて、以下に入力してください。

最大 1000 文字

逆に、画像のデータサイズを小さくするべきではない場面はどのような時でしょうか?理由を含めて以下に入力してください。

最大 1000 文字

RGBカラーの各色を抜き出してみよう

階調を変えて画像を表示してみましょう。

すでにアップロードされている「ip01-06-01.png」を読み込み、加工します。

Google Colabの新しいプログラム記入部分を作成し、次のプログラムを貼り付けて実行してください。

# RGBチャンネルを分離
r, g, b = img.split()

# チャンネル別画像作成(他のチャンネルを0に)
r_img = Image.merge("RGB", (r, Image.new("L", r.size), Image.new("L", r.size)))
g_img = Image.merge("RGB", (Image.new("L", g.size), g, Image.new("L", g.size)))
b_img = Image.merge("RGB", (Image.new("L", b.size), Image.new("L", b.size), b))

# 再合成(RGBチャンネルを再び合成)
merged_img = Image.merge("RGB", (r, g, b))

# 表示
fig, axes = plt.subplots(1, 5, figsize=(18, 4))
titles = ["Original", "Red Channel", "Green Channel", "Blue Channel", "Merged"]
images = [img, r_img, g_img, b_img, merged_img]

for ax, im, title in zip(axes, images, titles):
    ax.imshow(im)
    ax.set_title(title)
    ax.axis("off")

plt.tight_layout()
plt.show()

実行結果

すごいね!!赤だったり、緑だったり、青だったり!!

R・G・Bの3色だから、元の画像はこれらの色が組み合わさっているってことか!!

そうなんです。これらの画像は、各画素のRとGとBの成分を抜き出した画像になるんですよ。

それを組み合わせたものが一番右の画像ですが、元の画像と全く同じですね。

画像って、実はたくさんのデータが集まってできているんだね。

最初の読み込みの時に、好きな画像をアップロードすれば、自分の好きな画像で試せます。

興味のある人は、前のアクティビティも含めて、試してみてください。

このプログラムでは何も提出する必要はありません。次の学習へ進みましょう。

※この再現版では提出は行いません(送信先は未接続です)

Well done!

次のステップに進みましょう!

次のステップに進む

← 前のステップにもどる