
目次
はじめに
前回は、Python(Anaconda)とOpenCVをインストールし、開発環境を構築しました。
今回は、実際にOpenCVを利用して画像処理を行っていこうと思います。
結果出力について
画像処理を行い、処理後の画像表示は主に以下の方法があります。
- ファイル出力
- 画面出力
- Jupyter Notebookを利用し、Notebbook上でインライン表示
それぞれについて、利用方法を下記します。
ファイル出力
cv2.imwriteメソッドにてファイルを出力し、結果ファイルを保存します。
import cv2 img = cv2.imread('input.jpg') cv2.imwrite('output.jpg',img)
画面出力
cv2.imshowメソッドにて画像表示ウィンドウを表示します。
imshowメソッドのみだと表示すると同時に終了してしまうため、キー入力による待機処理を使用します。
import cv2 img = cv2.imread('input.jpg') cv2.imshow('Window Name',img) cv2.waitKey(0) #キー入力待ちにして待機(0は無期限待機) cv2.destroyAllWindows() #表示した画像表示ウィンドウを破棄
JupyterNotebookの利用
Jupyter Notebookとはプログラムを実行し、実行結果を記録出来るツールです。
Anacondaをインストールすると同梱されており、Pythonに限らず多種の言語を使用出来ます。
JupyterNotebookで画像をインライン表示する場合は、以下の2通りがあります。
matplotlibを利用
matplotlibとはグラフを作成・表示するPythonのライブラリです。
%matplotlib inline import cv2 import matplotlib.pyplot as plt img = cv2.imread('input.jpg') plt.imshow(img)
IPython.displayモジュールを利用
import cv2 from IPython.display import Image Image('input.jpg')
今回はOpenCVでどのような画像処理が出来るのかを試すため、手軽なJupyter Notebook上でmatplotlibを利用した方法で表示していこうと思います。
基本的な画像処理
OpenCVで出来る基本的な画像処理を試していきます。
今回、利用した画像は以下のポストの写真です。
(※記事投稿のため、実際の画像よりも縮小されております。画像処理後の結果も縮小して表示しております。)

グレースケール
まずはグレースケール表示です。いわゆる白黒写真です。
明暗のみの情報になるので画像処理ではよく使用されます。
%matplotlib inline import cv2 import matplotlib.pyplot as plt gry_img = cv2.imread('input.jpg', 0) #imreadの第2引数に0を指定するとグレースケールで読み込み plt.gray() #matplotlibでグレースケールを使用する場合はグレースケールで読み込むように指定 plt.imshow(gry_img)

2値化
白と黒の2色のみで構成される画像に変換します。
cv2.thresholdメソッドを使用して、グレースケール画像から2値化します。
%matplotlib inline import cv2 import matplotlib.pyplot as plt gry_img = cv2.imread('input.jpg', 0) #グレースケールで読み込み ret, threshold_img = cv2.threshold(gry_img, 127, 255, cv2.THRESH_OTSU) #第2,3引数は閾値、第4引数は手法のフラグ plt.gray() #matplotlibでグレースケールを使用する場合はグレースケールで読み込むように指定 plt.imshow(threshold_img)

トリミング
画像の切り抜きを行います。
%matplotlib inline import cv2 import matplotlib.pyplot as plt img = cv2.imread('input.jpg') height = img.shape[0] #高さ width = img.shape[1] #幅 trim_img = img[100:height, 100:width] #高さ(上)・幅(左)を100pixelずつ除く trim_img = cv2.cvtColor(trim_img, cv2.COLOR_RGB2BGR) #matplotlibで表示する場合はRGBからBGRに変換 plt.imshow(trim_img)

