Skip to content

7. 画像処理 ①:基礎

近年、ディープラーニングの発展により、画像認識技術は飛躍的に進化しています。本講義では、まず画像データの基本的な扱い方を学び、次回以降で古典的な特徴抽出や CNN(畳み込みニューラルネットワーク)について学んでいきます。

第 7 回では、機械学習における画像処理の基礎について学びます。

7.1 画像データの基礎

7.1.1 デジタル画像とは

デジタル画像は、画素(ピクセル) と呼ばれる小さな点の集まりで表現されます。各画素は色や明るさの情報を持っており、これらを格子状に配置することで画像を構成します。

graph LR
    A["デジタル画像<br/>(例: 1920×1080)"]
    B["画素の集まり<br/>(ピクセル配列)"]
    C["各画素の値<br/>(R, G, B: 0-255)"]
    D["数値データ<br/>(行列として処理)"]

    A --> B --> C --> D

    style A fill:#e6ccff,stroke:#9966ff,stroke-width:3px
    style B fill:#ccffcc,stroke:#66cc66,stroke-width:3px
    style C fill:#ffffcc,stroke:#ffcc00,stroke-width:3px
    style D fill:#ffcccc,stroke:#ff6666,stroke-width:3px

画像の主要な要素:

  • 画素(ピクセル): 画像を構成する最小単位
  • 解像度: 画像の幅 × 高さのピクセル数(例:1920×1080)
  • 色深度: 各画素で表現できる色の数(例:8bit = 256 色)

7.1.2 画像の種類

デジタル画像は、色の表現方法によって主に 3 つの種類に分けられます。

graph TB
    A["デジタル画像の種類"]

    B["グレースケール画像<br/>(1チャンネル)<br/>例: 白黒写真"]
    C["カラー画像 RGB<br/>(3チャンネル)<br/>例: 通常の写真"]
    D["RGBA画像<br/>(4チャンネル)<br/>例: PNG透過画像"]

    A --> B & C & D

    B --> B1["明るさのみ<br/>0(黒) ~ 255(白)"]
    C --> C1["Red, Green, Blue<br/>各 0~255 の組み合わせ"]
    D --> D1["RGB + Alpha透明度<br/>0(透明) ~ 255(不透明)"]

    style A fill:#e6ccff,stroke:#9966ff,stroke-width:3px
    style B fill:#ccffcc,stroke:#66cc66,stroke-width:2px
    style C fill:#ffffcc,stroke:#ffcc00,stroke-width:2px
    style D fill:#ffcccc,stroke:#ff6666,stroke-width:2px
    style B1 fill:#e6ffe6,stroke:#66cc66,stroke-width:1px
    style C1 fill:#fffef0,stroke:#ffcc00,stroke-width:1px
    style D1 fill:#ffe6e6,stroke:#ff6666,stroke-width:1px

グレースケール画像:

  • 各画素が 1 つの値(明るさ)を持つ
  • 0(黒)から 255(白)の範囲
  • 形状: (高さ, 幅)

カラー画像(RGB):

  • 各画素が R(赤)、G(緑)、B(青)の 3 つの値を持つ
  • 各チャンネルが 0〜255 の範囲
  • 形状: (高さ, 幅, 3)

RGBA 画像:

  • RGB + Alpha(透明度)
  • 形状: (高さ, 幅, 4)

7.1.3 Python での画像の扱い

Python で画像を扱うには、主に以下のライブラリを使用します。

主要なライブラリ

  • Pillow(PIL): 画像の読み込み・保存・基本操作
  • OpenCV: 高度な画像処理・コンピュータビジョン
  • matplotlib: 画像の表示
  • NumPy: 画像データの数値計算
