Python
 Computer >> コンピューター >  >> プログラミング >> Python

Pythonで学ぶ畳み込み(Convolution)の基礎:画像から特徴を抽出する仕組みと実装

本記事では、Python 3.x(またはそれ以前のバージョン)における「畳み込み(Convolution)」について解説します。畳み込みは、ニューラルネットワークや画像の特徴抽出において中心的な役割を果たす基本的な操作です。

推奨環境 − Jupyter Notebook
前提条件 − NumPy および Matplotlib がインストール済みであること

インストール方法

必要なライブラリが未インストールの場合は、以下のコマンドで導入できます。

>>> pip install numpy
>>> pip install matplotlib

畳み込みとは

畳み込みとは、画像に対して「カーネル」と呼ばれる小さな行列を、スライディングウィンドウのように順番に適用していくことで、画像から特徴を抽出する操作です。カーネル内に設定する値によって、画像の中から特定のパターンや特徴を選択的に検出することができます。

本記事では、適切なカーネルを用いて、画像内の水平方向のエッジ(端点)垂直方向のエッジ(端点)を検出する方法を学びます。それでは、実際のコードを見ていきましょう。

実装例

import numpy as np
from matplotlib import pyplot

# 画像の初期化
img1 = np.array([np.array([100, 100]), np.array([80, 80])])
img2 = np.array([np.array([100, 100]), np.array([50, 0])])
img3 = np.array([np.array([100, 50]), np.array([100, 0])])

# 水平方向の端点を検出するためのカーネル
coordinates_horizontal = np.array([np.array([3, 3]), np.array([-3, -3])])
print(coordinates_horizontal, 'は水平方向の端点を検出するためのカーネルです')

# 垂直方向の端点を検出するためのカーネル
coordinates_vertical = np.array([np.array([3, -3]), np.array([3, -3])])
print(coordinates_vertical, 'は垂直方向の端点を検出するためのカーネルです')

# 要素ごとの乗算を行った後に総和を取る関数
def apply_coordinates(img, coordinates):
    return np.sum(np.multiply(img, coordinates))

# img1 の可視化
pyplot.imshow(img1)
pyplot.axis('off')
pyplot.title('sample 1')
pyplot.show()

# 画像1 の水平・垂直特徴スコアを確認
print('水平方向エッジの特徴スコア:', apply_coordinates(img1, coordinates_horizontal))
print('垂直方向エッジの特徴スコア:', apply_coordinates(img1, coordinates_vertical))

# img2 の可視化
pyplot.imshow(img2)
pyplot.axis('off')
pyplot.title('sample 2')
pyplot.show()

# 画像2 の水平・垂直特徴スコアを確認
print('水平方向エッジの特徴スコア:', apply_coordinates(img2, coordinates_horizontal))
print('垂直方向エッジの特徴スコア:', apply_coordinates(img2, coordinates_vertical))

# img3 の可視化
pyplot.imshow(img3)
pyplot.axis('off')
pyplot.title('sample 3')
pyplot.show()

# 画像3 の水平・垂直特徴スコアを確認
print('水平方向エッジの特徴スコア:', apply_coordinates(img3, coordinates_horizontal))
print('垂直方向エッジの特徴スコア:', apply_coordinates(img3, coordinates_vertical))

実行結果

各サンプル画像に対して、水平用カーネルと垂直用カーネルを適用した結果、以下のような特徴スコアが得られます。

  • sample 1:水平スコア 120 / 垂直スコア 0 → 明暗差が小さく、ほぼ平坦な画像として判定される
  • sample 2:水平スコア 450 / 垂直スコア 150 → 水平方向のエッジが強く検出される
  • sample 3:水平スコア 150 / 垂直スコア 450 → 垂直方向のエッジが強く検出される

このように、スコアの絶対値が大きいほど、そのカーネルが対応する方向の特徴(エッジ)が画像内に強く存在していることを意味します。実際のCNN(畳み込みニューラルネットワーク)では、この操作を多数のカーネルに対して繰り返し行うことで、輪郭やテクスチャなど、より複雑な特徴を段階的に学習していきます。

まとめ

本記事では、Python 3.x を使った畳み込みの基本概念と、NumPy・Matplotlib を利用したシンプルな実装方法を紹介しました。カーネルの値を変えることで検出できる特徴が変わるという点は、画像認識や深層学習を理解する上で非常に重要な基礎知識です。ぜひ自身でもさまざまなカーネルを試してみてください。

  1. JavaScriptのslice()メソッドとは?配列から要素を取り出す使い方を実例で解説

    JavaScriptのslice()メソッドは、大きな配列の中から選択した範囲の要素を抜き出し、新しい配列として返すメソッドです。最大の特徴は、元の配列を一切変更しない(非破壊的な操作)という点にあります。そのため、元データを保持したまま部分的なコピーを作りたい場合に非常に便利です。 slice()メソッドの基本構文 arr.slice(start, end) start:取り出しを開始するインデックス番号(省略可・デフォルトは0) end:取り出しを終了する位置の直前のインデックス番号(省略可・デフォルトは配列の末尾まで)。endで指定した要素自体は結果に含まれない点に注意してください。

  2. C#の多次元配列とは?2次元配列の宣言方法と使い方を実例付きで解説

    C#では、多次元配列を扱うことができます。int型の2次元配列は、次のように宣言します。int[] a;多次元配列の中で最もシンプルな形式が2次元配列です。2次元配列とは、1次元配列を要素として持つ配列、すなわち「配列の配列」のような構造をイメージすると分かりやすいでしょう。例えば、次の図は3行4列の2次元配列を表しています。多次元配列の使用例ここからは、実際にC#で多次元配列を操作するサンプルコードを見ていきましょう。以下の例では、5行2列の2次元配列を宣言・初期化し、入れ子になったforループですべての要素を出力します。using System; namespace ArrayApplic