【Python】OpenCVでの画像の勾配 – Sobel(), Laplacian()

Pythonの応用
スポンサーリンク

OpenCVを使ったPythonでの画像処理について、ここでは画像の勾配を検出する方法を見ていきます。

画像の勾配とは濃度勾配とも言われ、各画素の値の変化の度合を示します。これは画素の位置を変数とした場合の微分値であると言われますが、ここではその数学的な厳密な意味には触れませんが、エッジのような個所を表す画像と見なしてオブジェクトの検出や認識、輪郭追跡の前処理などに利用されます。

ここでは、cv2.Sobel()、cv2.Laplacian()などを見ていきましょう。

スポンサーリンク

勾配検出フィルタ- cv2.Sobel()、cv2.Laplacian()

いつものように各種ライブラリをインポートします。jupyter notebookを使って見ていきます。

import cv2
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline

ここは、お決まりのライブラリのインポートです。

画像を読み込みます。

img = cv2.imread('images/stairs.jpg',0)

imagesフォルダにstairs.jpgを用意して、これをimread()で読み込んでいます。0を指定してグレースケールで読み込みます。

読み込んだ画像を表示する関数を定義してみます。

def display_img(img):
    fig = plt.figure(figsize=(8,6))
    ax = fig.add_subplot(111)
    ax.imshow(img,cmap='gray')

figure()でアスペクト比を指定し、add_subplot()で111を指定して画像を左上の端を基準に表示します。

display_img(img)

画像を表示してみます。

この画像を基準に勾配処理をしていきます。

次のように処理してみます。

sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=5)
sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=5)
laplacian = cv2.Laplacian(img,cv2.CV_64F)

cv2.Sobel()、cv2.Laplacian()をそれぞれ処理しています。以下で見ていきましょう。

Sobel()

Sobel()関数はノイズ耐性がある処理です。上の処理の第2引数のcv2.CV_64Fは画素の型の種類を与えています。ここでは64ビットの倍精度実数浮動小数点数です。

勾配を計算する方向は、引数yorderとxorderで指定します。第3引数(yorder)を1にするとx方向の勾配、第4引数(xorder)を1にするとy方向の勾配を計算します。第5引数(ksize)に勾配を計算するカーネルのサイズを指定できます。ここでは5を指定しています。

display_img(sobelx)
display_img(sobely)

それぞれ表示するとこうなります。

第3引数を1にした場合。

第4引数を1にした場合。

Laplacian()

Laplacian()関数は、Sobel()を使って計算されるx、yに関する2次微分を足し合わせることで処理すると数学的には説明されますが、細かい意味合いには立ち入りません。

上で処理をした結果だけ見ておきましょう。

display_img(laplacian)

表示するとこうなります。

スポンサーリンク

処理を組み合わせる

これまで、別のところでも色々な処理を見て来ました。ここで、これらの処理を組み合わせて使ってみることにしましょう。

画像を合成する

ここまで扱ったことと、addWeighted()を使って合成してみます。

addWeighted()についてはこちらを参照してください。

【Python】OpenCVで画像を合成する - addWeighted, bitwise演算, ROI
Pythonに画像処理ライブラリのOpenCVを使って、2つの画像を合成したり重ねたりする方法を見ていきたいと思います。addWeighted()での合成や、関心領域(ROI)とbitwise演算を使った合成の方法を見ていきます。

このように合成するコードを書いてみました。

blended = cv2.addWeighted(src1=sobelx,alpha=0.5,src2=sobely,beta=0.5,gamma=0)
display_img(blended)

addWeighted()を使って、上で求めたsobelxとsobelyを合成しています。

モルフォロジー勾配

次はモルフォロジー勾配と組み合わせてみます。

モルフォロジー勾配の処理についてはこちらを参照してください。

【Python】OpenCVのモルフォロジー変換 - erode(), dilate(), morphologyEx()
OpenCVを使ったPythonでの画像処理について、膨張処理、収縮処理のモルフォロジー変換を扱います。白黒画像のような二値画像を対象に簡単な処理を行います。erode()、dilate()、morphologyEx()を使ってみましょう。

morphologyEX()で上の合成で作ったblendedを処理してみます。

kernel = np.ones((4,4),np.uint8)
gradient = cv2.morphologyEx(blended,cv2.MORPH_GRADIENT,kernel)
display_img(gradient)

カーネルを4×4にして、cv2.MORPH_GRADIENTでモルフォロジー勾配処理を行います。

2値化 – 閾値処理

今度は画像の2値化処理を組み合わせてみます。

2値化、閾値処理についてははこちらを参照してください。

【Python】OpenCVで画像の2値化 - 閾値処理 threshold()
OpenCVを利用したPythonでの画像の2値化処理を見ていきます。2値化処理によって画像の特徴的な部分を取り出すことができますが、そのためには最適な閾値処理が必要です。閾値処理には単純な閾値処理と適応的閾値処理があります。

threshold()を使って色々と処理してみましょう。

ret,th1 = cv2.threshold(img,100,255,cv2.THRESH_BINARY)
display_img(th1)

ここでは処理する画像にimgを使ってみます。閾値をここでは100を指定してみます。2値化の最大値を255として、THRESH_BINARYで処理してみます。

次は、上で処理した画像のgradientを使ってやってみましょう。

ret,th1 = cv2.threshold(gradient,200,255,cv2.THRESH_BINARY_INV)
display_img(th1)

閾値をここでは200にして、THRESH_BINARY_INVで処理してみます。

今度は、上で処理したblendedを使ってみます。

ret,th1 = cv2.threshold(blended,100,255,cv2.THRESH_BINARY_INV)
display_img(th1)

閾値を100に設定し、THRESH_BINARY_INVで処理してみます。

以上、画像の勾配を色々な処理と組み合わせてみました。

スポンサーリンク

最後に

ここではOpenCVを使ったPythonでの画像処理について、画像の勾配を検出して処理する方法を扱いました。

画像の勾配とは濃度勾配とも言われ、エッジのような個所を表す画像と見なしてオブジェクトの検出や認識、輪郭追跡の前処理などに利用されます。

数学的な細かい処理はすっ飛ばして動きだけを扱いました。細かい数学的意味などは検索などで確認してください。(初心者にとっては、ここで説明があるとややこしいだけですよね)

ここでは、cv2.Sobel()、cv2.Laplacian()の処理と、以前に行った処理との組み合わせを見てきました。

ここで扱った処理は、数字の画像認識などにも繋がる処理ですので覚えておきましょう。

タイトルとURLをコピーしました