graph TB
    A["画像ファイル<br/>(PNG, JPEG, etc.)"]
    B["読み込み:<br/>Pillow / OpenCV"]
    C["NumPy配列に変換<br/>(height, width, channels)"]
    D["画像処理・演算<br/>(NumPy / OpenCV)"]
    E1["表示: matplotlib"]
    E2["保存: Pillow / OpenCV"]

    A --> B --> C --> D
    D --> E1
    D --> E2

    style A fill:#e6f3ff,stroke:#66b3ff,stroke-width:3px
    style B fill:#fff4cc,stroke:#ffcc00,stroke-width:3px
    style C fill:#ccffcc,stroke:#66cc66,stroke-width:3px
    style D fill:#ffffcc,stroke:#ffcc00,stroke-width:3px
    style E1 fill:#ffcccc,stroke:#ff6666,stroke-width:2px
    style E2 fill:#ffe6f0,stroke:#ff99cc,stroke-width:2px

7.2 画像の読み込みと表示

7.2.1 Pillow による画像の読み込み

Pillow は、Python で画像を扱うための基本的なライブラリです。

画像を読み込むには PIL.Image.open() 関数を使用します。

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

# 画像の読み込み
img = Image.open('sample.jpg')

# 画像情報の確認
print(f"画像サイズ: {img.size}")  # (幅, 高さ)
print(f"画像モード: {img.mode}")  # 'RGB', 'L' など
print(f"画像フォーマット: {img.format}")  # 'JPEG', 'PNG' など

# NumPy配列に変換
img_array = np.array(img)
print(f"配列の形状: {img_array.shape}")  # (高さ, 幅, チャンネル数)
print(f"データ型: {img_array.dtype}")
print(f"値の範囲: {img_array.min()} ~ {img_array.max()}")

# 画像の表示
plt.figure(figsize=(8, 6))
plt.imshow(img)
plt.title('元の画像')
plt.axis('off')
plt.show()

Pillow のインストール

Pillow をインストールするには、以下のコマンドを実行します。

pip install Pillow

※ CHIKUWA Editor にはインストール済みです。

7.2.2 サンプル画像の生成

実習用に、NumPy を使ってサンプル画像を生成してみましょう。

import numpy as np
import matplotlib.pyplot as plt

# グレースケール画像の生成(グラデーション)
height, width = 200, 300
gradient = np.linspace(0, 255, width, dtype=np.uint8)
gray_img = np.tile(gradient, (height, 1))

# カラー画像の生成(RGB)
color_img = np.zeros((200, 300, 3), dtype=np.uint8)
color_img[:, :100, 0] = 255  # 左側を赤
color_img[:, 100:200, 1] = 255  # 中央を緑
color_img[:, 200:, 2] = 255  # 右側を青

# 表示
fig, axes = plt.subplots(1, 2, figsize=(12, 5))

axes[0].imshow(gray_img, cmap='gray')
axes[0].set_title('グレースケール画像')
axes[0].axis('off')

axes[1].imshow(color_img)
axes[1].set_title('カラー画像(RGB)')
axes[1].axis('off')

plt.tight_layout()
plt.show()

print(f"グレースケール画像の形状: {gray_img.shape}")
print(f"カラー画像の形状: {color_img.shape}")

7-1

7.3 画素と色空間

7.3.1 RGB 色空間

RGB 色空間 は、赤(Red)、緑(Green)、青(Blue)の 3 つの原色を組み合わせて色を表現する方法です。

graph TB
    A["RGB 色空間<br/>(加法混色)"]
    B["R: 0-255<br/>(赤チャンネル)"]
    C["G: 0-255<br/>(緑チャンネル)"]
    D["B: 0-255<br/>(青チャンネル)"]
    E["色の組み合わせ<br/>256³ = 16,777,216 色"]

    A --> B & C & D
    B & C & D --> E

    style A fill:#e6ccff,stroke:#9966ff,stroke-width:3px
    style B fill:#ffcccc,stroke:#ff6666,stroke-width:2px
    style C fill:#ccffcc,stroke:#66cc66,stroke-width:2px
    style D fill:#ccccff,stroke:#6666ff,stroke-width:2px
    style E fill:#ffffcc,stroke:#ffcc00,stroke-width:3px

