OpenCV(Open Source Computer Vision Library)とはインテル社が開発したC/C++、Java、Python、MATLABの言語向けの画像処理ライブラリ集です。
画像のフィルタ処理、テンプレートマッチング、物体認識、映像解析、機械学習などのアルゴリズムが多数用意されています。
顔の検出や特徴抽出等のパッケージも揃っているため、比較的容易に画像処理を試す&実装することができます。
スポンサードリンク
Windows パソコン上で gnupack_devel を利用して動作確認しています。
Pythonをインストールした後、各ライブラリを「pip install」でインストールしてください。
OpenCVのGitHubからダウンロードします。
展開
opencv → releases → OpenCV 3.1 → Downloads → opencv-3.1.0.exe → 実行 → 展開フォルダを指定 → Extract
サンプル(写真、動画)は、以下に格納されています。
opencv\sources\samples\data
画像処理は、出力形態から大きく分けて3つに分類されます。
| 画像改善 | 雑音やぼけのような画像劣化要因を取り除くことにより、見にくいもの・見えないものを見えるようにする |
|---|---|
| 画像解析 | 特徴量を計測する |
| 画像認識 | 画像に写っているモノを識別し、その判断後にアクションを起こさせる(人間の視覚の代行) |
OpenCV 3.1.0は以下の画像フォーマットの入出力をサポートしています(※詳細は「公式ドキュメント(英語)」を参照)
| 画像フォーマット | 拡張子 |
|---|---|
| Windows bitmap | .bmp、.dib |
| JPEG | .jpeg、.jpg、.jpe |
| JPEG 2000 | .jp2 |
| Portable Network Graphics | .png |
| WebP | .webp |
| Portable image format | .pbm、.pgm、.ppm |
| Sun rasters | .sr、.ras |
| TIFF | .tiff、.tif |
| OpenEXR Image | .exr |
| Radiance HDR | .hdr、.pic |
| GDAL | Raster、Vectorに列挙されるフォーマット |
※ 画像の種類をファイルの拡張子からではなく、内容から判別しています。
スポンサードリンク
動画ファイル(.mp4, .avi, .mov, .mpeg, .flv, .wmv形式)を利用することができます。
# coding: UTF-8
import numpy as np
import cv2
cap = cv2.VideoCapture('input.avi')
ret, frame = cap.read()
cv2.imwrite('first_frame.png',frame)
while(cap.isOpened()):
ret, frame = cap.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
cv2.imshow('frame',gray)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
cv2.waitKey()はキーボードからのなんらかの応答を、指定したミリ秒間だけ待ち受ける関数です。
ここでは'q'ボタンを押すとwhileループから抜け出ることができるように、waitkey()で'q'ボタンが押されたときに帰ってくる応答コマンドを待ちうけています。
濃淡がなく、白と黒しかない図形・画像は、画素の値が0、1の2つの値しか取りません。そのような画像を2値画像と呼びます。
ret, dst = cv2.threshold(src, threshold, max_value, threshold_type)
特徴が急激に変化する画像中の場所を探すにはエッジ検出するのが画像分割の基本的手法となっている。
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('sample.jpg',0)
edges = cv2.Canny(img,100,200)
plt.subplot(121),plt.imshow(img,cmap = 'gray')
plt.title('Original Image'), plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(edges,cmap = 'gray')
plt.title('Edge Image'), plt.xticks([]), plt.yticks([])
plt.show()
特徴量による画像比較は検出したい物体について「ピクセルの値(RGB値など)の表現ではなく、その物体を最もよく表現するポイントを数値で表現し、そのポイントごとの数値で比較」するというアプローチです。
特徴量の具体的な手法としてOpenCVでは、HaarLike(明度差)、HOG(輝度の勾配方向)、SIFTやSURF、AKAZE(Accelerated KAZE)などが実装されています。
画像のマッチングを行うときは、回転、拡縮、アフィン変換などを意識する必要があります。
動画像での水玉コラ自動作成に詳細を書いています。
for m in range(0, len(gFeature)):
features_prev = np.array([[[gFeature[m][0], gFeature[m][1]]]], np.float32)
# 前フレーム、現フレーム、前フレームでの点の位置、画像ピラミッドの最大レベル数
features, status, err = cv2.calcOpticalFlowPyrLK( \
gray_prev, \
gray_next, \
features_prev, \
None, \
winSize = (20, 20), \
maxLevel = 3, \
criteria = CRITERIA, \
flags = 0)
# フレームに有効な特徴点を描画
if features is not None:
for feature in features:
gFeature[m][0] = feature[0][0]
gFeature[m][1] = feature[0][1]
else:
del gFeature[m]
Tesseract-OCR というgoogleが開発を行っているOCRエンジンが存在します。
これ を入れる
Pythonで使いたいのでラッパーを入れる。
日本語に対応させるためにここからjapn.traineddataを/usr/local/tessdataに入れる。
パスを貼る。
export TESSDATA_PREFIX="/usr/local/share/tessdata/tessdata/
プログラムを書く。
#-*- coding:utf-8 -*-
import tesseract
#tesseractオブジェクト作成(文字コードも設定)
api = tesseract.TessBaseAPI()
api.Init(".","jpn",tesseract.OEM_DEFAULT)
api.SetPageSegMode(tesseract.PSM_AUTO)
#画像ファイル読み込み
mImgFile = "D:\\work\\image.jpg"
mBuffer=open(mImgFile,"rb").read()
#文字情報取得
result = tesseract.ProcessPagesBuffer(mBuffer,len(mBuffer),api)
print result
制約のない実世界シーンの画像に対して、コンピュータがその中に含まれる物体を一般的な名称で認識することを一般物体認識と呼びます。
2010年に「物体検出アルゴリズムObjectness」がリリースされました。
OpenCVのContributionにあるBING(Objectness)を使用します。
BING(Binarized Normed Gradients for Objectness Estimation)
画像中からオブジェクトらしい矩形領域を抽出することができる手法で、物体認識の前処理に利用できます。
物体認識を問題領域の観点から大別して2系統あります。
| 特定物体認識 | 既知の物体Aについて、画像中のどこに物体Aが存在するか(もしくは存在しない)を調べる |
| 一般物体認識 | 画像が何を示しているものなのかを言い当てる(例:車の画像) |
カメラ画像から自分の好きな物体を検出する
OpenCVでHOGを求めて、scikit-imageのSVMで学習できますが、dlibを使う方が容易です。
dlib を使って、HOG特徴とSVMによる学習を使った物体検出
学習により、切り出した画像中にHOG特徴の有無を判定できるSVMを作成します。
検出時には、入力画像からHOGピラミッドを作成し、各画像におけるHOG特徴の有無でSVMで判定します。
複雑な形の認識は(顔認識など)は CascadeClassifier で行います。
単純な認識機を多段(カスケード)に組み合わせることで認識精度を上げます。
ただし、機械学習したデータを使って認識を行うため学習データを作る必要です。
OpenCVには以下の学習データ(Haar-like特徴分類器)があらかじめ用意されています。
[OpenCV Install Dir]/Library/etc/haarcascades/
| ファイル名 | 内容 |
|---|---|
| haarcascade_eye.xml | 目 |
| haarcascade_eye_tree_eyeglasses.xml | 眼鏡 |
| haarcascade_frontalcatface.xml | 猫の顔(正面) |
| haarcascade_frontalcatface_extended.xml | 猫の顔(正面) |
| haarcascade_frontalface_alt.xml | 顔(正面) |
| haarcascade_frontalface_alt2.xml | 顔(正面) |
| haarcascade_frontalface_alt_tree.xml | 顔(正面) |
| haarcascade_frontalface_default.xml | 顔(正面) |
| haarcascade_fullbody.xml | 全身 |
| haarcascade_lefteye_2splits.xml | 左目 |
| haarcascade_licence_plate_rus_16stages.xml | ロシアのナンバープレート(全体) |
| haarcascade_lowerbody.xml | 下半身 |
| haarcascade_profileface.xml | 顔(証明写真) |
| haarcascade_righteye_2splits.xml | 右目 |
| haarcascade_russian_plate_number.xml | ロシアのナンバープレート(数字) |
| haarcascade_smile.xml | 笑顔 |
| haarcascade_upperbody.xml | 上半身 |
#coding: utf-8
import cv2
import sys
import numpy as np
# Haar-like特徴分類器の読み込み
face_cascade = cv2.CascadeClassifier('haarcascades/haarcascade_frontalface_default.xml')
eye_cascade = cv2.CascadeClassifier('haarcascades/haarcascade_eye.xml')
# イメージファイルの読み込み
img = cv2.imread(sys.argv[1])
# グレースケール変換
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 顔を検知
faces = face_cascade.detectMultiScale(gray)
for (x,y,w,h) in faces:
# 検知した顔を矩形で囲む
cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
# 顔画像(グレースケール)
roi_gray = gray[y:y+h, x:x+w]
# 顔画像(カラースケール)
roi_color = img[y:y+h, x:x+w]
# 顔の中から目を検知
eyes = eye_cascade.detectMultiScale(roi_gray)
for (ex,ey,ew,eh) in eyes:
# 検知した目を矩形で囲む
cv2.rectangle(roi_color,(ex,ey),(ex+ew,ey+eh),(0,255,0),2)
# 画像表示
cv2.imshow('img',img)
# 何かキーを押したら終了
cv2.waitKey(0)
cv2.destroyAllWindows()
CascadeClassifier.detectMultiScale のパラメータは次のとおりです。
| パラメータ | 説明 |
|---|---|
| image: | CV_8U型の行列。ここに格納されていいる画像中から物体が検出されます |
| objects: | 矩形を要素とするベクトル。それぞれの矩形には、検出した物体を含みます |
| scaleFactor: | 画像スケールにおける縮小量 |
| minNeighbors: | 物体候補となる矩形は、最低でもこの数だけの近傍矩形を含む必要があります |
| minSize: | 物体が取り得る最小サイズ。これよりも小さい物体は無視されます |
| maxSize: | 物体が取り得る最大サイズ |
error: (-215) !empty() in function detectMultiScale
とエラーが出力される場合は、cv2.CascadeClassifier('パス名/haarcascade_frontalface_alt.xml') のpathが間違っています。
絶対PATHで書き直すか、ファイルそのものを同じディレクトリに持ってきてください。
スポンサードリンク