Python : 膨張(dilate)、収縮(erode)処理

最近は、ソフトウェアよりもソフトを動すためのハード関連の

図面書いたり、電気関連のことをやったりと

ソフトをあまりやっていなかったのもあり、更新していませんでした。

会社でリストラやりそうな雰囲気があり、

仕事のモチベーションが下がっているのもありますけどね、

そんな中来月から組合執行委員になるのですが・・・

と色々あるのですが、単純にさぼっていました。

 

前置きが長くなりましたが、膨張、収縮の処理についてです。

基本はノイズ除去の際に使う処理なのですが、ちょうどよい画像がないので、

いつものlenaさんでやります。

f:id:Kangkang1981:20200310225916j:plain

今回使うモジュールはいつものopencvとnumpyです。

numpyではカーネルの指定をします。

import cv2

import numpy as np

 

まずこの処理は二極化された画像しか使えないため、

今回は大津氏のプログラムを使い二極化画像を使います。

 frame = cv2.imread('lena.jpg')
#白黒画像を作成
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
#二極化、大津氏プログラム
ret,th_otsu = cv2.threshold(gray,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)

これが今回使う画像です。

f:id:Kangkang1981:20200626213814j:plain

 

ここから処理になります。

まずカーネル(構造的要素)を決めます。

正直細かいことはよくわかっていないのですが、

大まかには膨張、縮小する際の範囲決めです。

今回はカーネルを(3,3)と(5,5)の場合で比較してみます。

カーネルはこのように書きます。

kernel = np.ones*1

 

収縮処理

f:id:Kangkang1981:20200626214755j:plain

膨張処理

f:id:Kangkang1981:20200626214820j:plain

 

このようにカーネルの範囲が大きくなると、収縮の際は黒の範囲が、

膨張の時は白が増えるのがわかりますね。

 

プログラムの詳細は下記です。

import cv2
import numpy as np

frame = cv2.imread('lena.jpg')
#白黒画像を作成
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
#二極化、大津氏プログラム
ret,th_otsu = cv2.threshold(gray,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)

#カーネルサイズの決定
kernel = np.ones((3,3),np.uint8)
#縮小処理
erosion_th = cv2.erode(th_otsu,kernel)
#膨張処理
dilation_th = cv2.dilate(th_otsu,kernel)

#カーネルサイズを5にすると
kernel5 =  np.ones((5,5),np.uint8)
#縮小処理 カーネル5
erosion5_th = cv2.erode(th_otsu,kernel5)
#膨張処理 カーネル5
dilation5_th = cv2.dilate(th_otsu,kernel5)

#画像を横に連結 左がカーネル3、右がカーネル5
frame_erosion = cv2.hconcat([erosion_th,erosion5_th])
frame_dilation = cv2.hconcat([dilation_th,dilation5_th])

#画像の書き込み
cv2.imwrite('th_otsu.jpg',th_otsu)
cv2.imwrite('erosion.jpg',frame_erosion)
cv2.imwrite('dilation_th.jpg',frame_dilation)

#画像の表示
cv2.imshow('moto',th_otsu)
cv2.imshow('erosion',frame_erosion)
cv2.imshow('dilation_th',frame_dilation)

#キー入力を待つ
cv2.waitKey(0)
#全ての開いたウインドウ閉じる
cv2.destroyAllWindows()

今までにpythonについて書いた記事はここにリンクを貼ってあります。

興味があればぜひご覧ください。

*1:3,3),np.uint8)

kernel5 = np.ones((5,5),np.uint8)

 

縮小処理はこのように書きます。
erosion_th = cv2.erode(th_otsu,kernel)

erosion5_th = cv2.erode(th_otsu,kernel5)


膨張処理は
dilation_th = cv2.dilate(th_otsu,kernel)

dilation5_th = cv2.dilate(th_otsu,kernel5)

 

画像はこのようになります(左側が(3,3) 、右側が(5,5