主要な色の例:

R G B
0 0 0
255 255 255
255 0 0
0 255 0
0 0 255
255 255 0
255 0 255
水色 0 255 255
import numpy as np
import matplotlib.pyplot as plt

# 表示する色(色名とRGB値)
colors = {
    '黒': [0, 0, 0],
    '白': [255, 255, 255],
    '赤': [255, 0, 0],
    '緑': [0, 255, 0],
    '青': [0, 0, 255],
    '黄': [255, 255, 0],
    '紫': [255, 0, 255],
    '水色': [0, 255, 255]
}

# 2行4列で8色を表示
fig, axes = plt.subplots(2, 4, figsize=(12, 6))
axes = axes.ravel()

# 各色を順番に表示
for i, (name, rgb) in enumerate(colors.items()):
    img = np.full((100, 100, 3), rgb, dtype=np.uint8)
    axes[i].imshow(img)
    axes[i].set_title(f'{name}\nRGB{tuple(rgb)}')
    axes[i].axis('off')

plt.tight_layout()
plt.show()

7-2

7.3.2 グレースケール変換

カラー画像をグレースケール画像に変換する方法はいくつかあります。

変換方法:

  1. 単純平均法: Gray = (R + G + B) / 3
  2. 加重平均法: Gray = 0.299×R + 0.587×G + 0.114×B ※ 人間の視覚特性を考慮した重み付け
  3. Pillow の変換: Image.convert() 関数で 'L' モードに変換
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt

# サンプル画像の作成
color_img = np.zeros((200, 300, 3), dtype=np.uint8)
color_img[:, :100, 0] = 255  # 赤
color_img[:, 100:200, 1] = 255  # 緑
color_img[:, 200:, 2] = 255  # 青

# 方法1: 単純平均法
gray_avg = np.mean(color_img, axis=2).astype(np.uint8)

# 方法2: 加重平均法
gray_weighted = (0.299 * color_img[:, :, 0] +
                0.587 * color_img[:, :, 1] +
                0.114 * color_img[:, :, 2]).astype(np.uint8)

# 方法3: Pillowを使用(内部で加重平均の計算)
img_pil = Image.fromarray(color_img)
gray_pil = np.array(img_pil.convert('L'))

# 表示
fig, axes = plt.subplots(2, 2, figsize=(12, 10))

axes[0, 0].imshow(color_img)
axes[0, 0].set_title('元のカラー画像')
axes[0, 0].axis('off')

axes[0, 1].imshow(gray_avg, cmap='gray')
axes[0, 1].set_title('単純平均法')
axes[0, 1].axis('off')

axes[1, 0].imshow(gray_weighted, cmap='gray')
axes[1, 0].set_title('加重平均法')
axes[1, 0].axis('off')

axes[1, 1].imshow(gray_pil, cmap='gray')
axes[1, 1].set_title('Pillow の convert()')
axes[1, 1].axis('off')

plt.tight_layout()
plt.show()

7-3

色空間の使い分け

  • RGB: 画像の表示、一般的な画像処理、ニューラルネットワークの入力
  • グレースケール: 形状認識、高速処理、計算量削減

7.3 機械学習のための画像前処理

機械学習モデルに画像を入力する前に、適切な前処理を行うことが重要です。このセクションでは、ニューラルネットワークで画像を扱う際に必須となる処理を学びます。

7.3.1 画像のリサイズ

ニューラルネットワークは固定サイズの入力を必要とするため、画像のリサイズは必須の前処理です。画像のリサイズには Image.resize() 関数を使用します。

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

# サンプル画像の読み込み
original = data.astronaut()  # (512, 512, 3)

# NumPy配列をPillow Imageに変換
img_pil = Image.fromarray(original)
# 画像をリサイズ
resized_pil = img_pil.resize((224, 224))  # (幅, 高さ) - よく使われるサイズ
# Pillow ImageをNumPy配列に戻す
resized_array = np.array(resized_pil)

