Comments
Description
Transcript
OpenCVによる動画処理
OpenCV による動画処理 田中 那智 廣安 知之 山本 詩子 2014 年 8 月 25 日 IS Report No. 2014090201 Report Medical Information System Labratry Abstract 画像処理ライブラリである OpenCV は世界でも広く使用されている.また画像処理のみではなく,動 画より画像を抽出して動画処理に利用することもできる.本稿では,OpenCV を用いた基礎的な動 画処理と顔検出を行い,またそれらの原理について述べる. 目次 第 1 章 はじめに . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 1.1 OpenCV とは . . . . . . . . . . . . . . . . . . . . . . . . . . 2 1.2 ディジタル画像について . . . . . . . . . . . . . . . . . . . . . . 2 第 2 章 カメラキャプチャ . . . . . . . . . . . . . . . . . . . . . . . . . 3 第 3 章 動画処理 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 3.1 ネガポジ反転 . . . . . . . . . . . . . . . . . . . . . . . . . . 5 3.2 上下左右反転 . . . . . . . . . . . . . . . . . . . . . . . . . . 5 3.3 サイズ変換 . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 3.4 平滑化処理 . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 3.4.1 ガウシアンフィルタ . . . . . . . . . . . . . . . . . . . . . . . 7 3.4.2 バイラテラルフィルタ . . . . . . . . . . . . . . . . . . . . . . 7 3.5 グレースケール化 . . . . . . . . . . . . . . . . . . . . . . . . . 9 3.6 二値化 (大津法). . . . . . . . . . . . . . . . . . . . . . . . . . 9 3.7 顔検出 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 第 1 章 はじめに 1.1 OpenCV とは OpenCV とは,Intel によって開発された画像処理,画像認識に関連する機能のライブラリのこと である.C,C++,Python,Java によって記述することが可能であり,Windows や Linux など複数 のプラットフォームに対応している.BSD ライセンスに基づくオープンソースソフトウェア (OSS) として提供されているため、誰でも無償で利用することができる.本稿では言語は C++を用いる. OpenCV で利用できる機能には以下のようなものがある. • 行列計算 • フィルタ処理 • 特徴点抽出 • オブジェクトトラッキング • 機械学習 • GUI(ウィンドウ表示,画像 (動画) ファイルの入出力,カメラキャプチャ) またこの他にも,開発者自身が独自のアルゴリズムを実装するために用いることができる基本的機 能や便利な機能も備わっている.また,それらの機能を利用する際に必要なライブラリのうち本稿で 使用するのは次の 4 つである. • imgproc(フィルタ処理,エッジ抽出,色変換など) • highgui(ウィンドウ表示,画像や動画ファイルの入出力,カメラキャプチャ) • objdetect(顔や人体などのオブジェクト検出) • core(画像や行列データ構造の提供,図形描画) 1.2 ディジタル画像について 本稿において述べる画像は全てディジタル画像である.ディジタル画像とは 0 以上の整数で構成 される 2 次元配列で表現される.画像を構成する各要素を画素あるいはピクセル (pixel) と呼ぶ.グ レースケールの場合,0∼255 で表現する.この値が明るさであり,0 は完全な黒,255 は完全な白で ある.フルカラーの場合は各画素の値は 3 つの 0∼255 の値の組で表現する.この 3 つの組はそれぞれ R(赤)G(緑)B(青) の強さを表している.例えば (255, 0, 0) は赤で,(0, 0, 255) は青,(255, 255, 255) は白である.ただし,色の表現方法は RGB だけでなく方法によっては 4 つの組を使用する場合もあ る.1) 2 第 2 章 カメラキャプチャ 動画を処理するには,入力動画を複数の画像に分解しそれぞれに画像処理を行って出力する.そのた め動画を分解した画像の枚数分繰り返す while 文の中で画像を処理する場合と同じ処理を利用するこ とができる.以下にカメラ入力を画面に表示させるプログラムを掲載する. 1 2 3 4 #include #include #include #include "opencv2/objdetect/objdetect.hpp" "opencv2/highgui/highgui.hpp" "opencv2/imgproc/imgproc.hpp" "opencv2/core/core.hpp" 5 6 7 using namespace std; using namespace cv; 8 9 10 11 12 13 14 // @function main i n t m a i n ( i n t argc , c o n s t c h a r * * a r g v ) { // -- 1. Definition CvCapture* capture; Mat frame; 15 16 17 18 19 20 21 // -- 2. Load the cascades (Only for face detection) if( !face_cascade.load(face_cascade_name)) { printf("Error loading1\n"); r e t u r n -1; }; 22 23 24 25 26 // -- 3. Capture from camera and set size c a p t u r e = c v C a p t u r e F r o m C A M ( -1 ) ; c v S e t C a p t u r e P r o p e r t y ( capture , C V _ C A P _ P R O P _ F R A M E _ W I D T H , 6 4 0 ) ; c v S e t C a p t u r e P r o p e r t y ( capture , C V _ C A P _ P R O P _ F R A M E _ H E I G H T , 4 8 0 ) ; 27 28 29 30 31 32 33 34 35 // -- 4. Processing the video and show it if( capture ) { while( true ) { M a t dst , g r a y _ i m g ; M a t d s t 2 ( f r a m e . r o w s *0.5 , f r a m e . c o l s *2.0 , f r a m e . t y p e ( ) ) ; vector < Rect > f a c e s ; 36 37 38 frame = cvQueryFrame( capture ); / / P r o c e s s i n g functions - - - - - - - - - - - - - - - - - 3 第 2 章 カメラキャプチャ 39 // --------------------------------------------char c = cvWaitKey( 50 ); if( c == 27 ) break; imshow( "output_window" , frame ); 40 41 42 43 44 } 45 } return 0; 46 47 } カメラより動画をキャプチャするには highgui.hpp をインクルードする必要がある.ただし,後の 処理の為に必要な全てのライブラリも,既に表記している.また,2. Load the cascades および 4. Processing the video and show it 以下の std::vector<Rect> faces; は顔検出の場合のみ使用するが, 処理を行う部分のみを変更すれば違う処理ができるよう既に表記している.また以下に,動画を取り 込んで再生する際に使用するコードについて述べる. 1. cvCaptureFromCAM(-1) 0 以上の値に当てはめられたカメラを検出し,画像を取り込む関数.引数を-1 にすることで一 番始めに検出したカメラを使用する 2. cvSetCaptureProperty 取り込んだカメラデータより幅と高さを設定する関数. 3. cvQueryFrame cvCaptureFromCAM の戻り値を設定する関数.この while 文の中での役割をわかりやすくい うと,動画から画像を一枚だけ取り出すというものである. 4. cvWatiKey 画像を表示したとき何 ms 間表示し続けるかを指定する.動画の場合,() 内の数字が1枚あた りの表示時間を変えることができ,すなわち frame page per second[fps]をコントロールで きる. 5. if( c == 27 ) break; char c = cvWaitKey( 50 ); とともに使用し,esc キーを押すと while 文をスキップする. 4 第 3 章 動画処理 第 2 章のカメラキャプチャプログラム内の”Processing”と表記している部分に以下のコードを追加す ると各処理を行い,それを表示することができる. 3.1 ネガポジ反転 ネガポジ反転は各画素の濃淡を反転させることで,グレースケール画像であれば明るい画素は暗 く,暗い画素は明るくなる.RGB カラー画像の場合,R,G,B それぞれに対し,反転がおこる.こ のコードは単に入力に NOT 演算子をつけたもの,すなわち反転画像を出力画像とするという意味で ある.以下のコードでネガポジ反転を行うとができる. 1 d s t = ∼f r a m e ; ネガポジ反転を行った結果の例を Fig. 3.1.1 に示す. (a) 入力画像 (b) 出力画像 Fig. 3.1.1 ネガポジ反転の結果 (自作) 3.2 上下左右反転 出力画像の上下,左右,あるいは上下左右両方の反転を行う.以下のコードで上下左右の反転を行 うことができる.また,3 つめの引数が 0 のときは水平軸を中心に反転,1 のときは垂直軸を中心に 反転,-1 のときは両方を反転する. 1 f l i p ( frame , dst , 0 ) ; 上下左右反転を行った結果の例を Fig. 3.2.1 に示す. 3.3 サイズ変換 縦横の長さをそれぞれ独立して変えることができるため,画像のサイズを変えたり,縦長にしたり できる.変換した際,元画像にはなかったピクセルが必要になったり,存在していたピクセルが不要 になったりする.そこで補完を行い,自然なサイズ変換が行えるようにしている. 5 3.4 平滑化処理 第 3 章 動画処理 (a) 入力画像 (b) 上下反転 (c) 左右反転 (d) 上下左右反転 Fig. 3.2.1 上下左右反転の結果 (自作) 1 r e s i z e ( frame , dst2 , d s t 2 . s i z e ( ) , 0.5 , 2 , c v : : I N T E R _ C U B I C ) ; サイズ変換を行った結果の例を Fig. 3.3.1 に示す. (a) 入力画像 (b) 出力画像 Fig. 3.3.1 サイズ変換の結果 (自作) 3.4 平滑化処理 平滑化処理は一般にノイズを除去するための処理として利用される.平滑化には様々な手法があ るが,本稿ではガウシアンフィルタを用いたものと,バイラテラルフィルタを用いたものについて述 べる. 6 3.4 平滑化処理 3.4.1 第 3 章 動画処理 ガウシアンフィルタ ガウシアンフィルタによる平滑化は,以下のコードで行うことができる. 1 G a u s s i a n B l u r ( frame , dst , S i z e (5 , 5 ) , 10 , 1 0 ) ; ガウシアンフィルタによる平滑化を行った結果の例を Fig. 3.4.1 に示す. (a) 入力画像 (b) カーネルサイズ 5 (c) カーネルサイズ 11 Fig. 3.4.1 ガウシアンフィルタによる平滑化の結果 (自作) 平滑化の考え方のベースとなるのが,目的画素とその周辺の平均値を取るというものである.しか し一般的な画像において,目的画素から離れれば離れるほど目的画素の値との差が大きくなる.これ を考慮し,目的画素に近いほど重みを大きくするように式 (3.1) のガウス分布の関数を用いる.これ により単純に平均値を取るよりも自然で滑らかな平滑化が行える. f (x, y) = 1 x2 + y 2 exp(− ) 2πσ 2 2σ 2 (3.1) 式 (3.1) を用いてレートを計算しているのがガウシアンフィルタである.σ の値が大きくなるほど平 滑化の効果が大きくなる.ガウシアンフィルタによって得られるカーネルでよく用いられるのは Fig. 3.4.2 である.また上記のコードでは,3 つ目の引数がカーネルサイズ,4 つ目が Y 軸方向の σ ,5 つ 目が X 軸方向の σ を意味する. 3.4.2 バイラテラルフィルタ バイラテラルフィルタによる平滑化は以下のコードで行うことができる. 1 b i l a t e r a l F i l t e r ( frame , dst , 5 , 50 , 1 0 0 ) ; バイラテラルフィルタによる平滑化を行った結果の例を Fig. 3.4.3 に示す. ガウシアンフィルタなどのフィルタでは,エッジまで平滑化されてしまい,ぼけた画像になってし まうという欠点がある.これを解決するのがバイラテラルフィルタである.なお,バイラテラルフィ ルタは処理前の画像データの配列を f (i, j),処理後の画像データの配列を g(i, j) とすると式 (3.2) の ようになる. 7 3.4 平滑化処理 第 3 章 動画処理 1 1 ___ ___ 4 ___ 4 ___ 6 ___ 256 256 256 256 256 16 ___ 4 16 ___ 4 24 ___ ___ ___ 256 256 256 256 256 1 ___ ___ 2 ___ 1 16 16 16 ___ ___ ___ 2 4 2 16 16 16 ___ 1 2 ___ 1 ___ 16 16 16 ___ 6 256 4 ___ 256 24 ___ 24 ___ 36 ___ ___ 6 256 256 256 256 16 ___ 4 16 ___ 24 ___ ___ 256 256 256 256 1 1 ___ ___ 4 ___ 4 ___ 6 ___ 256 256 256 256 256 (a) 3 × 3 (b) 5 × 5 Fig. 3.4.2 ガウシアン分布によるカーネル (自作) (a) 入力画像 (b) カーネルサイズ 5 (c) カーネルサイズ 11 Fig. 3.4.3 バイラテラルフィルタによる平滑化の結果 (自作) 8 3.5 グレースケール化 w w ∑ ∑ g(x, y) = 第 3 章 動画処理 f (i + m, j + n) exp(− n=−w n=−w w ∑ m2 + n2 (f (i, j) − f (i + m, j + n))2 ) ) exp(− 2σ12 2σ22 w ∑ m2 + n2 (f (i, j) − f (i + m, j + n))2 exp(− ) exp(− ) 2σ12 2σ22 n=−w n=−w (3.2) w はカーネルのサイズ,σ1 がガウシアンフィルタを制御し,σ2 が輝度差を制御している.バイラテ ラルフィルタはガウシアンで用いたカーネルにさらに重みを変化させる.輪郭をぼかさずノイズのみ を除去するために,目的画素との値の差が大きいところは重みを小さく,差が小さいところでは重み を大きくする.この重みの振り分けを正規分布に従って行うため,その標準偏差である σ2 の値も平 滑化の効果に影響する. 3.5 グレースケール化 グレースケール化は以下のコードで行うことができる. 1 c v t C o l o r ( frame , dst , C V _ B G R 2 G R A Y ) ; グレースケール化を行った結果の例を Fig. 3.5.1 に示す. (a) 入力画像 (b) 出力画像 Fig. 3.5.1 グレースケール化の結果 (自作) 画像処理や画像認識は色情報に効果や精度を左右されるため,色を単純化すると処理が行いやすい 場合が多い.後に述べる 2 値化と顔検出がその例である.RGB からグレースケールに変換する際に はグレースケールの輝度値を Y として式 (3.3) が用いられる. Y = 0.299R + 0.587G + 0.114B 3.6 (3.3) 二値化 (大津法) 画像を白と黒の 2 つの色のみで表現された画像を 2 値画像といい,2 値画像に変換することを 2 値 化という.2 値化は閾値を設定し,それより値が大きいものは全て白に,小さいものは黒に変換する. 9 3.6 二値化 (大津法) 第 3 章 動画処理 この閾値が高すぎると出力画像の画素の多くは黒になってしまい,何の画像であったかわからなく なってしまう.逆に閾値が低すぎると多くの画素が白となってしまう.そこで最適な閾値を決定する 方法に大津法というものがある.3.5 のグレースケール化の関数の二つ目の引数を gray img に変え, それに続けて以下のコードを追加すると大津法による 2 値化が行える. 1 t h r e s h o l d ( gray_img , dst , 0 , 255 , c v : : T H R E S H _ O T S U ) ; 大津法によ 2 値化を行った結果の例を Fig. 3.6.1 に示す. (a) 入力画像 (b) 出力画像 Fig. 3.6.1 大津法による 2 値化の結果 (自作) 大津法では分離度という値が最大となる閾値をとる.分離度はクラス間分散とクラス内分散との比 で求めることができ,以下のように求める.閾値 t で 2 値化するとき,閾値よりも輝度値が小さい側 のクラスの画素数を n1 ,平均を m1 ,分散を σ1 ,輝度値が大きい側のクラスの画素数 n2 ,平均を m2 , 2 は 分散を σ2 ,画像全体の画素数を nt ,平均を mt ,分散を σt とする.このときクラス内分散 σw n1 n2 σ12 + σ2 n1 + n2 n1 + n2 2 (3.4) n1 (m1 − mt )2 + n2 (m2 − mt )2 n1 n2 (m1 − m2 )2 = n1 + n2 (n1 + n2 )2 (3.5) n1 m1 + n2 m2 n1 + n2 (3.6) n1 n2 (m1 − m2 )2 (n1 + n2 )2 (3.7) 2 σw = クラス間分散 σb2 は σb2 = ここで全体の平均 mt は mt = であるので式 (3.5) は σb2 = と表すことができる.ここで全分散 σt は 2 σt2 = σb2 + σw 10 (3.8) 3.7 顔検出 第 3 章 動画処理 σb2 σ2 = 2 b 2 2 σw σt − σb (3.9) ここで,全分散 σ − t は閾値に関係なく一定なので,クラス内分散σ − b2 が最大となる閾値を求めれ ばよいことがわかる.かつ,クラス内分散の式の分母も閾値に関係なく一定であるので,クラス間分 散の分子 n1 n2 (m1 − m2 )2 (3.10) が最大となる閾値 t を求めればよい.すなわち,黒白それぞれの領域のヒストグラムから画素数 n と画素値の平均値 m から式 (3.10) の最大値を出したときの閾値を最適な閾値と判断する. 3.7 顔検出 OpenCV のライブラリには顔の検出器が用意されている.入力画像をその検出器にかけると顔の 部分が検出できる.そこで下記のコードでは,顔を検出し,検出できた顔の中心に合わせて円を描い ている.2.5 のコードの二つ目の引数を gray img に変え,以下のコードを追加すると Haar-like によ る顔検出が行える. 1 2 3 4 5 6 7 f a c e _ c a s c a d e . d e t e c t M u l t i S c a l e ( gray_img , faces , 1.1 , 2 , 0 | CV _ H AAR_SCALE_IMAGE , S i z e (200 , 2 0 0 ) ) ; dst = frame; for( size_t i = 0; i < faces.size(); i++ ) { P o i n t c e n t e r ( f a c e s [ i ] . x + f a c e s [ i ] . w i d t h * 0.5 , f a c e s [ i ] . y + faces[i].height * 0.5 ); e l l i p s e ( dst , center , S i z e ( f a c e s [ i ] . w i d t h * 0.5 , f a c e s [ i ] . h e i g h t * 0 . 5 ) , 0 , 0 , 360 , S c a l a r (255 , 0 , 2 5 5 ) , 4 , 8 , 0 ); } 顔検出を行った結果の例を Fig. 3.7.1 に示す. (a) 入力画像 (b) 出力画像 Fig. 3.7.1 顔検出の結果 (自作) 11 3.7 顔検出 第 3 章 動画処理 OpenCV によって物体を検出するとき,Fig. 3.7.2 のような流れで行われる.本稿では,特徴量抽 出において Haar-like 特徴,学習において AdaBoost の機械学習アルゴリズムを扱う. Learning images Input image Feature value Feature value Learning Recognition Result for learning Input image Fig. 3.7.2 物体検出の流れ (参考文献 2) を参考に自作) 探索窓と呼ばれる矩形領域を Fig. 3.7.3 のように走査していき,その領域の中で特定の特徴を持っ た部分があるか調べていく.ここでいう特徴とはエッジや線,点などが画素値の差として現れている ことを指す. Fig. 3.7.3 探索窓による物体検出 (自作) 探索窓内においてどのような特徴があるかを Fig. 3.7.4 の形から探索する.Fig. 3.7.4 の白の部分 と黒部分の画素値の差が特徴量となる.また,探索窓ひとつに対しひとつの Haar-like 特徴を含み,ひ とつの探索窓がひとつの識別器として働く.これらの識別器は特徴の形や位置,サイズを様々に変え て約 12 万個用意されている.実際の学習の際にはそれらを複数組み合わせてより検出率の高い識別 器を構成する.AdaBoost を通すことで,最適な組み合わせ自動的に選択される.AdaBoost による 12 3.7 顔検出 第 3 章 動画処理 機械学習では数百の正と負の学習データを入力する必要がある.学習によって得られた検出器を用い て入力画像から物体検出を行うことができる. Edge features Line features Center surround feature Fig. 3.7.4 Haar-like 特徴 (参考文献 2) を参考に自作) 13 参考文献 1) 渡部広一, 三木光範. 画像情報処理. 共立出版, 2012. 2) slideshare「第 10 回 CV 勉強会 OpenCV 祭り 物体検出徹底解説」. 14