#論考5 [和訳と要約](※Only興味のあるところ)Learning_OpenCV3_Computer_Vision_with_Python_2nd_Edition (1)
※Learning_OpenCV3_Computer_Vision_with_Python_2nd_Edition
のフルヤ和訳→フルヤ要約(1)(※興味のあるところだけ抜粋)
【顔追尾とImage操作】tracking / image manupulation on camera
並列する2つのInputを分析することで、リアルタイムでの顔認識を可能にします。
加えて録画済みのデータについてもこれらは適応可能です。
これらStream同士で検出された顔情報をSuperImpose、ブレンドされ
FilterやDistortionがリアルタイムで適応されます。
(The application will superimpose faces from one stream onto faces in the other...)
【オブジェクト志向型の動画分析】
これらリアルタイムでの顔編集はライブパフォーマンス的で、例えばDisneylandのアトラクションなどで多用されます。
OpenCVで動画がImageに還元される際には、SourceやDestinationと関係なく、
ほぼ全て同質にそれらを扱うことが可能です。
どのようにgetされsetされるにせよ、同様のロジックを適用することが可能です。
この際I/OのコードとApplicationのコードは分離して構築されます。
まず、CaptureManagerとWindowManagerというクラス。
ApplicationコードはCaptureManagerクラスを用いて新しいFrameを読み取り、
各フレームを任意の数のoutputへDispatchします。
この際送信されるデータは、
原型のimageFile、再構築されたVideoFile、或いはWindowManagerクラスを経由したWindow用表示データなどです
CaptureManager,WindowManagerは同時に拡張性と柔軟性を持っています。
カスタマイズすることで、OpenCVに頼らず、その他のフレームワークにも適応が可能です。
【VideoStreamの抽象化_CaptureManager】
OpenCVはVideo、Cameraより”Stream of Image”をキャプチャしたり、閲覧したり、操作したりする。
CaptureManagerクラスはそれらデータを抽象化し、Outputまでの流れを担うものだ。
CaptureManagerクラスは、VideoCaptureクラスと共に初期化。
クラス内包として、enterFrame()とexitFrame()Methodを持つ。
これらはApplication内のMainLoop中に呼び出されて機能する。
Applicationは呼び出しの最中に、”channel”Propertyをset,"frame"Propertyをgetするかもしれない
”channel”Propertyは初期値0。マルチヘッドカメラ使用時にことなる値を設定する可能性がある。
”frame”Propertyは、enterFrame()が呼ばれた再の最新のChannel情報に一致するImageデータを格納する。
同時にCaptureManagerは
WriteImage(),startWritingVideo(),stopWritingVideo() Method を持ち、柔軟にあらゆる側面で利用が可能です。
上記のメソッドは内部的処理を進めますが、実際のファイルライトは、exitFrame()の実行まで保留されています。
exitFrame()が実行された際は、"frame"Propertyがwindow表示される場合もあります。
その際、ApplicationCodeはWindowManagerクラスを、CaptureManagerのConstructerの引数として渡す。
或いは"previewWindowManager"Propertyを設定するかどちらかを行います。
もしAppllicationCodeがframeを操作する場合、
その操作は録画されたファイルかWindowの表示データに反映されます。
CaptureManagerクラスは引数とプロパティとしてshouldMirrorPreviewを持っています。
もしデータを鏡像として表示させたい際は、Trueに設定することでhorizontallyFlippedされたデータを表示することが可能です。
VideoWriterクラスがFPSのデータを必要とすることを思い出してください。
しかしながらOpenCVは正確なフレームレートを検出しません。
変わりにCaptureManagerクラスは、frameカウンターとPythonの認識している標準時間を用いることで
これを解決します。Pythonの標準時間は time.time() 関数で、必要となればこれを用いて時間計測を行います。
しかしながらこのやり方は安易なものではありません。
time.time()はシステム依存性があり、FPSは可変的なものだからです。
算出結果は不正確なものである場合も少なくありません。
まずはmanagers.py を制作します。
これはCaptureManager実行用です。
( PythonはPrivateを定義しないので
)ここではUnderscoreで定義された変数を用意します。 例: self._enteredFrame.
これらは、現在読み取り中のframeやその他のファイルライト操作に関連したものでデコレータで定義されます
※@property は自分で定義したObjectから値を取得したり更新したり削除したりする。
enterFrame()は、Frameをglab(=Synchronizes)するのみ。
実際のchannelからの保存は後続するframe変数を待つことになる
exitFrame()はCurrentChannelからimageを取得。フレームレートを算出し
WindowManagerを経由してWindowに表示させる。
その一方でチャンネルからの確実な保存は、frame変数の読み込みを待っている。
そして、exitframe()は、現在のチャンネルのイメージを引き受け、FPSを見積もり、もしあればイメジをWindowManagerに表示。
そして保留されている全てのファイルへのイメージ書き込みを引き受ける。
以下に記述するその他のメソッドに関してはやはり(exitframe()同様、ファイル書き込みに関連している。
【cameoClass】
Application部分の実装に関しては、Cameoクラスが実装します。
Cameoクラスは2つのメソッドを持っています。run() onKeypress()です。
初期化の際、CameoクラスはWindowManagerクラスをonoKeypress()をコールバックとして構成します。
run()が呼ばれたとき、ApplicationはMainLoopを実行します。
この時MainLoopではframeとeventが実行されています。
eventの実行結果として、onKeypress()を呼ぶことも出来ます。
SpacebarでScreenshotを。TabでScreenCast(Recording)のStart/Stopを。
EscでApplicationを終了したりといった命令を与えることが出来ます。
Application起動時、Liveカメラのフィードはミラーされます。
しかし一方でscreenshotsやscreencastsはされません。
CaptureManager初期化の際、shouldMirrorPreview をTrueにしているからです。
【Prrocessing Images with OpenCV 3】
遅かれ早かれ、Imageそのものの編集は必要になります。
◆色空間と編集特性
Gray 色情報が極限まで少ないので、FaceDetectionに適している。
BGR 全てのpixelは8bit3列のArrayに格納される。Web系は親和性が高いがRGBの順番で扱う
HSV H:hueはtone。saturationは密集度、valueは明暗
◆BGR
[0 255 255](no blue, full green, and full red) →Yellow
となる。これは光の属性であって、もし絵の具でやったらマッディbrownになろう。
これはBGR(RGB)がadditiveだからだ。絵の具はsubtractiveである。
絵具にメディウムがあるように、monitorのメディウムは光であり、
moniterは光をemitすることでそれを表現するからだ。
【Fourier Transform】
フーリエ変換は様々な画像変換において中核になる。
フーリエは18世紀フランスの数学者で、様々な数学的発見をしている。
中でも熱原則に関する研究に集中しており、彼は全てをwaveformとした。
彼は全てのwaveformは、単純に異なる周波数の組み合わさった類同としたのだ。
言い換えるならば、私体の周囲で確認できるwaveformは、異なるwaveformsの総和なのだということ。
この概念は画像解析においては非常に有用である。
これによってpixelのシグナルが大きく変わる部分を領域境界線として認識することが可能だからだ。
この機能を用いて、ノイズかInterestか、backgroundかforegrandか等が判別しうる。
Numpyライブラリは離散フーリエ変換のMethod(fft2())を実装しており、
この複雑な計算を容易に処理することが出来る。
magniturde spectrum はフーリエ変換の原理から構成されている。
これはimageを変化の点から捉えるもので、
最も明るいpixelをcenterに集め、外縁に向けてグラデーションし端部で最も暗くなると考える
とわかりやすい。
この構図に変換することで、
1つのイメージの中にどれだけのlight/Dark_pixelが含まれているか、そのdistributionはどの程度か
を用意に知ることが出来る。
フーリエ変換はImage変換におけるあらゆるアルゴリズムの根本に位置している
例えばエッヂ検出やシェイプ検出。
具体例の簡易的なものとして、まずはHPFとLPFについて見てみたい。
◆HighPassFilter(HPF )
HPFはある領域に対して周囲のピクセルとの差異に応じて
intensityを付与するエフェクトです。
この仕組に酔って、対象範囲内はその他の領域と比べboostされます
言い換えればその部分は顕著に目立つようになるということです。
これは特別優秀なedge detectionです。
◆LowPassFilter
HPFがpixelIntensityを操作するのなら、
LPFは周囲との差異に応じて低い方を通す
これはでノイズやブラーに向いている
最もポピュラーなのはGaussianBlur
※高周波数のデータを弱める(attenuate)することは、柔らかくする。
CF◆Convolution 畳み込み演算
足し算の結果を足し集める演算。マトリックスで指定される
→Operator,Filter,Mask,Kernel
【EdgeDetection】
Edgeは人間にとってもマシンにとっても重要だろう
Edgeによって私達は、逆光でも物体の種類やポーズを判別、ラフスケッチをする。
OpenCVはたくさんのエッヂ検出フィルターを持っている。
Laplacian(),Sobel(),Scharr()
これらは非エッジ領域を黒、エッジを白か強調色で彩色します。
しかし、これはしばしばノイズをエッヂと認識してしまうので不正確です。
この欠点に関しては、イメージをblurしてから処理を行うことで軽減できます。
blur(),medianBlur(),GaussianBlur()
同時にグレイスケールに変換することも効果的です。
通例
*1:3,3),dtype=np.uint8)
print(img)
【結果】
array([[0, 0, 0],
[0, 0, 0],
[0, 0, 0]], dtype=uint8)
全てのpixelはsingle 8-bit integer 表現される。
つまり、全て0-255の尺度を持つ