print(f"元の画像: {original.shape}")
print(f"リサイズ後: {resized_array.shape}")

# 表示
fig, axes = plt.subplots(1, 2, figsize=(12, 5))

axes[0].imshow(original)
axes[0].set_title(f'元の画像 {original.shape[:2]}')
axes[0].axis('off')

axes[1].imshow(resized_array)
axes[1].set_title(f'リサイズ後 {resized_array.shape[:2]}')
axes[1].axis('off')

plt.tight_layout()
plt.show()

よく使われる画像サイズ

  • 224×224: VGG、ResNetなどの標準サイズ
  • 299×299: Inception系のネットワーク
  • 32×32: CIFAR-10データセット
  • 28×28: MNISTデータセット(手書き数字)

7.3.2 正規化(0-1 変換)

画像の画素値(0-255)をニューラルネットワークに適した範囲(0-1)に正規化することは極めて重要です。

import numpy as np
import matplotlib.pyplot as plt
from skimage import data

# サンプル画像の読み込み
img = data.camera()

# 正規化: 0-255 → 0-1
img_normalized = img / 255.0

print(f"元の画像の範囲: {img.min()}{img.max()}")
print(f"元の画像のデータ型: {img.dtype}")
print(f"正規化後の範囲: {img_normalized.min():.2f}{img_normalized.max():.2f}")
print(f"正規化後のデータ型: {img_normalized.dtype}")

# 表示(matplotlib は 0-1 と 0-255 の両方に対応)
fig, axes = plt.subplots(1, 2, figsize=(12, 5))

axes[0].imshow(img, cmap='gray')
axes[0].set_title(f'元の画像 (0-255)\n{img.dtype}')
axes[0].axis('off')

axes[1].imshow(img_normalized, cmap='gray')
axes[1].set_title(f'正規化後 (0-1)\n{img_normalized.dtype}')
axes[1].axis('off')

plt.tight_layout()
plt.show()

正規化の重要性

なぜ正規化が必要か?

  1. 学習の安定性: 大きな値(0-255)はニューラルネットワークの学習を不安定にする
  2. 勾配の制御: 適切な範囲の値により、勾配消失・爆発を防ぐ
  3. 収束速度: 正規化により学習が速く収束する

標準的な正規化方法:

  • img / 255.0 → [0, 1] の範囲
  • (img - mean) / std → 平均0、標準偏差1(標準化)

7.3.3 データ拡張の基礎

データ拡張は、訓練データを人工的に増やす技術です。過学習を防ぎ、モデルの汎化性能を向上させます。画像の変換には Image.transpose()Image.rotate() 関数を使用します。

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

# サンプル画像の読み込み
img = data.chelsea()  # 猫の画像
img_pil = Image.fromarray(img)

# データ拡張の例
augmented = {
    '元の画像': img,
    '左右反転': np.array(img_pil.transpose(Image.FLIP_LEFT_RIGHT)),
    '回転 15度': np.array(img_pil.rotate(15)),
    '明るさ +50': np.clip(img + 50, 0, 255).astype(np.uint8),
}

# 表示
fig, axes = plt.subplots(2, 2, figsize=(12, 10))
axes = axes.ravel()

for idx, (title, aug_img) in enumerate(augmented.items()):
    axes[idx].imshow(aug_img)
    axes[idx].set_title(title)
    axes[idx].axis('off')

plt.tight_layout()
plt.show()

データ拡張のポイント

よく使われる拡張手法:

  • 左右反転: 最も一般的な拡張
  • 回転: 物体の向きに依存しない認識
  • 明るさ調整: 照明条件の変化に対応
  • クロッピング: ランダムな位置から切り取り

注意点:

  • 拡張は訓練データのみに適用(テストデータには適用しない)
  • タスクに応じて適切な拡張を選択(例: 文字認識では上下反転は不適切)