(若干わかりづらいですが、左上のハイビスカスが無くなっています。)
リサイズ
画像のサイズを変更します。(縮小、拡大)
%matplotlib inline import cv2 import matplotlib.pyplot as plt img = cv2.imread('input.jpg') height = img.shape[0] #高さ width = img.shape[1] #幅 resize_img = cv2.resize(img, (int(width*0.5), int(height*0.5))) #サイズを×0.5で縮小 resize_img = cv2.cvtColor(resize_img, cv2.COLOR_RGB2BGR) #matplotlibで表示する場合はRGBからBGRに変換 plt.imshow(resize_img)

射影変換
ある平面を別の平面に射影する変換を行います。
よく書類などをカメラで撮影して、正面からの平面に変換しているのをよく見かけますね。
ここでは、numpyというPythonの数値計算ライブラリを使用します。
%matplotlib inline import cv2 import numpy as np import matplotlib.pyplot as plt img = cv2.imread('input.jpg') height, width, ch = img.shape #画像の大きさを取得 #points1の座標からpoints2の座標に変換するため、座標を指定 points1 = np.float32([[320,236],[1104,402],[12,332],[1053,640]]) points2 = np.float32([[0,0],[1250,0],[0,500],[1250,500]]) #透視変換の行列を求める M = cv2.getPerspectiveTransform(points1, points2) #画像を変換する dst = cv2.warpPerspective(img, M, (1250,500)) dst = cv2.cvtColor(dst, cv2.COLOR_RGB2BGR) #matplotlibで表示する場合はRGBからBGRに変換 plt.imshow(dst)

エッジ検出
画像の輪郭を検出します。
%matplotlib inline import cv2 import matplotlib.pyplot as plt img = cv2.imread('input.jpg', 0) #グレースケールで読み込み canny_img = cv2.Canny(img, 50, 110) #第2,3引数は閾値 plt.gray() plt.imshow(canny_img)

ぼかし
画像を平滑化させるガウシアンフィルタを用いて、画像にぼかし処理をいれます。
ガウシアンフィルタにはカーネルサイズおよび標準偏差を調整して、ぼかし具合を調整します。
どちらのパラメータも数値が大きくなるとぼかし具合が強くなります。
標準偏差に0を指定すると、カーネルサイズ(正の奇数を指定)から自動計算されます。
%matplotlib inline import cv2 import matplotlib.pyplot as plt img = cv2.imread('input.jpg') gauss_img = cv2.GaussianBlur(img, (15,15), 0) #第2引数はカーネル、第3引数は標準偏差 gauss_img = cv2.cvtColor(gauss_img, cv2.COLOR_RGB2BGR) #matplotlibで表示する場合はRGBからBGRに変換 plt.imshow(gauss_img)

(わかりにくいですがぼけてます)
モザイク処理
画像のモザイク処理は、画像を一旦縮小し、元の大きさに拡大することでモザイク処理を施すことが出来ます。
(実際は縮小時に画素の平均化等のアルゴリズムが発生している)
%matplotlib inline import cv2 import matplotlib.pyplot as plt img = cv2.imread('input.jpg') orgsize = img.shape[:2][::-1] img = cv2.resize(img, (int(orgsize[0]/20), int(orgsize[1]/20))) #画像を1/20に縮小 img = cv2.resize(img, orgsize) #画像を元のサイズに拡大 img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR) #matplotlibで表示する場合はRGBからBGRに変換 plt.imshow(img)

線の描画
line関数で画像に線を追加して描画します。
%matplotlib inline import cv2 import matplotlib.pyplot as plt img = cv2.imread('input.jpg') height = img.shape[0] #高さ width = img.shape[1] #幅 img = cv2.line(img, (0,0), (width,height), (0,0,255), 5) #第2引数が始点、第3引数が終点、第4引数が色、第5引数が線の太さ img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR) #matplotlibで表示する場合はRGBからBGRに変換 plt.imshow(img)

(左上から右下に線を入れています)
おわりに
今回はOpenCVでどのような画像処理が出来るのか、基本的な処理を見ていきました。
次回は、顔検出分類器を使用して顔検出をして遊んでいきたいと思います。