PythonでOpenCV

PythonでOpenCVやってみた.Windowsでの各種開発環境導入にある程度慣れている人向け.Pythonの導入から,OpenCVのサンプルコードが動くまでの手順を説明しています.各環境がどういうものか,については説明しません.個人的な感想としては,C言語でOpenCVを動かすよりもかなりハードルが低い.

References

本項目を書くにあたっては,下記のWebサイトを大いに参考にいたしました.ありがとうございます.

環境

Microsoft Windows 10 (64bit) において,下記の環境をインストールすることが目標.

  • Anaconda for Windows 64bit
  • OpenCV 3.1+opencv_contrib for Windows 64bit

導入手順

  1. Continuum社の公式サイトより,Anacondaのインストーラをダウンロード
  2. インストーラを実行
  3. Unofficial Windows Binaries for Python Extension Packagesより,"opencv_python-3.1.0+contrib_opencl-cp35-cp35m-win_amd64.whl" というファイルをダウンロード
  4. Windowsのコマンドプロンプトにおいて,以下のコマンドを実行する.ダウンロードしたwhlファイルのフォルダが存在する場所において,Shift+右クリックから「コマンド ウィンドウをここで開く」メニューを使うと楽
    • pip install "opencv_python-3.1.0+contrib_opencl-cp35-cp35m-win_amd64.whl"
  5. Anacondaには開発環境Spyderが同梱されているので,そちらでコードを書いて実行

コード例1: オプティカルフロー

OpenCV公式チュートリアルを大いに参考にしています.

import numpy as np import cv2 # カメラキャプチャの宣言 cap = cv2.VideoCapture(0) # 一回読み込んでグレーにしてとかいう準備 _, frame1 = cap.read() prvs = cv2.cvtColor(frame1,cv2.COLOR_BGR2GRAY) hsv = np.zeros_like(frame1) hsv[...,1] = 255 while(1): # 現在フレームを取得してグレースケール _, frame2 = cap.read() next = cv2.cvtColor(frame2, cv2.COLOR_BGR2GRAY) # Farnebackの手法でオプティカルフローを計算 flow = cv2.calcOpticalFlowFarneback(prvs, next, None, 0.5, 3, 15, 3, 5, 1.2, 0) # フローの向きを色相にマップする mag, ang = cv2.cartToPolar(flow[...,0], flow[...,1]) hsv[...,0] = ang*180/np.pi/2 hsv[...,2] = cv2.normalize(mag,None,0,255,cv2.NORM_MINMAX) rgb = cv2.cvtColor(hsv,cv2.COLOR_HSV2BGR) # 表示 cv2.imshow("frame", frame2) cv2.imshow("Calculated Opt Flow", rgb) # escが入ったら終了 k = cv2.waitKey(10) if k == 27: break # 現在フレームの画像を次の基準画像にする prvs = next cap.release() cv2.destroyAllWindows()

frame
estimated optical flow

(L to R) フレーム画像,計算されたオプティカルフロー

コード例2: AKAZEによる物体検出

import cv2 # カメラキャプチャの宣言 cap = cv2.VideoCapture(2) # テンプレートの読み込み ref = cv2.imread("template.jpg") # ディテクタを宣言 detector = cv2.AKAZE_create() kpRef, descRef = detector.detectAndCompute(ref, None) while(1): # 現在フレームを取得してグレースケール _, frame = cap.read() # 特徴量を検出 kp, desc = detector.detectAndCompute(frame, None) # matcherを生成 bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True) # matchしてソート matches = bf.match(desc,descRef) matches = sorted(matches, key=lambda x:x.distance) # 表示 imgMatch = cv2.drawMatches(frame, kp, ref, kpRef, matches[:30], None, flags=2) cv2.imshow("Matching Result", imgMatch) # escが入ったら終了 k = cv2.waitKey(10) if k == 27: break elif k == ord('s'): cv2.imwrite("frame.jpg", frame) cv2.imwrite("match.jpg", imgMatch) cap.release() cv2.destroyAllWindows()

AKAZE_matching