2004 年度 卒業研究 動画像のフィルタ処理 岡山理科大学 総合情報学部 情報科学科 澤見研究室 I01I006 東 大輔 目次 1 はじめに 2 2 開発環境 3 3 BMP 4 4 色空間 5 4.1 RGB 色空間 5 4.2 CMY 色空間 5 4.3 YCrCb 色空間 5 5 フィルタ 6 5.1 ネガフィルタ 7 5.2 グレースケールフィルタ 8 5.3 Sobel フィルタ 9 5.4 メディアンフィルタ 10 5.5 肌色抽出フィルタ 11 5.6 背景差分フィルタ 13 6 実験 14 6.1 抽出精度の向上 14 6.2 応用 14 7 まとめ 17 8 参考文献 18 1 1 はじめに 近年のコンピュータ性能の向上は著しく,多少複雑な計算でも難なく処理することが可 能となった.その結果,動画像を扱う機会も増え,個人レベルでの動画編集,処理も一般 的に行われるようになってきた.例えばゲーム業界ではコンシューマー機に USB カメラを 接続し,ユーザー自身の動きを介してプレイする作品が登場している.映画でよく見られ る近未来のコンピュータ操作方法が実現する日もそう遠くないかもしれない.そこで今回 はそういった処理の仕組みを理解するため動画像のフィルタ処理について研究を行った. 研究の流れは以下のようになる(図 1). 画像データの解析 必要部分の理解 フィルタの研究 フィルタの開発 図 1:研究の流れ 2 2 開発環境 実験に用いた装置一覧を表 1 に示す.USB 接続の web カメラは実験者の正面のやや高め に設置する. 表 1:実験装置一覧 装置 製品名 備考 … 計算機 カメラ Creative WebCam NX Ultra CPU Pentium4 2.6GHz Memory 2GB OS Windows XP SP2 フォーマット RGB24 解像度 320×240 フレームレート 30fps 動画像に対してリアルタイムに処理を行うことを条件とするので,実行速度が速い言語 を選ぶ必要がある.そこで C#,C++,Java,Perl,PHP を用いた場合の浮動小数点演算 による処理速度を比較し,最速の言語を選択することにする.計算内容は 0 ≤ x ≤ で π 2 π 2 の範囲 ×10 毎に sin ( x ) の近似値を算出することにした(表 2,図 2). −6 表 2:処理速度 言語 計算時間[ms] C++ 15 C# 109 Java 140 PHP 6807 Perl 9994 図 2:処理速度 結果より C++が最速であることが分かった.ここでは Microsoft Visual C++ 6.0 を使用 することにした.そしてコンポーネントとしてマニュアルやサンプルデータが豊富な DirectX 8.1 SDK を使用した. 3 3 BMP キャプチャ機材から取得するデータは 24bit の DIB(デバイス独立ビットマップ)であるが, DIB は BMP と仕組みは同じなので BMP について説明を行う. BMP とは Windows 標準のペイント系グラフィックデータのことである.表示される画 像の左上角を座標(0,0),右下角を座標(X,Y)としている.内部データは左上から右下までの各 画素の RGB 情報を羅列したもの,つまり高さ×幅×3 個の要素数を持つ配列のようなもの である.フィルタ処理はその情報を用いた演算をすることで実現している.24 ビットカラ ーを扱うので,プログラムでは BYTE 型のポインタを用いる(図 3). 255 255 255 … 200 200 200 … 134 134 134 … 72 72 0 … 102 249 210 200 10 0 0 0 … 10 210 10 … BYTE型 図 3:BMP 4 0 35 15 4 色空間 4.1 RGB 色空間 RGB 色空間とは加法混色により色を表現する方法である.Red,Green,Blue を光の 三原色にしており,RGB 値が等しい場合には数値を増すごとに白に近づき,減らすごと に黒くなる.コンピュータのモニタはこの RGB 色空間で表されている. 4.2 CMY 色空間 CMY 色空間とは減法混色により色を表現する方法である.Cyan,Magenta,Yellow を色の三原色にしており,CYM 値が等しい場合には数値を増すごとに黒に近づき,減ら すごとに白くなる.印刷物等はこの CMY 色空間で表されている.RGB 色空間とは補色 関係になっている(図 4). 図 4:RGB 色空間と CMY 色空間 4.3 YCrCb 色空間 画素の色を輝度と二つの色差で表す方法である.RGB 色空間と異なり明るさと色を独 立して扱うことが可能なので,明るさだけの増減,明るさを固定したまま色のバランス を変更,といった処理が容易である.また,光源の種類にあまり左右されずに色の違い を調べることが可能なので,特定色の抽出に使われている.RGB 色空間からの変換式を 次に示す(式 1).今回は肌色抽出フィルタとグレースケールフィルタを適用する際に用い ている. ⎛ Y ⎞ ⎛ 0.299 0.587 0.114⎞⎛ R⎞ ⎛ 0 ⎞ ⎜ ⎟ ⎜ ⎟⎜ ⎟ ⎜ ⎟ Cr = 0 . 500 − 0 . 419 − 0 . 081 ⎜ ⎟ ⎜ ⎟⎜G⎟ +⎜128⎟ ⎜Cb⎟ ⎜−0.169 −0.331 0.500⎟⎜ B⎟ ⎜128⎟ ⎠⎝ ⎠ ⎝ ⎠ ⎝ ⎠ ⎝ 5 (式 1) 5 フィルタ 原画像(図 5)に対してネガフィルタ,グレースケールフィルタ,Sobel フィルタ,肌色 抽出フィルタ,背景差分フィルタの各処理を行う. 図 5:原画像 6 5.1 ネガフィルタ 2 進数表記した RGB を bit 反転し,原画像のネガティブ画像を出力するフィルタであ る(図 6).フィルタ処理部分のプログラムはごく単純で以下のようになっている(プログラ ム 1). //ネガフィルタ for(Pointer = 0; Pointer < BufferSize; Pointer++ ) { WriteBuffer[Pointer] = (BYTE)~ReadBuffer[Pointer]; } プログラム 1:ネガフィルタ 図 6:ネガフィルタ 7 5.2 グレースケールフィルタ RGB データから輝度情報を求め,各画素に代入することで 256 階調のグレースケール に変換するフィルタである(図 7).プログラムは以下のようになっている(プログラム 2). //グレースケールフィルタ for(Pointer = 0; Pointer < BufferSize; Pointer += 3 ) { WriteBuffer[Pointer] = WriteBuffer[Pointer + 1] = WriteBuffer[Pointer + 2] = 0.299 * ReadBuffer[Pointer + 2] + 0.587 * ReadBuffer[Pointer + 1] + 0.144 * ReadBuffer[Pointer]; } プログラム 2:グレースケールフィルタ 図 7:グレースケールフィルタ 8 5.3 Sobel フィルタ 注目画素に関し,その周辺 8 近傍の画素を用いて微分演算することで,色が急激に変化 する場所,つまりエッジ部分を検出することができるフィルタである(図 8).オペレータ は水平方向(図 9),垂直方向に関して別個に定義してある(図 10). 1 0 −1 1 2 1 2 0 −2 1 0 −1 0 0 0 −1 − 2 −1 図 9:水平方向 図 10:垂直方向 プログラムは以下のようになっている(プログラム 3). //Sobel フィルタ for(Pointer = 0; Pointer < BufferSize; Pointer += 3) { WriteBuffer[Pointer] = WriteBuffer[Pointer+1] = WriteBuffer[Pointer+2]= sqrt(pow(ReadBuffer[Pointer+Width-3]-ReadBuffer[Pointer+Width+3]+( ReadBuffer[Pointer-3]<<1)-(ReadBuffer[Pointer+3]<<1)+ReadBuffer[Poi nter-Width-3]-ReadBuffer[Pointer-Width+3],2)+pow(ReadBuffer[Pointer+ Width-3]+(ReadBuffer[Pointer+Width]<<1)+ReadBuffer[Pointer+Width+ 3]-ReadBuffer[Pointer-Width-3]-(ReadBuffer[Pointer-Width]<<1)-ReadBu ffer[Pointer-Width+3],2)); } プログラム 3:Sobel フィルタ 図 8:Sobel フィルタ 9 5.4 メディアンフィルタ 注目画素に関し,その周辺 8 近傍の RGB 値をソートし,中間の値を注目画素に代入す ることでノイズを低減するフィルタである.2 値化画像に関するプログラムを以下に示す (プログラム 4). //メディアンフィルタ for(I = Width + 3; I < BufferSize – Width - 3; I += 3) { count = 0; for(j = -3; j <= 3; j += 3) { if(ReadBuffer[i + Width + j] == ReadBuffer[i]) { count++; } if(ReadBuffer[i + j] == ReadBuffer[i]) { count++; } if(ReadBuffer[i - Width + j] == ReadBuffer[i]) { count++; } if(count >= 5) { break; } } if(count < 5) { WriteBuffer[i] = WriteBuffer[i + 1] = WriteBuffer[i + 2] = ~ReadBuffer[i]; } } プログラム 4:メディアンフィルタ 10 5.5 肌色抽出フィルタ RGB 色空間は明るさの変化に敏感なため肌色領域の抽出には向いていない.そこで, YCrCb 色空間をはじめとする他の色空間に変換してから抽出処理を行う手法が良く用い られる.今回は YCrCb 色空間を用いて肌色領域の抽出を行う. RGB を YCrCb に変換し,明るさに敏感な輝度情報 Y を無視し,Cr,Cb に関する要 素を閾値として設定し,色要素を抜き出している.肌色領域中の画素の Cr と Cb の値は, 以下の条件を満たす. 133 ≤ Cr ≤ 173 , 77 ≤ Cb ≤ 127 (式 2) 肌色領域を抽出した結果は次のようになる(図 9).プログラムは以下のようになっている (プログラム 5). //肌色抽出フィルタ for(Pointer = 0; Pointer < BufferSize; Pointer += 3) { Cr = (BYTE)(0.5 * ReadBuffer[Pointer + 2] - 0.418 * ReadBuffer[Pointer + 1] - 0.081 * ReadBuffer[Pointer] + 128); Cb = (BYTE)(-0.168 * ReadBuffer[Pointer + 2] - 0.331 * ReadBuffer[Pointer + 1] + 0.5 * ReadBuffer[Pointer] + 128); if((133 <= Cr) && (Cr <= 173) && (77 <= Cb) && (Cb <= 127)) { WriteBuffer[Pointer + 2] = ReadBuffer[Pointer + 2], WriteBuffer[Pointer + 1] = ReadBuffer[Pointer + 1], WriteBuffer[Pointer] = ReadBuffer[Pointer]; } else { WriteBuffer[Pointer + 2] = WriteBuffer[Pointer WriteBuffer[Pointer] = 0; } } プログラム 5:肌色抽出フィルタ 11 + 1] = 図 9:肌色抽出フィルタ 12 5.6 背景差分フィルタ あらかじめ背景画像を取得しておき,入力画像で差分をとった値を閾値として,入力画 像を切り抜き,合成するフィルタである.単純に背景画像と入力画像との差分値を閾値と するとノイズの関係上精度が低くなる.そこで最小二乗法により補完処理を行っている. 背景画像を原画像(図 5)とし,手をかざした画像を背景差分フィルタ(図 10)とする.プロ グラムは以下のようになっている(プログラム 6). //背景差分フィルタ for(Pointer = 0; Pointer < BufferSize; Pointer += 3) { d = sqrt(pow(ReadBuffer[Pointer] pow(ReadBuffer[Pointer + 1] - - BGBuffer[Pointer], BGBuffer[Pointer + 1], 2) + 2) + pow(ReadBuffer[Pointer + 2] - BGBuffer[Pointer + 2], 2)); if(d > 50) { WriteBuffer[Pointer] = ReadBuffer[Pointer], WriteBuffer[Pointer + 1] = ReadBuffer[Pointer + 1], WriteBuffer[Pointer + 2] = ReadBuffer[Pointer + 2]; } else { WriteBuffer[Pointer] = WriteBuffer[Pointer + 1] = WriteBuffer[Pointer + 2] = 0; } } プログラム 6:背景差分フィルタ 図 10:背景差分フィルタ 13 6 実験 6.1 抽出精度の向上 先に説明した肌色抽出フィルタ,メディアンフィルタ,背景差分フィルタを用いて, 肌色抽出の精度を高める実験を行った.背景画像を原画像(図 5)とし,手をかざし,処理 を行った.適用するフィルタの順序は肌色抽出フィルタ⇒メディアンフィルタ⇒背景差 分フィルタとしている.まず肌色抽出フィルタで肌色候補を抜き出す(図 11).この段階で は背景の木質部分も抜かれており,肌色の近似色が抽出されているのがわかる.また明 らかに肌色である指先が抜き出されていないなど,精度の低さが確認できる.次に肌色 候補(図 11)にメディアンフィルタをかけることでノイズを低減させている(図 12).これ により先ほどの指先部分が補完され肌色部分が全て抜き出せることを確認できる.最後 に背景差分フィルタをかけることで背景と入力画像を切り離す.これにより木質部分が 除かれ,肌色領域の抽出が完了する.結果画像(図 13)と肌色候補(図 11)を比較すれば, 抽出精度が高まっているのは明らかであり,この実験は成功といえる. 6.2 応用 先の実験(6.1)により正確に肌色領域を抽出することが可能となったので,肌色領域を インターフェイスとする以下のゲームを作成した. ・肌色で画面の緑色を消し,隠された画像を表示させるゲーム 1(図 14) ・画面中を跳ねているボールを相手ゴールに入れるゲーム 2(図 15) 図 11:肌色候補 14 図 12:肌色+メディアンフィルタ 図 13:肌色+メディアン+背景差分 15 図 14:ゲーム 1 図 15:ゲーム 2 16 7 まとめ 今回実現した肌色抽出フィルタの応用として手をポインティングデバイスとして利用す るプログラムも作成したが,ごく限られた条件でしか正常な動作を期待できないものにと どまっている.課題としては,画面内に複数人の手が存在する場合の処理をどうするか, 照明による挙動のちらつきをどう抑えるか,カメラの視野の端での操作感の悪さをどうす るか,などが挙げられる. 発光ダイオードを指先に装着し,抽出領域に加えることで挙動のちらつきをなくすこと は可能であるが,手だけでは思うような操作ができないので気楽さに欠けるようであった. これを解決するためには Cr,Cb だけでなく Y も加えて 3 次元で抽出する方法もいいかも しれない.もしくは色空間自体を改める必要があるかもしれない.また,カメラ 2 台を角 度を付けて接続し,視野を広げることで操作感の向上が望めるものと思われる. 17 8 参考文献 (1)土井研究室,”DirectXMedia 改め DirectX な日々”, http://wwwdoi.elec.nara-k.ac.jp/html/jisyu/dxm/ (2)mtws project,”mtws project hp”, http://mtws.sytes.net/ (3)加藤研究室,”プログラミング/キャプチャ”, http://www.katolab.ee.kagu.sut.ac.jp/programing/capture.htm (4)川嶋宏彰,”Capturing with IEEE-1394 Firewire Camera under Windows2000 & DirectX”, http://vision.kuee.kyoto-u.ac.jp/~hiroaki/firewire (5)MasashiKatsumata,”WinAPI Database”, http://www.geocities.co.jp/SiliconValley-Cupertino/5872/ (6)feconi,” C# と C++, Java, Perl, PHP の速度を比較してみる”, http://feconi.azo.to/csharp/compare02.php (7)宍戸 輝光,”DIB とグラフィック処理実験室”, http://www.sm.rim.or.jp/~shishido/graphics.html (8)林 晴比古,”新 Visual C++ 6.0 入門シニア編”, ソフトバンク パブリッシング株式会社 (9)林 晴比古,”新 C++言語入門シニア編”, ソフトバンク パブリッシング株式会社 18
© Copyright 2024 Paperzz