Python + OpenCV4プログラミングの学習(4)〜アフィン変換〜
本記事はOpenCVによるアフィン変換を行ったときの備忘録である。
アフィン変換とは...
図形を回転させたり引き延ばしたりする変換 ja.wikipedia.org
事前準備
以下の記事で仮想環境opencvEnvを構築していることを前提とする。 kawakeee.hatenablog.com
また、任意の画像を用意しておく。今回はLenna.jpgを用意した。
フリップ
以下のコードを写経しflip.pyのファイルを作成。
import cv2 try: img = cv2.imread('img/Lenna.jpg') if img is None: print('ファイルを読み込めません') import sys sys.exit() # 画像を上下反転させる dst = cv2.flip(img, 0) cv2.imwrite('img/flip0.jpg', img) cv2.imshow('dst1', dst) # 画像を左右反転させる dst = cv2.flip(img, 1) cv2.imwrite('img/flip1.jpg', img) cv2.imshow('dst2', dst) # 画像を両軸反転させる dst = cv2.flip(img, -1) cv2.imwrite('img/flip2.jpg', img) cv2.imshow('dst3', dst) cv2.waitKey(0) cv2.destroyAllWindows() except: import sys print("Error:", sys.exc_info()[0]) print(sys.exc_info()[1]) import traceback print(traceback.format_tb(sys.exc_info()[2]))
- cv2.flip(...):画像をフリップ(反転)させる
使用例:cv2.flip(img, 0)
引数は、順に(対象画像データ, フリップ方向)を表す。 以下のように、フリップ方向の値により反転軸を指定できる。
フリップ方向の値 | 反転方向 |
---|---|
0に等しい | 上下反転 |
正 | 左右反転 |
負 | 両軸反転 |
実行結果
(opencvEnv)$ python filp.py
指定フォルダ配下にフリップされた画像が生成されていることを確認。
リサイズ
以下のコードを写経しresize.pyのファイルを作成。
import cv2 try: img = cv2.imread('img/Lenna.jpg') if img is None: print('ファイルを読み込めません') import sys sys.exit() SCALE = 0.5 SCALE2 = 1.62 # 画像の高さ・幅を取得 height = img.shape[0] width = img.shape[1] # 画像を半分(0.5乗じる)のサイズにリサイズ dst = cv2.resize(img, (int(width*SCALE), int(height*SCALE))) cv2.imwrite('img/resize0.5.jpg', dst) cv2.imshow('dst1', dst) # 画像を1.62乗じてリサイズ dst = cv2.resize(img, (int(width*SCALE2), int(height*SCALE2))) cv2.imwrite('img/resize1.62.jpg', dst) cv2.imshow('dst2', dst) # 画像を縦を圧縮してリサイズ dst = cv2.resize(img, (400, 200)) cv2.imwrite('img/resize400*200.jpg', dst) cv2.imshow('dst3', dst) cv2.waitKey(0) cv2.destroyAllWindows() except: import sys print("Error:", sys.exc_info()[0]) print(sys.exc_info()[1]) import traceback print(traceback.format_tb(sys.exc_info()[2]))
変数SCALE
を用意して半分(0.5をかける)のサイズにリサイズしている。
- cv2.resize(...):画像をリサイズする
使用例:cv2.resize(img, (400, 200))
引数は、順に(対象画像,幅, 高さ)を表す。実行結果
(opencvEnv)$ python resize.py
指定フォルダ配下にリサイズされた画像が生成されていることを確認。
回転
以下のコードを写経しrotate.pyのファイルを作成。
import cv2 try: img = cv2.imread('img/Lenna.jpg') if img is None: print('ファイルを読み込めません') import sys sys.exit() # 画像の高さ・幅を取得 height = img.shape[0] width = img.shape[1] # 回転原点座標を生成 center = (int(width/2), int(height/2)) # 回転変換行列の生成 (回転原点座標, 回転角度, スケーリング値) affin_trans = cv2.getRotationMatrix2D(center, 33.0, 1.0) # 回転変換処理 (対象画像, 回転変換行列, 出力配列(画像サイズの指定)) dst = cv2.warpAffine(img, affin_trans, (width, height)) cv2.imwrite('img/rotate033.jpg', dst) cv2.imshow('dst1', dst) affin_trans = cv2.getRotationMatrix2D(center, 110.0, 1.2) dst = cv2.warpAffine(img, affin_trans, (width, height), flags=cv2.INTER_CUBIC) cv2.imwrite('img/rotate110.jpg', dst) cv2.imshow('dst2', dst) cv2.waitKey(0) cv2.destroyAllWindows() except: import sys print("Error:", sys.exc_info()[0]) print(sys.exc_info()[1]) import traceback print(traceback.format_tb(sys.exc_info()[2]))
順に、対象画像を反時計周りの方向に33°、110°回転させる。
- cv2.getRotationMatrix2D(...):回転変換行列の生成
使用例:cv2.getRotationMatrix2D(center, 33.0, 1.0)
引数は、順に(回転原点座標,回転角度,スケーリング値)を表す。 - cv2.warpAffine(...):画像のアフィン変換を実行
使用例:cv2.warpAffine(img, affin_trans, (width, height))
引数は、順に(対象画像,変換行列,出力配列(画像サイズ))を表す。
実行結果
(opencvEnv)$ python rotate.py
指定フォルダ配下に回転された画像が生成されていることを確認。
透視投影
以下のコードを写経しperspective.pyのファイルを作成。
import cv2 import numpy as np try: # (225 * 225)の画像 img = cv2.imread('img/Lenna.jpg') if img is None: print('ファイルを読み込めません') import sys sys.exit() # 画像の列・行の大きさを取得 rows,cols = img.shape[:2] x0 = cols/4 x1 = (cols*3)/4 y0 = rows/4 y1 = (rows*3)/4 # 入力の座標を指定 list_srcs = np.float32([ [x0, y0], [x0, y1], [x1, y1], [x1, y0] ]) # pattern-0 x_margin = cols/10 y_margin = rows/10 # 出力の座標を指定(台形) list_dsts = np.float32([ [x0+x_margin, y0+y_margin], list_srcs[1], list_srcs[2], [x1-x_margin, y0+y_margin] ]) # 透視変換行列の生成 (入力座標, 出力座標) perspective_matrix = cv2.getPerspectiveTransform(list_srcs, list_dsts) # 画像の透視投影処理 (対象画像, 透視変換行列, 出力配列(画像サイズの指定)) dst = cv2.warpPerspective(img, perspective_matrix, (cols, rows)) cv2.imwrite('img/dst0.jpg', dst) cv2.imshow('dst0', dst) #pattern-1 x_margin = cols/8 y_margin = rows/8 list_dsts = np.float32([list_srcs[0],list_srcs[1],[x1-x_margin, y1-y_margin],[x1-x_margin, y0+y_margin]]) perspective_matrix = cv2.getPerspectiveTransform(list_srcs,list_dsts) dst = cv2.warpPerspective(img, perspective_matrix, (cols, rows)) cv2.imwrite('img/dst1.jpg', dst) cv2.imshow('dst1', dst) #pattern-2 x_margin = cols/6 y_margin = rows/6 list_dsts = np.float32([[x0+x_margin, y0+y_margin],list_srcs[1],[x1-x_margin, y1-y_margin],list_srcs[3]]) perspective_matrix = cv2.getPerspectiveTransform(list_srcs,list_dsts) dst = cv2.warpPerspective(img, perspective_matrix, (cols, rows)) cv2.imwrite('img/dst2.jpg', dst) cv2.imshow('dst2', dst) cv2.waitKey(0) cv2.destroyAllWindows() except: import sys print("Error:", sys.exc_info()[0]) print(sys.exc_info()[1]) import traceback print(traceback.format_tb(sys.exc_info()[2]))
list_srcs
に入力座標、list_dsts
に出力座標を指定し、3パターンの透視投影を実行。
- cv2.getPerspectiveTransform(...):透視変換行列の生成
使用例:cv2.getPerspectiveTransform(list_srcs, list_dsts)
引数は、順に(入力座標,出力座標)を表す。返戻値は引数に対する透視変換行列。 - cv2.warpPerspective(...):画像の透視投影を実行
使用例:cv2.warpPerspective(img, perspective_matrix, (cols, rows))
引数は、順に(対象画像,透視変換行列,出力配列(画像サイズ))を表す。
実行結果
(opencvEnv)$ python perspective.py
指定フォルダ配下に透視投影された画像が生成されていることを確認。
トリミング
以下のコードを写経しtrimming.pyのファイルを作成。
import cv2 try: img = cv2.imread('img/Lenna.jpg') if img is None: print('ファイルを読み込めません') import sys sys.exit() # 画像の高さ・幅を取得 height = img.shape[0] width = img.shape[1] # imgをスライス処理してトリミング dst = img[40:height, 40:width] cv2.imwrite('img/Trimming.jpg', dst) cv2.imshow('dst0', dst) cv2.waitKey(0) cv2.destroyAllWindows() except: import sys print("Error:", sys.exc_info()[0]) print(sys.exc_info()[1]) import traceback print(traceback.format_tb(sys.exc_info()[2]))
トリミングはimgに対してスライスする事で可能。元画像の上部、左側の40pxを除去させる。
実行結果
(opencvEnv)$ python trimming.py
指定フォルダ配下にトリミングされた画像が生成されていることを確認。
まとめ
- cv2.flip(...):画像をフリップ(反転)させる
- cv2.getRotationMatrix2D(...):回転変換行列の生成
- cv2.warpAffine(...):画像のアフィン変換を実行
- cv2.getPerspectiveTransform(...):透視変換行列の生成
- cv2.warpPerspective(...):画像の透視投影を実行
ソースコード
Python + OpenCV4プログラミングの学習(3)〜グラフィックス〜
本記事はOpenCVによるグラフィックスを行ったときの備忘録である。
事前準備
以下の記事で仮想環境opencvEnvを構築していることを前提とする。 kawakeee.hatenablog.com
円を描く
以下のコードを写経しcircle.pyのファイルを作成。
import numpy as np import cv2 # 画像データ(400×400 px)の生成 img = np.zeros((400, 400, 3), np.uint8) # 円の描写 (対象画像データ, 中心座標, 半径, 色情報, 円の太さ) cv2.circle(img, (200, 200), 50, (255, 0, 0) ,1) cv2.imwrite('img/circle1.jpg', img) cv2.imshow('img1', img) img = np.zeros((400, 400, 3), np.uint8) # 半径 色 太さ を変更 cv2.circle(img, (200, 200), 100, (0, 255, 0) ,3) cv2.imwrite('img/circle2.jpg', img) cv2.imshow('img2', img) img = np.zeros((400, 400, 3), np.uint8) # 半径 色 太さ を変更 cv2.circle(img, (200, 200), 150, (0, 0, 255) ,-1) cv2.imwrite('img/circle3.jpg', img) cv2.imshow('img3', img) cv2.waitKey(0) cv2.destroyAllWindows()
- cv2.circle(...):円の描写
使用例:cv2.circle(img, (200, 200), 50, (255, 0, 0) ,1)
引数は、順に(対象画像データ, 中心座標, 半径, 色情報, 円の太さ)を表す。
cv2.waitKey(0)
によってキーが押されるまで以降のコードは実行されない。何かのキーが押されるとcv2.destroyAllWindows()
で全てのウィンドウが閉じられてプログラムが終了する。
実行確認
(opencvEnv)$ python circle.py
指定フォルダ配下に画像が生成されていることを確認。
また、cv2.imshow
によってウィンドウで画像が表示される事を確認。
線を描く
次に、任意の画像に対して線を描く。今回はLenna.jpgを用意した。
以下のコードを写経しlines_on_image.pyのファイルを作成。
import cv2 try: img = cv2.imread('img/Lenna.jpg') if img is None: print('ファイルを読み込めません') import sys sys.exit() # 画像に対して線を描く (対象画像, 始点, 終点, 色) cv2.line(img, (50, 50), (200, 50), (255, 0, 0)) # 追加して太さも指定 cv2.line(img, (50, 100), (200, 100), (0, 255, 0), 5) cv2.imwrite('img/LinesOnImage.jpg', img) cv2.imshow('img', img) cv2.waitKey(0) cv2.destroyAllWindows() except: import sys print("Error:", sys.exc_info()[0]) print(sys.exc_info()[1]) import traceback print(traceback.format_tb(sys.exc_info()[2]))
- cv2.line(...):線の描写
使用例:cv2.line(img, (50, 50), (200, 50), (255, 0, 0)) 引数は、順に(対象画像, 始点, 終点, 色)を表す。
実行結果
(opencvEnv)$ python lines_on_image.py
指定フォルダ配下にLinesOnImage.jpg生成され、線が描写された画像がウィンドウに表示される事を確認。
画像上に円を描く
次に、Lenna.jpgに対して円を描く。 以下のコードを写経しcircles_on_image.pyのファイルを作成。
import cv2 try: img = cv2.imread('img/Lenna.jpg') if img is None: print('ファイルを読み込めません') import sys sys.exit() # 画像に対して円を描く cv2.circle(img, (50, 50), 40, (0, 255, 0), 2) cv2.circle(img, (150, 150), 80, (255, 255, 0), 6) cv2.circle(img, (200, 200), 50, (0, 255, 255), -1) cv2.imwrite('img/CirclesOnImage.jpg', img) cv2.imshow('img', img) cv2.waitKey(0) cv2.destroyAllWindows() except: import sys print("Error:", sys.exc_info()[0]) print(sys.exc_info()[1]) import traceback print(traceback.format_tb(sys.exc_info()[2]))
円・線の描写で学んだ関数を使用し画像上に3つの円を描くよう記述。
実行結果
(opencvEnv)$ python circles_on_image.py
指定フォルダ配下にCirclesOnImage.jpg生成され、円が描写された画像がウィンドウに表示される事を確認。
画像上に文字を描く
次に、Lenna.jpgに対して文字を描く。
以下のコードを写経しdraw_text.pyのファイルを作成。
import cv2 try: img = cv2.imread('img/Lenna.jpg') if img is None: print('ファイルを読み込めません') import sys sys.exit() # 画像に対して文字を描く cv2.putText(img, 'Hello OpenCV', (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (150, 60, 80), 2) cv2.imwrite('img/puttext.jpg', img) cv2.imshow('img', img) cv2.waitKey(0) cv2.destroyAllWindows() except: import sys print("Error:", sys.exc_info()[0]) print(sys.exc_info()[1]) import traceback print(traceback.format_tb(sys.exc_info()[2]))
- cv2.putText(...):文字の描写
使用例:cv2.putText(img, 'Hello OpenCV', (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (150, 60, 80), 2) 引数は、順に(対象画像,文字列,表示位置, フォント,サイズ,色,太さ)を表す。
実行結果
(opencvEnv)$ python draw_text.py
指定フォルダ配下にputtext.jpg生成され、文字が描写された画像がウィンドウに表示される事を確認。
まとめ
- cv2.circle(...):円の描写
- cv2.line(...):線の描写
- cv2.putText(...):文字の描写
ソースコード
Python + OpenCV4プログラミングの学習(2)〜画像生成・読み込み・書き込み〜
本記事はOpenCVによる画像生成・読込・書込を行ったときの備忘録である。
事前準備
以下の記事で仮想環境opencvEnvを構築していることを前提とする。 kawakeee.hatenablog.com
画像を生成する
以下のコードを写経しcreate_img.pyのファイルを作成。
import numpy as np import cv2 # 画像情報(3次元配列)の生成 (行、列、色) img = np.zeros((400, 400, 3), np.uint8) img[:,:] = [255, 0, 0] # 生成したimgを指定ファイルとして保存 cv2.imwrite('img/blueImage.jpg', img) # imgを表示 cv2.imshow('img1', img) img[:,:] = [0, 255, 0] cv2.imwrite('img/greenImage.jpg', img) cv2.imshow('img2', img) img[:,:] = [0, 0, 255] cv2.imwrite('img/redImage.jpg', img) cv2.imshow('img3', img) cv2.waitKey(0) cv2.destroyAllWindows()
- cv2.imwrite(...):画像情報の保存(書き込み)
- cv2.imshow(...):画像情報の表示
実行確認
(opencvEnv)$ python create_img.py
指定フォルダ配下に画像が生成されていることを確認。
また、cv2.imshow
によってウィンドウで画像が表示される事を確認。
画像の読み込み・書き込み
任意の画像ファイルを用意する。今回はLenna.jpgを用意した。
以下のコードを写経しread_write.pyのファイルを作成。
import cv2 # 画像情報の読み込み img = cv2.imread('img/Lenna.jpg') # 画像情報の保存(書き込み) cv2.imwrite('img/ReadWrite.jpg', img)
- cv2.imread(...):画像情報の読み込み
実行結果
(opencvEnv)$ python read_write.py
指定フォルダ配下にReadWrite.jpg生成されていることを確認する。
まとめ
- cv2.imwrite(...):画像情報の保存(書き込み)
- cv2.imread(...):画像情報の読み込み
- cv2.imshow(...):画像情報の表示
ソースコード
Python + OpenCV4プログラミングの学習(1)〜開発環境の準備〜
本記事ではOpenCVが動作する開発環境構築の備忘録である。
事前確認
参考書籍ではAnacondaを使って学習を進めていくようだが、面倒なのでサクッとOpenCVが正常に動作する仮想環境を作る。
仮想環境の準備
仮想環境opencvEnvをvenvで作成
$ python3 -m venv opencvEnv # activate しておく $ source opencvEnv/bin/activate (opencvEnv)$ ...
OpenCVのインストール
pip install
でOpenCVをイントール
(opencvEnv)$ pip install opencv-python Collecting opencv-python Downloading https://files.pythonhosted.org/packages/e2/a9/cd3912ca0576ea6588095dce55e54c5f0efeb3d63fb88f16f4c06c0fac8d/opencv_python-4.1.2.30-cp36-cp36m-macosx_10_9_x86_64.whl (45.2MB) 100% |████████████████████████████████| 45.2MB 721kB/s Collecting numpy>=1.11.3 (from opencv-python) Using cached https://files.pythonhosted.org/packages/22/99/36e3408ae2cb8b72260de4e538196d17736d7fb82a1086cb2c21ee156ddc/numpy-1.17.4-cp36-cp36m-macosx_10_9_x86_64.whl Installing collected packages: numpy, opencv-python Successfully installed numpy-1.17.4 opencv-python-4.1.2.30 import cv2
pip freeze
でOpenCV4以上がインストールされた事を確認。
(opencvEnv)$ pip freeze numpy==1.18.1 opencv-python==4.1.2.30
実行確認
以下のコードを写経しhello_opencv.pyのファイルを作成。
import cv2 print(cv2.__version__)
hello_opencv.pyを実行し4.1.2
が表示されれば開発環境の準備は完了。
(opencvEnv)$ python hellow_opencv.py 4.1.2
(実行結果はOpenCVのバージョンによって変わる)
ソースコード
Python + OpenCVで顔検出(3)〜検出箇所のみに画像トリミング〜
こちらの記事で、リアルタイムカメラから顔検出→画像生成するところまでできた。 kawakeee.hatenablog.com
今回は、顔検出したタイミングで顔検出部分の画像ファイル(jpg)を生成させる。
顔検出箇所をトリミング
顔検出時に黒枠で囲む際の座標情報を用いて、フレームをトリミングする。 【一部抜粋】
# 検出した顔に印を付ける for (x, y, w, h) in face_list: color = (0, 0, 225) pen_w = 3 cv2.rectangle(img_gray, (x, y), (x+w, y+h), color, thickness = pen_w) # face_image:顔検出した部分だけにトリミングする face_image = img_gray[y:y+h, x:x+w]
【全文】
import cv2 if __name__ == '__main__': # 定数定義 ESC_KEY = 27 # Escキー INTERVAL= 33 # 待ち時間 FRAME_RATE = 30 # fps ORG_WINDOW_NAME = "org" GAUSSIAN_WINDOW_NAME = "gaussian" DEVICE_ID = 0 # 分類器の指定 cascade_file = "../xml/haarcascade_frontalface_alt2.xml" cascade = cv2.CascadeClassifier(cascade_file) # カメラ映像取得 cap = cv2.VideoCapture(DEVICE_ID) # 初期フレームの読込 end_flag, c_frame = cap.read() height, width, channels = c_frame.shape # ウィンドウの準備 cv2.namedWindow(ORG_WINDOW_NAME) cv2.namedWindow(GAUSSIAN_WINDOW_NAME) # 連番の生成 n = 0 # 変換処理ループ while end_flag == True: # 画像の取得と顔の検出 img = c_frame img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) face_list = cascade.detectMultiScale(img_gray, minSize=(100, 100)) # 検出した顔に印を付ける for (x, y, w, h) in face_list: color = (0, 0, 225) pen_w = 3 cv2.rectangle(img_gray, (x, y), (x+w, y+h), color, thickness = pen_w) # face_image:顔検出した部分だけにトリミングする face_image = img_gray[y:y+h, x:x+w] # フレーム表示 cv2.imshow(ORG_WINDOW_NAME, c_frame) cv2.imshow(GAUSSIAN_WINDOW_NAME, img_gray) # 顔が検出されたらjpgファイルを生成する if type(face_list) is not tuple : # face_imageを画像ファイルとして生成する cv2.imwrite('{}_{}.{}'.format('../images/trim/face', n, 'jpg'), face_image) n += 1 # Escキーで終了 key = cv2.waitKey(INTERVAL) if key == ESC_KEY: break # 次のフレーム読み込み end_flag, c_frame = cap.read() # 終了処理 cv2.destroyAllWindows() cap.release()
実行
pictureフォルダ(画面右)に、顔検出がされる度に顔検出箇所部分のみにトリミングされた画像ファイルが生成される事を確認。
ソースコード
今回のソースコードは以下のリポジトリのface_detect_trim.py
から転載。
github.com
参考記事
OpenCVの画像トリミングについての参考記事
www.pynote.info
Python + OpenCVで顔検出(2)〜検出時のフレーム画像をキャプチャ〜
こちらの記事で、リアルタイムカメラから顔検出するところまでできた。 kawakeee.hatenablog.com
今回は、顔検出したタイミングで画像ファイル(jpg)を生成させる。
顔検出時に条件分岐を追加
前回のface_detect.py
にてface_list
に顔検出情報が格納されると、型がtupleからndarrayに変更されるため、型を条件に画像ファイルを保存するかしないか判定する。
【一部抜粋】
# 顔が検出されたらjpgファイルを生成する if type(face_list) is not tuple : cv2.imwrite('{}_{}.{}'.format('../images/capture/face', n, 'jpg'), c_frame)
【全文】
import cv2 if __name__ == '__main__': # 定数定義 ESC_KEY = 27 # Escキー INTERVAL= 33 # 待ち時間 FRAME_RATE = 30 # fps ORG_WINDOW_NAME = "org" GAUSSIAN_WINDOW_NAME = "gaussian" DEVICE_ID = 0 # 分類器の指定 cascade_file = "../xml/haarcascade_frontalface_alt2.xml" cascade = cv2.CascadeClassifier(cascade_file) # カメラ映像取得 cap = cv2.VideoCapture(DEVICE_ID) # 初期フレームの読込 end_flag, c_frame = cap.read() height, width, channels = c_frame.shape # ウィンドウの準備 cv2.namedWindow(ORG_WINDOW_NAME) cv2.namedWindow(GAUSSIAN_WINDOW_NAME) # 連番の生成 n = 0 # 変換処理ループ while end_flag == True: # 画像の取得と顔の検出 img = c_frame img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) face_list = cascade.detectMultiScale(img_gray, minSize=(100, 100)) # 検出した顔に印を付ける for (x, y, w, h) in face_list: color = (0, 0, 225) pen_w = 3 cv2.rectangle(img_gray, (x, y), (x+w, y+h), color, thickness = pen_w) # フレーム表示 cv2.imshow(ORG_WINDOW_NAME, c_frame) cv2.imshow(GAUSSIAN_WINDOW_NAME, img_gray) # 顔が検出されたらjpgファイルを生成する if type(face_list) is not tuple : cv2.imwrite('{}_{}.{}'.format('../images/capture/face', n, 'jpg'), c_frame) n += 1 # Escキーで終了 key = cv2.waitKey(INTERVAL) if key == ESC_KEY: break # 次のフレーム読み込み end_flag, c_frame = cap.read() # 終了処理 cv2.destroyAllWindows() cap.release()
実行
pictureフォルダ(画面右)に、顔検出がされる度に画像ファイルが生成される事を確認。
ソースコード
今回のソースコードは以下のリポジトリのface_detect_cap.py
から転載。
github.com
参考記事
この記事ではボタン押下時に画像ファイルを生成している。 note.nkmk.me
Python + OpenCVで顔検出(1)〜リアルタイムカメラから検出〜
qiita.com 上の記事を参考にOpenCVで顔検出したときのメモ
仮想環境の準備
opencvEnvの環境をvenvで作成
$ python3 -m venv opencvEnv # activate しておく $ source opencvEnv/bin/activate (opencvEnv)$ ...
openCVのインストール
pipでopenCVをイントール
(opencvEnv)$ pip install opencv-python Collecting opencv-python Downloading https://files.pythonhosted.org/packages/e2/a9/cd3912ca0576ea6588095dce55e54c5f0efeb3d63fb88f16f4c06c0fac8d/opencv_python-4.1.2.30-cp36-cp36m-macosx_10_9_x86_64.whl (45.2MB) 100% |████████████████████████████████| 45.2MB 721kB/s Collecting numpy>=1.11.3 (from opencv-python) Using cached https://files.pythonhosted.org/packages/22/99/36e3408ae2cb8b72260de4e538196d17736d7fb82a1086cb2c21ee156ddc/numpy-1.17.4-cp36-cp36m-macosx_10_9_x86_64.whl Installing collected packages: numpy, opencv-python Successfully installed numpy-1.17.4 opencv-python-4.1.2.30 import cv2
顔検出のプログラム準備
face_ detect.pyを作成する
【face_ detect.py】
import cv2 if __name__ == '__main__': # 定数定義 ESC_KEY = 27 # Escキー INTERVAL= 33 # 待ち時間 FRAME_RATE = 30 # fps ORG_WINDOW_NAME = "org" GAUSSIAN_WINDOW_NAME = "gaussian" DEVICE_ID = 0 # 分類器の指定 cascade_file = "../xml/haarcascade_frontalface_alt2.xml" cascade = cv2.CascadeClassifier(cascade_file) # カメラ映像取得 cap = cv2.VideoCapture(DEVICE_ID) # 初期フレームの読込 end_flag, c_frame = cap.read() height, width, channels = c_frame.shape # ウィンドウの準備 cv2.namedWindow(ORG_WINDOW_NAME) cv2.namedWindow(GAUSSIAN_WINDOW_NAME) # 変換処理ループ while end_flag == True: # 画像の取得と顔の検出 img = c_frame img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) face_list = cascade.detectMultiScale(img_gray, minSize=(100, 100)) # 検出した顔に印を付ける for (x, y, w, h) in face_list: color = (0, 0, 225) pen_w = 3 cv2.rectangle(img_gray, (x, y), (x+w, y+h), color, thickness = pen_w) # フレーム表示 cv2.imshow(ORG_WINDOW_NAME, c_frame) cv2.imshow(GAUSSIAN_WINDOW_NAME, img_gray) # Escキーで終了 key = cv2.waitKey(INTERVAL) if key == ESC_KEY: break # 次のフレーム読み込み end_flag, c_frame = cap.read() # 終了処理 cv2.destroyAllWindows() cap.release()
分類器のファイルを取得
顔検出に使用するhaarcascade_frontalface_alt2.xml
を以下のサイトから取得し、任意の場所にファイルをダウンロードする。
ja.osdn.net
実行
face_ detect.pyを実行する。ターミナルからカメラのアクセス許可を求めらるので許可する。
(opencvEnv)$ python face_ detect.py
カメラで取得できる映像から顔検出することができる。カメラは[Esc]で強制終了できる。