Core Imageの顔認識をOS Xで - その4 [OpenCV関係]
映像のクリエータにとってピクセルフォーマットは表現に関わる重要な問題かもしれない。でも僕みたいなプログラマにとってピクセルフォーマットはカラーかグレーかぐらいしか問題にはならない。カラー画像のRGBかCMYKかあるいは色空間がsRGBかAdobeRGBなのかなんていうのは好きにしてもらっていい、というスタンスである。しかし、どうしてもピクセルフォーマットに関わらなくてはならいときもある。それが表現に影響するならちょっとはがんばろうと思うけど、まったくそうでないこともある。
この場合は4:2:2コンポーネントの形式が一番いい、と言っている。これは入力デバイスに関係なくこれが配列の先頭になっているので、生に近い(カメラはベイヤ配列である、あるいは伝送路での形式に近い)ということを前提にしているようであるが、ちょっとレガシーな感じがしないでもない。
しかし後の扱いはコンポーネント形式ではあまり便利でない。今回の場合CIImageで使える8ビットARGBフォーマットが含まれている(0x20)のでこれで出力させる。そのためにAVCaptureVideoDataOutputが
とりあえずこうするとCMSampleBufferの中の画像データフォーマットはARGBになってメモリの領域をコピーするだけでCIImageのインスタンスを作ることができる。
しかしこんなのもう少し簡単にすべきだよなあ。少なくとも僕にとってはまったくどうでもいい。こういうことは、普通のプログラマから隠蔽するのがCocoa/Objective-Cの思想じゃないのかなあ。
4.3 AVCaptureVideoDataOutputのピクセルフォーマット指定
実はAV Foundationのデータ出力オブジェクトであるAVCaptureVideoDataOutputでは、ピクセルフォーマットを指定できる。さっきのCVImageBufferのCVPixelBufferGetPixelFormatType()で返るフォーマットはこの指定に従う。ただし、AVCaptureVideoDataOutput* dataOutput = [[AVCaptureVideoDataOutput alloc]init]; NSArray *ftypes = [dataOutput availableVideoCVPixelFormatTypes];で返ってくるフォーマットタイプのなかのものしか使えない。このNSArrayはさっきのフォーマット定数がNSNumberのインスタンスとして入っている。例えば僕のiMac(10.8)でこの配列を書き出させると
2013-07-26 07:28:16.259 CIDetectorTest[3512:303] '2vuy' 0x32767579 2013-07-26 07:28:16.259 CIDetectorTest[3512:303] 'yuvs' 0x79757673 2013-07-26 07:28:16.260 CIDetectorTest[3512:303] ' ' 0x20 2013-07-26 07:28:16.260 CIDetectorTest[3512:303] 'BGRA' 0x42475241 2013-07-26 07:28:16.260 CIDetectorTest[3512:303] ' ' 0x18 2013-07-26 07:28:16.260 CIDetectorTest[3512:303] ' ' 0x10 2013-07-26 07:28:16.261 CIDetectorTest[3512:303] 'B565' 0x42353635 2013-07-26 07:28:16.261 CIDetectorTest[3512:303] 'L555' 0x4C353535 2013-07-26 07:28:16.261 CIDetectorTest[3512:303] 'L565' 0x4C353635 2013-07-26 07:28:16.261 CIDetectorTest[3512:303] '5551' 0x35353531 2013-07-26 07:28:16.262 CIDetectorTest[3512:303] 'v308' 0x76333038 2013-07-26 07:28:16.262 CIDetectorTest[3512:303] 'v408' 0x76343038 2013-07-26 07:28:16.262 CIDetectorTest[3512:303] 'v216' 0x76323136 2013-07-26 07:28:16.262 CIDetectorTest[3512:303] 'v210' 0x76323130 2013-07-26 07:28:16.263 CIDetectorTest[3512:303] 'v410' 0x76343130となっている。文字として読めないのは、みっつめが8ビットARGB、いつつめが8ビットRGB、むっつめがRGB各5ビットビッグエンディアン16ビット整数のフォーマットである。Referenceによるとこの配列の一番最初のが一番効率のいいフォーマットである、となっている。これ以外はフォーマット変換が発生する、ということなんだろう。さてここで、このなかにRGBAがない、ということに注意する必要がある。
この場合は4:2:2コンポーネントの形式が一番いい、と言っている。これは入力デバイスに関係なくこれが配列の先頭になっているので、生に近い(カメラはベイヤ配列である、あるいは伝送路での形式に近い)ということを前提にしているようであるが、ちょっとレガシーな感じがしないでもない。
しかし後の扱いはコンポーネント形式ではあまり便利でない。今回の場合CIImageで使える8ビットARGBフォーマットが含まれている(0x20)のでこれで出力させる。そのためにAVCaptureVideoDataOutputが
@property(nonatomic, copy) NSDictionary *videoSettingsというプロパティを持っていてこれにkCVPixelBufferPixelFormatTypeKeyをキーにしてフォーマットの定数を設定した辞書を渡せばいい。つまり
NSNumber *argbformat = [NSNumber numberWithInt:kCVPixelFormatType_32ARGB]; NSDictionary *dic = [NSDictionary dictionaryWithObject:argbformat forKey:kCVPixelBufferPixelFormatTypeKey]; dataOutput.videoSettings = dic;とすればいい、ということになる。このvideoSettingsというプロパティではいまのところこのkCVPixelBufferPixelFormatTypeKeyキーしか意味がない。
とりあえずこうするとCMSampleBufferの中の画像データフォーマットはARGBになってメモリの領域をコピーするだけでCIImageのインスタンスを作ることができる。
しかしこんなのもう少し簡単にすべきだよなあ。少なくとも僕にとってはまったくどうでもいい。こういうことは、普通のプログラマから隠蔽するのがCocoa/Objective-Cの思想じゃないのかなあ。
2013-07-30 21:44
nice!(0)
コメント(0)
トラックバック(0)
コメント 0