OpenCVのpythonインターフェース入門

[Pycon JP 2014](https://pycon.jp/2014/) ,9月14日(日)

林 昌希(Masaki Hayashi)

[derivecv.tumblr.com](derivecv.tumblr.com), [@derivecv](http://twitter.com/derivecv)

慶応義塾大学大学院 博士課程

発表者について

  • 専門は機械学習による画像認識
  • 元計測システム開発者 => 現在 博士課程3年
  • DERiVEコンピュータビジョンブログ・メルマガ(@derivecv)
  • 研究は「チームスポーツ映像からの人物姿勢推定とその応用」
  • 翻訳者に「コンピュータビジョン - アルゴリズムと応用」著者:Richard Szeliski ; 訳者:玉木徹 他
  • Web連載:「コンピュータビジョンのセカイ〜今そこにあるミライ〜」マイナビニュースにて2011年3月より連載中

本日の内容と目的

目的

  • コンピュータビジョンの初級者: Pythonでコンピュータビジョンプログラミングは簡単に始められる!!

  • コンピュータビジョンの中級者: C++でしかOpenCVを使っていない方 -->> Pythonインターフェースを知らないせいで莫大な時間損失をしていることに気づくべき!Matlabのようにインタラクティブプログラミングの恩恵が得られる

  • データ解析•機械学習系のみなさま: Scikit-learnやpandasは使えて画像認識をはじめてみたい!という方への最初のきっかけに

 目次

  1. Computer Visionとは
  2. OpenCVの概要と、pythonからの使用
  3. 入出力と可視化
  4. 画像処理の基礎的な処理のデモ
  5. 応用例(動画での背景差分、人検出)

1. Computer Visionとは

Computer Vision: カメラで撮影した画像•動画、デプスなどから、実世界の様子を計算機で(できれば自動的に)把握する技術分野

In [1]:
from IPython.display import YouTubeVideo

YouTubeVideo('ftQnykTmGPw')
Out[1]:

2-1. OpenCVの概要

  • C++言語向けのComputer Vision向け大規模ライブラリ
  • Python, Javaなどのラッパーも提供されていて、C++版とほぼ同じように使える
  • 画像処理,動画像入出力から, ステレオビジョン、局所特徴量、顔検出などコンピュータビジョンの基本的な道具が全部入っている
  • 最新のバージョンはOpenCV2.4.9。先日、OpenCV3.0.0のα版がリリース。

OpenCV(2.4.9)の主要モジュール

In [2]:
# cv2モジュールからのOpenCV関数へのアクセス例
import cv2
img = cv2.imread('Lenna.png')

多くのモジュールに分割されているが、Pythonからだと全ての関数は「cv2」でインポートし、cv2.から各関数にアクセスするだけ

基本モジュール(いつも使う)

  • core
  • imgproc (画像処理)
  • highgui (画像の表示ウィンドウとマウスキーボード入力)

OpenCV(2.4.9)の主要モジュール

応用モジュール (カテゴリーごとの処理)

  • video (動画処理、背景差分、オプティカルフロー)
  • calib3d (カメラキャリブレーション、ステレオ幾何)
  • features2d (局所特徴量とそのマッチング)
  • objdetect (物体検出: 顔検出,人検出,Latent SVM)
  • stitching (パノラマ作成)
  • superres (超解像)
  • videostab (動画安定化)
  • ml (基礎的な機械学習)
  • gpu, ocl (各アルゴリズムのCUDA版、OpenCL版)

2-2. OpenCVのpythonからの使用方法

  • cv2モジュールをインポート
  • 画像データはnumpyのarray(多次元配列)として格納されている

(C++ではなく)PythonでOpenCVを使うメリット

  • numpyやscipyなどのpythonで充実している数値計算ライブラリとの連繋
  • C++と違って(コンパイルを待たずに)、インタラクティブに、実験的に実行できる(しかもIPythonもある!)
  • IPython Notebook(再生可能なノート)による、全ての結果のノート保存と、そのノートのグループ共有・Web共有
  • Scikit-learn, pandasなど、機械学習、データサイエンスとの相性もGood

3. 入出力と可視化

  • 画像の入力はcv2.imread() ---> numpy.ndarray型の画像データ
  • OpenCVの画像データの構造
    • カラー画像:(height × width × channels)の3次元配列
    • グレー画像:(height × width)の2次元配列
In [3]:
import cv2
img = cv2.imread('Lenna.jpg')
print img.shape
(512, 512, 3)
In [4]:
gray= cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
print gray.shape
(512, 512)

OpenCV画像データがnumpy配列であるメリット

  • numpy,scipyなどの線形代数関数が、OpenCVでのプログラムにも使用可能。(C++のOpenCVでは、画像を扱うMatクラスに用意されている線形代数関数を使う)
  • numpy的な画像操作を書けば、c言語並みの計算スピードをnumpyにより簡単に確保しやすい。
  • scikit-learnpyMC3などの、Pythonの統計的・機械学習ライブラリとの連繋もGood!
  • numpyの配列はMatlabの配列と似ているので、研究者もPythonへ移行しやすい。(参考:Numpy for Matlab Users)

注意点

  • matplotlib,PIL,scikit-imageはRGB画像で保持するのに対して、nnOpeCVはBGR画像がデフォルト(後述のように、カラー変換が必要)

画像の可視化1 with OpenCV

cv2.imshow()を用いる

In [5]:
cv2.imshow('color image',img)
In [6]:
cv2.imshow('gray image',gray)

画像の可視化2 with matplotlib

Matplotlibのpyplot.imshowでも画像をplotできる

In [7]:
import matplotlib.pyplot as plt
%matplotlib inline

plt.imshow(img)
Out[7]:
<matplotlib.image.AxesImage at 0x10f3e8f90>

※ 前述のように、OpenCVの画像はBGR画像なので、matplotlibで正しく表示するには色変換する必要有り

画像の可視化2 with matplotlib

OpenCVで読み込んだ画像はBGR画像 => cvCvtColor()でRGB画像へ変換

In [8]:
cvimg= cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
plt.imshow(cvimg)
Out[8]:
<matplotlib.image.AxesImage at 0x1113bb690>

4. 画像処理の基礎的な処理のデモ : ガウシアンブラー

元画像に対して、ガウシアンフィルターを用いてボケ画像を作成

In [9]:
import numpy as np
#2Dカーネルを自分で作成して フィルタリング
kernel = np.ones((5,5),np.float32)/25
dst = cv2.filter2D(cvimg,-1,kernel)
#既に用意されているGaussinaBlur関数でフィルタリング
dst2 = cv2.GaussianBlur(cvimg,(5,5),0)
In [10]:
plt.figure(figsize=(16, 8))
plt.subplot(131),plt.imshow(cvimg),plt.title('Original')
plt.xticks([]), plt.yticks([])
plt.subplot(132),plt.imshow(dst),plt.title('Averaging')
plt.xticks([]), plt.yticks([])
plt.subplot(133),plt.imshow(dst2),plt.title('Averaging2')
plt.xticks([]), plt.yticks([])
plt.show()

4. 画像処理の基礎的な処理のデモ : エッジ検出

元画像から、以下の各フィルターでエッジ画像を作成

  1. Laplacian2次微分した結果
  2. X方向の1次微分(Sobelフィルタ)
  3. Y方向の1次微分(Sobelフィルタ
In [14]:
laplacian = cv2.Laplacian(gray,cv2.CV_64F)
sobelx = cv2.Sobel(gray,cv2.CV_64F,1,0,ksize=5)
sobely = cv2.Sobel(gray,cv2.CV_64F,0,1,ksize=5)
plt.figure(figsize=(16, 8))
plt.subplot(1,4,1),plt.imshow(cvimg,cmap = 'gray');plt.title('Original'), plt.xticks([]), plt.yticks([])
plt.subplot(1,4,2),plt.imshow(laplacian,cmap = 'gray');plt.title('Laplacian'), plt.xticks([]), plt.yticks([])
plt.subplot(1,4,3),plt.imshow(sobelx,cmap = 'gray');plt.title('Sobel X'), plt.xticks([]), plt.yticks([])
plt.subplot(1,4,4),plt.imshow(sobely,cmap = 'gray');plt.title('Sobel Y'), plt.xticks([]), plt.yticks([])
plt.show()