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
章 カメラキャプチャ
動画を処理するには,入力動画を複数の画像に分解しそれぞれに画像処理を行って出力する.そのた め動画を分解した画像の枚数分繰り返すwhile文の中で画像を処理する場合と同じ処理を利用するこ とができる.以下にカメラ入力を画面に表示させるプログラムを掲載する. 1 # i n c l u d e " o p e n c v 2 / o b j d e t e c t / o b j d e t e c t . h p p " 2 # i n c l u d e " o p e n c v 2 / h i g h g u i / h i g h g u i . h p p " 3 # i n c l u d e " o p e n c v 2 / i m g p r o c / i m g p r o c . h p p " 4 # i n c l u d e " o p e n c v 2 / c o r e / c o r e . h p p " 5 6 u s i n g n a m e s p a c e s t d ; 7 u s i n g n a m e s p a c e c v ; 8 9 / / @ f u n c t i o n m a i n 10 i n t m a i n ( i n t a r g c , c o n s t c h a r * * a r g v ) 11 { 12 / / - - 1 . D e f i n i t i o n 13 C v C a p t u r e * c a p t u r e ; 14 M a t f r a m e ; 15 16 / / - - 2 . L o a d t h e c a s c a d e s ( O n l y f o r f a c e d e t e c t i o n ) 17 i f ( ! f a c e _ c a s c a d e . l o a d ( f a c e _ c a s c a d e _ n a m e ) ) 18 { 19 p r i n t f ( " E r r o r l o a d i n g 1 \ n " ) ; 20 r e t u r n -1; 21 } ; 22 23 / / - - 3 . C a p t u r e f r o m c a m e r a a n d s e t s i z e 24 c a p t u r e = c v C a p t u r e F r o m C A M ( -1 ) ; 25 c v S e t C a p t u r e P r o p e r t y ( c a p t u r e , C V _ C A P _ P R O P _ F R A M E _ W I D T H , 6 4 0 ) ; 26 c v S e t C a p t u r e P r o p e r t y ( c a p t u r e , 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 / / - - 4 . P r o c e s s i n g t h e v i d e o a n d s h o w i t 29 i f ( c a p t u r e ) 30 { 31 w h i l e ( t r u e ) 32 { 33 M a t dst , g r a y _ i m g ; 34 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 ( ) ) ; 35 v e c t o r < R e c t > f a c e s ; 36 37 f r a m e = c v Q u e r y F r a m e ( c a p t u r e ) ; 38 / / P r o c e s s i n g f u n c t i o n s-第2 章 カメラキャプチャ 39 40 / / -41 c h a r c = c v W a i t K e y ( 5 0 ) ; 42 i f ( c = = 2 7 ) b r e a k ; 43 i m s h o w ( " o u t p u t _ w i n d o w " , f r a m e ) ; 44 } 45 } 46 r e t u r n 0 ; 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;
第
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 ( f r a m e , dst , 0 ) ; 上下左右反転を行った結果の例をFig. 3.2.1に示す.3.3
サイズ変換
縦横の長さをそれぞれ独立して変えることができるため,画像のサイズを変えたり,縦長にしたり できる.変換した際,元画像にはなかったピクセルが必要になったり,存在していたピクセルが不要 になったりする.そこで補完を行い,自然なサイズ変換が行えるようにしている.3.4平滑化処理 第3 章 動画処理 (a)入力画像 (b)上下反転 (c)左右反転 (d)上下左右反転 Fig. 3.2.1 上下左右反転の結果(自作) 1 r e s i z e ( f r a m e , d s t 2 , 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
平滑化処理
平滑化処理は一般にノイズを除去するための処理として利用される.平滑化には様々な手法があ るが,本稿ではガウシアンフィルタを用いたものと,バイラテラルフィルタを用いたものについて述 べる.3.4平滑化処理 第3 章 動画処理 3.4.1 ガウシアンフィルタ ガウシアンフィルタによる平滑化は,以下のコードで行うことができる. 1 G a u s s i a n B l u r ( f r a m e , 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 2πσ2exp(− x2+ y2 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 ( f r a m e , dst , 5 , 50 , 1 0 0 ) ; バイラテラルフィルタによる平滑化を行った結果の例をFig. 3.4.3に示す. ガウシアンフィルタなどのフィルタでは,エッジまで平滑化されてしまい,ぼけた画像になってし まうという欠点がある.これを解決するのがバイラテラルフィルタである.なお,バイラテラルフィ ルタは処理前の画像データの配列をf (i, j),処理後の画像データの配列をg(i, j)とすると式(3.2)の ようになる.
3.4平滑化処理 第3 章 動画処理 16 16 16 16 16 16 16 16 16
___
___
___
___
___
___
___
___
___
1 1 1 1 2 2 2 2 4 (a) 3×3 256___
___
___
___
___
___
___
___
___
1 24 24 4 256 256 6 4 256 256 256 256 256 256 6 16 36___
___
___
24 4 256 256 256 16 256___
___
___
1 4 256 256 6___
___
___
4 24 256 256 256 16___
256 16___
4 256 256___
___ ___
1 4 256 256 6___
4 256 256___
1 (b) 5×5 Fig. 3.4.2 ガウシアン分布によるカーネル(自作) (a)入力画像 (b)カーネルサイズ5 (c)カーネルサイズ11 Fig. 3.4.3 バイラテラルフィルタによる平滑化の結果(自作)3.5グレースケール化 第3 章 動画処理 g(x, y) = w ∑ n=−w w ∑ n=−w f (i + m, j + n) exp(−m 2+ n2 2σ12 ) exp(− (f (i, j)− f(i + m, j + n))2 2σ22 ) w ∑ n=−w w ∑ n=−w exp(−m 2+ n2 2σ12 ) exp(− (f (i, j)− f(i + m, j + n))2 2σ22 ) (3.2) wはカーネルのサイズ,σ1がガウシアンフィルタを制御し,σ2が輝度差を制御している.バイラテ ラルフィルタはガウシアンで用いたカーネルにさらに重みを変化させる.輪郭をぼかさずノイズのみ を除去するために,目的画素との値の差が大きいところは重みを小さく,差が小さいところでは重み を大きくする.この重みの振り分けを正規分布に従って行うため,その標準偏差であるσ2の値も平 滑化の効果に影響する.
3.5
グレースケール化
グレースケール化は以下のコードで行うことができる. 1 c v t C o l o r ( f r a m e , 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.3)3.6
二値化 (大津法)
画像を白と黒の2つの色のみで表現された画像を2値画像といい,2値画像に変換することを2値 化という.2値化は閾値を設定し,それより値が大きいものは全て白に,小さいものは黒に変換する.3.6二値化(大津法) 第3 章 動画処理 この閾値が高すぎると出力画像の画素の多くは黒になってしまい,何の画像であったかわからなく なってしまう.逆に閾値が低すぎると多くの画素が白となってしまう.そこで最適な閾値を決定する 方法に大津法というものがある.3.5のグレースケール化の関数の二つ目の引数をgray imgに変え, それに続けて以下のコードを追加すると大津法による2値化が行える. 1 t h r e s h o l d ( g r a y _ i m g , dst , 0 , 2 5 5 , 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,画像全体の画素数をnt,平均をmt,分散をσtとする.このときクラス内分散σw2 は σw2 = n1 n1+ n2 σ12+ n2 n1+ n2 σ22 (3.4) クラス間分散σb2は σb2 = n1(m1− mt) 2+ n 2(m2− mt)2 n1+ n2 = n1n2(m1− m2) 2 (n1+ n2)2 (3.5) ここで全体の平均mtは mt= n1m1+ n2m2 n1+ n2 (3.6) であるので式(3.5)は σb2= n1n2(m1− m2) 2 (n1+ n2)2 (3.7) と表すことができる.ここで全分散σtは σ2t = σ2b + σ2w (3.8)
3.7顔検出 第3 章 動画処理 σb2 σ2 w = σ 2 b σ2 t − σb2 (3.9) ここで,全分散σ− tは閾値に関係なく一定なので,クラス内分散σ− b2が最大となる閾値を求めれ ばよいことがわかる.かつ,クラス内分散の式の分母も閾値に関係なく一定であるので,クラス間分 散の分子 n1n2(m1− m2)2 (3.10) が最大となる閾値tを求めればよい.すなわち,黒白それぞれの領域のヒストグラムから画素数n と画素値の平均値mから式(3.10)の最大値を出したときの閾値を最適な閾値と判断する.
3.7
顔検出
OpenCVのライブラリには顔の検出器が用意されている.入力画像をその検出器にかけると顔の 部分が検出できる.そこで下記のコードでは,顔を検出し,検出できた顔の中心に合わせて円を描いている.2.5のコードの二つ目の引数をgray imgに変え,以下のコードを追加するとHaar-likeによ
る顔検出が行える. 1 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 ( g r a y _ i m g , f a c e s , 1 . 1 , 2 , 0 | C V _ H A A R _ S C A L E _ I M A G E , S i z e ( 2 0 0 , 2 0 0 ) ) ; 2 d s t = f r a m e ; 3 f o r ( s i z e _ t i = 0 ; i < f a c e s . s i z e ( ) ; i + + ) 4 { 5 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 + f a c e s [ i ] . h e i g h t * 0 . 5 ) ; 6 e l l i p s e ( dst , c e n t e r , 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 , 3 6 0 , S c a l a r ( 2 5 5 , 0 , 2 5 5 ) , 4 , 8 , 0 ) ; 7 } 顔検出を行った結果の例をFig. 3.7.1に示す. (a)入力画像 (b)出力画像 Fig. 3.7.1 顔検出の結果(自作)
3.7顔検出 第3 章 動画処理 OpenCVによって物体を検出するとき,Fig. 3.7.2のような流れで行われる.本稿では,特徴量抽 出においてHaar-like特徴,学習においてAdaBoostの機械学習アルゴリズムを扱う. Learning images Learning Feature value
Result for learning
Input image Feature value Recognition 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による
3.7顔検出 第3 章 動画処理
機械学習では数百の正と負の学習データを入力する必要がある.学習によって得られた検出器を用い て入力画像から物体検出を行うことができる.
Edge features
Line features
Center surround feature
参考文献
1) 渡部広一,三木光範. 画像情報処理. 共立出版, 2012.