つれづれなる備忘録

日々の発見をあるがままに綴る

OpenCVの使い方18 ~ 画像勾配

 今回はOpenCVを用いた画像勾配処理としてラプラシアンフィルタとソベルフィルタにについて紹介する。

1. 画像勾配

画像勾配処理は輪郭やエッジ検出をする上で使われる。まず以下の解像チャートで画像勾配処理をする。

import cv2
import numpy as np
from matplotlib import pyplot as plt
from google.colab import files
uploaded_file = files.upload()
orig = cv2.imread(uploaded_file_name)
src = cv2.cvtColor(orig, cv2.COLOR_BGR2RGB)
gray = cv2.cvtColor(orig, cv2.COLOR_BGR2GRAY)
plt.imshow(orig, cmap='gray',vmax=255,vmin=0)
plt.title('Original')

"解像チャート"
解像チャート

2. ラプラシアンフィルタ

画像勾配処理として、ラプラシアンフィルタを適用してみる。ラプラシアンフィルタを適用するにはcv2.Laplacian(orig,cv2.CV_64F)とする。2つ目の引数のCV_64Fは出力画像のビット深度を指定するオプションでfloat64になっている。

laplacian = cv2.Laplacian(orig,cv2.CV_64F)
plt.imshow(laplacian,cmap='gray',vmax=255,vmin=0)
plt.title('Laplacian')

"ラプラシアンフィルタ"
ラプラシアンフィルタ

3. ソベルフィルタ

 次にソベルフィルタを適用するにはcv2.Sobel(src,cv2.CV_64F,1,0,ksize=5)とする。2つ目の引数はラプラシアンフィルタと同様に出力画像のビット深度で3つ目、4つ目は処理方向をしていする。3つ目の引数を1とするとX方向、4つ目の引数を1とするとY方向に処理される。X方向にソベルフィルタを適用するには3つ目と4つ目の引数は(1,0)、逆にY方向に適用するには(0,1)とする。最後のksizeカーネルサイズで小さいほどシャープな勾配になる。X方向のソベルフィルタは縦線、Y方向は横線の輪郭を上手く抽出できている。

sobelx = cv2.Sobel(src,cv2.CV_64F,1,0,ksize=5)
sobely = cv2.Sobel(src,cv2.CV_64F,0,1,ksize=5)
plt.figure(figsize=(8,16))
plt.subplot(1,2,1)
plt.imshow(sobelx,cmap='gray',vmax=255,vmin=0)
plt.title('Sobel X')
plt.subplot(1,2,2)
plt.imshow(sobely,cmap='gray',vmax=255,vmin=0)
plt.title('Sobel Y')

"ソベルフィルタ"
ソベルフィルタ

カーネルサイズをksize=3とした場合は、上の処理よりもシャープに見えている。

sobelx = cv2.Sobel(orig,cv2.CV_64F,1,0,ksize=3)
sobely = cv2.Sobel(orig,cv2.CV_64F,0,1,ksize=3)
plt.figure(figsize=(8,16))
plt.subplot(1,2,1)
plt.imshow(sobelx,cmap='gray',vmax=255,vmin=0)
plt.title('Sobel X')
plt.subplot(1,2,2)
plt.imshow(sobely,cmap='gray',vmax=255,vmin=0)
plt.title('Sobel Y')

"ソベルフィルタ(k=3)"
ソベルフィルタ(k=3)

最後に出力画像のビット深度をfloat64からuint8にした場合の違いを見る。uint8とするにはcv2.CV_8Uとすればよい。uint8は負の数は扱えず、白から黒に変化する負の勾配は0となるため、以下左側の輪郭は抽出できない

sobelx = cv2.Sobel(orig,cv2.CV_8U,1,0,ksize=5)
sobely = cv2.Sobel(orig,cv2.CV_8U,0,1,ksize=5)
plt.figure(figsize=(8,16))
plt.subplot(1,2,1)
plt.imshow(sobelx,cmap='gray',vmax=255,vmin=0)
plt.title('Sobel X')
plt.subplot(1,2,2)
plt.imshow(sobely,cmap='gray',vmax=255,vmin=0)
plt.title('Sobel Y')

"ソベルフィルタ(uint8)"
ソベルフィルタ(uint8)

4. カラー画像への適用

 上記ラプラシアンフィルタとソベルフィルタはカラー画像にもそのまま適用できる。以下カラー画像の適用結果のみを示す。

"カラー画像の処理"
カラー画像の処理

"カラー画像、ソベルフィルタ"
カラー画像、ソベルフィルタ

5. まとめ

 今回は画像勾配処理としてラプラシアンフィルタとソベルフィルタについて適用方法や処理結果について紹介した。