はじめに
画像処理は、デジタル画像を操作してその内容を解析、変換、編集する技術です。この技術は、写真編集、医療画像解析、自動運転車の視覚システムなど、さまざまな分野で利用されています。このシリーズは、実際の画像処理技術をPythonで実装することで、理論と実践を組み合わせた学習を目指しています。この記事では、エッジ検出に使われるLaplacian(ラプラシアン)フィルタと、輪郭を浮き出しにするEmbossフィルタについて解説します。これらのフィルタは、画像処理の基本的なツールとして広く利用されています。初心者の方でも理解できるように、各ステップを丁寧に解説し、Pythonの関数を使わずに実装する方法を紹介します。この記事では、画像処理100本ノックで用意されている「imori_noise.jpg」をダウンロードしてください。ダウンロードのURLはこちらです。
画像処理100本ノック 017. Laplacianフィルタ
Laplacianフィルタを実装せよ。
画像処理100本ノック
Laplacian(ラプラシアン)フィルタとは輝度の二次微分をとることでエッジ検出を行うフィルタである。
方針
Laplacianフィルタは、画像の輝度の二次微分を計算することでエッジを検出するフィルタです。二次微分は、画像の輝度の変化の速さを計算するもので、エッジ部分では大きな値を持ちます。デジタル画像は離散データであるため、画像の輝度の変化(一次微分)を次のように計算できます。
- x方向の一次微分:
- y方向の一次微分:
次に、これらの一次微分を使って二次微分を計算します。
- x方向の二次微分:
- y方向の二次微分:
これらを組み合わせると、ラプラシアンフィルタは次のように定義されます。
この操作を画像に適用するために、次のカーネルが使われます:
このカーネルは、中心のピクセルの値に対して、その上下左右のピクセルの値を足し合わせ、中心のピクセルの値を4倍したものを引くことで、二次微分を計算しています。Laplacianフィルタを適用するためには、以下の手順を踏みます:
- 画像を読み込む。
- 画像にゼロパディングを施し、画像の境界部分の処理を行う。
- 各ピクセルに対してLaplacianフィルタを適用し、エッジを強調する。
実装手順
- 画像の読み込み:
- 画像を読み込みます。
- ゼロパディング:
- 画像にゼロパディングを施し、カーネルの適用範囲を確保します。
- Laplacianフィルタを適用する:
- 各ピクセルに対してLaplacianフィルタを適用し、エッジを強調します。
解答と実行結果
まず、必要なライブラリをインポートし、画像をカラーで読み込みます。次に、画像をグレースケールに変換します。ここでは、cv2.cvtColor関数を使用して、画像をBGRからグレースケールに変換します。次に、画像の境界部分を処理するためにゼロパディングを施します。ここでは、画像の周囲に1ピクセルのゼロパディングを追加します。
その後、Laplacianフィルタのカーネルを定義します。このカーネルを使用して各ピクセルに対して二次微分を計算します。Laplacianフィルタを適用するための関数apply_laplacian_filterを定義します。この関数は、各ピクセルに対してカーネルを適用し、エッジを強調します。
最後に、apply_laplacian_filter(padded_img, kernel_laplacian)を使用してLaplacianフィルタを適用し、フィルタを適用した画像を表示します。
import cv2
import numpy as np
import matplotlib.pyplot as plt
# 画像の読み込み(カラー)
img = cv2.imread('imori.jpg')
# グレースケールに変換
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# ゼロパディング
pad_size = 1
padded_img = np.pad(gray, pad_size, mode='constant')
# Laplacianフィルタのカーネル
kernel_laplacian = np.array([[0, 1, 0], [1, -4, 1], [0, 1, 0]])
# Laplacianフィルタの適用
def apply_laplacian_filter(img, kernel):
output = np.zeros_like(img)
for i in range(img.shape[0] - 2):
for j in range(img.shape[1] - 2):
region = img[i:i+3, j:j+3]
output[i, j] = np.abs(np.sum(kernel * region))
return output
output_laplacian = apply_laplacian_filter(padded_img, kernel_laplacian)
# 結果の表示
plt.imshow(output_laplacian, cmap='gray')
plt.title('Laplacian Filter Output')
plt.show()
このコードを実行すると、次のような結果(右の画像)が得られます。
画像処理100本ノック 018. Embossフィルタ
Embossフィルタを実装せよ。
画像処理100本ノック
Embossフィルタとは輪郭部分を浮き出しにするフィルタで、次式で定義される。
方針
Embossフィルタは、画像の輪郭部分を浮き出しにするフィルタです。このフィルタは、画像の隣接するピクセルの輝度差を強調することで、浮き出し効果を生成します。Embossフィルタのカーネルは、画像の輝度の差を計算するために設計されています。具体的には、以下のカーネルを使用します:
このカーネルは、中心のピクセルの輝度を基準にして、その周囲のピクセルの輝度差を計算し、浮き出し効果を生成します。Embossフィルタを適用するためには、以下の手順を踏みます:
- 画像を読み込む。
- 画像にゼロパディングを施し、画像の境界部分の処理を行う。
- 各ピクセルに対してEmbossフィルタを適用し、輪郭を浮き出しにする。
実装手順
- 画像の読み込み:
- 画像を読み込みます。
- ゼロパディング:
- 画像にゼロパディングを施し、カーネルの適用範囲を確保します。
- Embossフィルタを適用する:
- 各ピクセルに対してEmbossフィルタを適用し、輪郭を浮き出しにします。
解答と実行結果
まず、必要なライブラリをインポートし、画像をカラーで読み込みます。次に、画像をグレースケールに変換します。
次に、Embossフィルタのカーネルを定義します。このカーネルを使用して各ピクセルに対して輝度差を計算し、浮き出し効果を生成します。Embossフィルタを適用するための関数apply_emboss_filterを定義します。この関数は、各ピクセルに対してカーネルを適用し、輪郭を浮き出しにします。
最後に、apply_emboss_filter(padded_img, kernel_emboss)を使用してEmbossフィルタを適用し、フィルタを適用した画像を表示します。
import cv2
import numpy as np
import matplotlib.pyplot as plt
# 画像の読み込み(カラー)
img = cv2.imread('imori.jpg')
# グレースケールに変換
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# ゼロパディング
pad_size = 1
padded_img = np.pad(gray, pad_size, mode='constant')
# Embossフィルタのカーネル
kernel_emboss = np.array([[-2, -1, 0], [-1, 1, 1], [0, 1, 2]])
# Embossフィルタの適用
def apply_emboss_filter(img, kernel):
output = np.zeros_like(img)
for i in range(img.shape[0] - 2):
for j in range(img.shape[1] - 2):
region = img[i:i+3, j:j+3]
output[i, j] = np.clip(np.sum(kernel * region), 0, 255)
return output
output_emboss = apply_emboss_filter(padded_img, kernel_emboss)
# 結果の表示
plt.imshow(output_emboss, cmap='gray')
plt.title('Emboss Filter Output')
plt.show()
このコードを実行すると、次のような結果(右の画像)が得られます。
最後に
この記事では、LaplacianフィルタとEmbossフィルタについて解説し、それぞれのカーネルの導出方法と適用手順を紹介しました。Laplacianフィルタはエッジ検出に、Embossフィルタは輪郭を浮き出しにする効果があります。これらのフィルタを理解し、使いこなすことで、画像処理の幅を広げることができます。次回は、さらに高度なフィルタについて学びましょう。
私の経歴などについては以下の記事から確認することができます!
ブログランキングに参加しています。ぜひクリックで応援お願いします
コメント