7.4 しきい値処理

しきい値処理 は、画像を二値化(白と黒の 2 値に分ける)する基本的な画像処理手法です。物体検出や領域分割の前処理として広く使われます。

graph LR
    A["グレースケール画像<br/>(画素値: 0-255)"]
    B["しきい値と比較<br/>(例: T=128)"]
    C{"画素値 > T?"}
    D["白 (255)<br/>(前景)"]
    E["黒 (0)<br/>(背景)"]
    F["二値画像<br/>(0 or 255)"]

    A --> B --> C
    C -->|Yes| D
    C -->|No| E
    D --> F
    E --> F

    style A fill:#e6f3ff,stroke:#66b3ff,stroke-width:3px
    style B fill:#fff4cc,stroke:#ffcc00,stroke-width:3px
    style C fill:#ffcccc,stroke:#ff6666,stroke-width:3px
    style D fill:#ffffff,stroke:#999999,stroke-width:2px
    style E fill:#888888,stroke:#666666,stroke-width:2px,color:#fff
    style F fill:#ccffcc,stroke:#66cc66,stroke-width:3px

しきい値処理の用途:

  • 物体と背景の分離
  • 文字認識の前処理
  • 物体の輪郭抽出
  • 特定の明るさ範囲の抽出

7.4.1 固定しきい値処理

最も基本的なしきい値処理は、固定のしきい値を使う方法です。

import numpy as np
import matplotlib.pyplot as plt
from skimage import data

# サンプル画像の読み込み
img = data.camera()

# しきい値を設定して二値化
threshold = 128
binary = (img > threshold).astype(np.uint8) * 255

# 表示
fig, axes = plt.subplots(1, 2, figsize=(12, 5))

axes[0].imshow(img, cmap='gray')
axes[0].set_title('元の画像')
axes[0].axis('off')

axes[1].imshow(binary, cmap='gray')
axes[1].set_title(f'しきい値 = {threshold}')
axes[1].axis('off')

plt.tight_layout()
plt.show()

7.4.2 大津の二値化(Otsu's method)

大津の二値化 は、画像のヒストグラムから自動的に最適なしきい値を決定する手法です。クラス内分散を最小化(クラス間分散を最大化)することで、最適なしきい値を求めます。最適なしきい値の計算には filters.threshold_otsu() 関数を使用します。

graph TB
    A["ヒストグラム分析<br/>(画素値の分布)"]
    B["全候補を探索<br/>(T = 0 ~ 255)"]
    C["分散計算<br/>(クラス間分散σ²)"]
    D["最大値を選択<br/>(max σ²)"]
    E["最適しきい値<br/>(自動決定)"]

    A --> B --> C --> D --> E

    style A fill:#e6f3ff,stroke:#66b3ff,stroke-width:3px
    style B fill:#fff4cc,stroke:#ffcc00,stroke-width:2px
    style C fill:#ffffcc,stroke:#ffcc00,stroke-width:2px
    style D fill:#ffcccc,stroke:#ff6666,stroke-width:2px
    style E fill:#ccffcc,stroke:#66cc66,stroke-width:3px
import numpy as np
import matplotlib.pyplot as plt
from skimage import data, filters

# サンプル画像の読み込み
img = data.camera()

# 大津の二値化でしきい値を自動決定
threshold_otsu = filters.threshold_otsu(img)
binary_otsu = img > threshold_otsu

print(f"大津の二値化による最適しきい値: {threshold_otsu}")

# 表示
fig, axes = plt.subplots(1, 2, figsize=(12, 5))

axes[0].imshow(img, cmap='gray')
axes[0].set_title('元の画像')
axes[0].axis('off')

axes[1].imshow(binary_otsu, cmap='gray')
axes[1].set_title(f'大津の二値化 (しきい値 = {threshold_otsu:.1f})')
axes[1].axis('off')

plt.tight_layout()
plt.show()

しきい値処理のポイント

しきい値の選び方:

  • 固定しきい値: 照明が均一で、対象物と背景のコントラストが明確な場合
  • 大津の二値化: 最適なしきい値を自動で決定したい場合

注意点:

  • しきい値処理の前に、ノイズ除去(ガウシアンフィルタなど)を適用すると効果的
  • カラー画像の場合は、グレースケールに変換してから処理する

7.5 画像フィルタリング

画像のノイズを除去するために、フィルタリング(平滑化)を行います。機械学習の前処理としても重要です。

7.5.1 ガウシアンフィルタ

ガウシアンフィルタ は、画像のノイズを除去しながらエッジを比較的保持するフィルタです。ガウシアンフィルタの適用には filters.gaussian() 関数を使用します。

import numpy as np
import matplotlib.pyplot as plt
from skimage import data, filters

# サンプル画像の読み込み
img = data.camera()

# ノイズを追加
noise = np.random.normal(0, 25, img.shape)
noisy_img = np.clip(img + noise, 0, 255).astype(np.uint8)

# ガウシアンフィルタでノイズ除去
filtered = filters.gaussian(noisy_img, sigma=2)

# 表示
fig, axes = plt.subplots(1, 3, figsize=(16, 5))

axes[0].imshow(img, cmap='gray')
axes[0].set_title('元の画像')
axes[0].axis('off')

axes[1].imshow(noisy_img, cmap='gray')
axes[1].set_title('ノイズあり')
axes[1].axis('off')

axes[2].imshow(filtered, cmap='gray')
axes[2].set_title('ガウシアンフィルタ適用後')
axes[2].axis('off')

plt.tight_layout()
plt.show()

ガウシアンフィルタのパラメータ

  • sigma: フィルタの強さ(大きいほど強くぼかす)
  • sigma=1: 弱いぼかし
  • sigma=3: 中程度のぼかし
  • sigma=5: 強いぼかし

7.6 scikit-image のサンプル画像

scikit-image は、画像処理のための Python ライブラリです。多くの画像処理アルゴリズムが実装されており、実験用のサンプル画像も含まれています。

サンプル画像の読み込みには data モジュールの各関数を使用します。

主なサンプル画像:

関数名 説明 サイズ 種類 用途例
data.camera() カメラマンの写真 512×512 グレースケール 一般的な画像処理の実験
data.astronaut() 宇宙飛行士の写真 512×512×3 カラー(RGB) カラー画像処理、チャンネル分離
data.coins() 複数のコインの写真 303×384 グレースケール しきい値処理、物体検出
data.chelsea() 猫の写真 300×451×3 カラー(RGB) データ拡張、リサイズ
data.coffee() コーヒーカップの写真 400×600×3 カラー(RGB) 色空間の変換
data.moon() 月面の写真 512×512 グレースケール コントラスト調整
data.text() テキストの画像 172×448 グレースケール 二値化、文字認識

使用例:

from skimage import data
import matplotlib.pyplot as plt

# サンプル画像の読み込み
img = data.astronaut()

# 画像の表示
plt.figure(figsize=(8, 6))
plt.imshow(img)
plt.title('Astronaut')
plt.axis('off')
plt.show()

# 画像情報の確認
print(f"形状: {img.shape}")
print(f"データ型: {img.dtype}")
print(f"値の範囲: {img.min()} ~ {img.max()}")

7.7 演習問題

演習 7-1: グレースケール変換の比較

演習 7-1

scikit-image のサンプル画像(coffee)を使って、グレースケール変換の違いを確認してください。

タスク:

  1. coffee 画像を読み込み、サイズと形状を確認
  2. 単純平均法でグレースケールに変換
  3. 加重平均法でグレースケールに変換
  4. 元のカラー画像、単純平均法、加重平均法の3つを1行3列で並べて表示

演習 7-2: ノイズ除去

演習 7-2

scikit-image のサンプル画像(camera)にガウシアンノイズを追加し、ガウシアンフィルタでノイズを除去してください。

タスク:

  1. camera 画像を読み込み
  2. ガウシアンノイズを追加(平均0、標準偏差25)
  3. ガウシアンフィルタでノイズ除去(sigma=2)
  4. 元の画像、ノイズあり、フィルタ結果を比較表示

演習 7-3: しきい値処理の実践

演習 7-3

scikit-image のサンプル画像(coins)を使って、しきい値処理を実践してください。

タスク:

  1. coins 画像を読み込み
  2. 固定しきい値で二値化
  3. 大津の二値化で自動的にしきい値を決定して二値化
  4. 元の画像、固定しきい値の結果、大津の二値化の結果を一つのグラフに表示

ヒント:

from skimage import data, filters
import matplotlib.pyplot as plt

# 画像の読み込み
coins = data.coins()

# 固定しきい値
threshold_fixed = 120
binary_fixed = coins > threshold_fixed

# 大津の二値化
threshold_otsu = filters.threshold_otsu(coins)
binary_otsu = coins > threshold_otsu

7.8 チャレンジ問題

チャレンジ: コイン検出の改善

scikit-image のサンプル画像(coins)には、明るいコインと暗いコインが混在しています。

from skimage import data
import matplotlib.pyplot as plt

coins = data.coins()
plt.imshow(coins, cmap='gray')
plt.title('Coins')
plt.axis('off')
plt.show()

課題: すべてのコインを適切に分離するにはどうすればよいか考えてみましょう。

ヒント:

  • 固定しきい値や大津の二値化だけでは、明るいコインと暗いコインを同時に検出するのは困難です
  • ガウシアンフィルタでノイズを除去してから二値化すると改善されるかもしれません
  • しきい値処理以外の手法(エッジ検出など)も組み合わせることができます
  • 画像を複数の領域に分割して、それぞれに異なるしきい値を適用する方法も考えられます

考えてみよう:

  1. なぜ単一のしきい値ではすべてのコインを検出できないのか?
  2. どのような前処理を行えば検出精度が向上するか?
  3. より高度な画像処理手法にはどのようなものがあるか?

7.9 まとめ

本章では、画像処理の基礎について学びました。

第 7 回のまとめ

画像データの基礎

  • デジタル画像は画素(ピクセル)の集まり
  • グレースケール(1チャンネル)とカラー画像(RGB: 3チャンネル)
  • Python では NumPy 配列として画像を扱う

画像の読み込みと表示

  • Pillow: 画像の読み込み・保存・基本操作
  • matplotlib: 画像の表示
  • NumPy: 画像データの数値計算

色空間

  • RGB: 赤・緑・青の3原色で表現(ニューラルネットワークの標準入力)
  • グレースケール: 明るさのみで表現(計算量削減、形状認識)

機械学習のための画像前処理(重要!)

  • リサイズ: ニューラルネットワークの固定サイズ入力に対応(224×224など)
  • 正規化: 0-255 → 0-1 の変換(学習の安定化、必須の処理)
  • 標準化: 平均0、標準偏差1への変換
  • データ拡張: 左右反転、回転、明るさ調整で訓練データを増やす

しきい値処理

  • 固定しきい値: 指定した値で二値化
  • 大津の二値化: ヒストグラムから最適なしきい値を自動決定
  • 物体と背景の分離、領域分割の前処理として重要

画像フィルタリング

  • ガウシアンフィルタ: ノイズ除去とエッジ保持のバランスが良い

機械学習で最も重要なポイント

  1. 正規化(0-1変換)は必須: img / 255.0
  2. リサイズ: モデルに合わせたサイズに統一
  3. データ拡張: 訓練データのみに適用
  4. グレースケール変換: 計算量削減が必要な場合

次回(第 8 回)は、古典的な特徴抽出手法(エッジ検出、HOG など)について学びます。