8

iPhoneで画像処理をしようとしています。http://developer.apple.com/library/ios/#qa/qa2010/qa1702.htmlを使用してカメラ フレームをキャプチャしています。

私の問題は、キャプチャされたバッファにアクセスしようとすると、カメラの FPS が 30 から約 20 に低下することです。修正方法を知っている人はいますか?

kCVPixelFormatType_32BGRA 形式で見つけた最低のキャプチャ品質 (AVCaptureSessionPresetLow = 192x144) を使用します。私が使用できるより低い品質を誰かが知っている場合は、喜んで試してみます.

Symbian などの他のプラットフォームで同じイメージ アクセスを行うと、問題なく動作します。

これが私のコードです:

#pragma mark -
#pragma mark AVCaptureSession delegate
- (void)captureOutput:(AVCaptureOutput *)captureOutput 
didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer 
    fromConnection:(AVCaptureConnection *)connection 
{ 
 /*We create an autorelease pool because as we are not in the main_queue our code is
  not executed in the main thread. So we have to create an autorelease pool for the thread we are in*/
 NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
 //Lock the image buffer
    if (CVPixelBufferLockBaseAddress(imageBuffer, 0) == kCVReturnSuccess)
    {  

  // calculate FPS and display it using main thread
  [self performSelectorOnMainThread:@selector(updateFps:) withObject: (id) nil waitUntilDone:NO];


  UInt8 *base = (UInt8 *)CVPixelBufferGetBaseAddress(imageBuffer); //image buffer start address

  size_t width  = CVPixelBufferGetWidth(imageBuffer); 
  size_t height = CVPixelBufferGetHeight(imageBuffer);

  int size = (height*width);
  UInt8* pRGBtmp = m_pRGBimage;

        /*
        Here is the problem; m_pRGBimage is RGB image I want to process.
        In the 'for' loop I convert the image from BGRA to RGB. As a resault, the FPS drops to 20.
        */ 
  for (int i=0;i<size;i++)
  {   
    pRGBtmp[0] = base[2];
    pRGBtmp[1] = base[1];
    pRGBtmp[2] = base[0];
    base = base+4;
    pRGBtmp = pRGBtmp+3;     
  }


  // Display received action
  [self performSelectorOnMainThread:@selector(displayAction:) withObject: (id) nil waitUntilDone:NO];
  //[self displayAction:&eyePlayOutput];
  //saveFrame( imageBuffer );

  //unlock the  image buffer
  CVPixelBufferUnlockBaseAddress(imageBuffer,0);

 }


 [pool drain];
} 

回答の続きとして、画像をリアルタイムで処理する必要があり、表示されています。

AVCaptureSessionPresetHigh を使用すると、次のような最も単純なことを行うことに気付きました。

 for (int i=0;i<size;i++)
    x = base[0];

フレームレートが 4 ~ 5 FPS に低下します。そのサイズの画像がキャッシュされていないためだと思います。

基本的に、96x48 の画像が必要です。ハードウェアアクセラレーションを使用してカメラ出力画像を縮小する簡単な方法はありますか?

4

3 に答える 3

8

画像内のすべてのピクセルを反復処理するものはすべて、最速の iOS デバイス以外ではかなり遅くなります。たとえば、640 x 480 ビデオ フレーム (307,200 ピクセル) のすべてのピクセルを単純なピクセルごとのカラー テストで反復するベンチマークを行ったところ、iPhone 4 では約 4 FPS でしか実行されないことがわかりました。

ケースで 27,648 ピクセルを処理しようとしていますが、これは iPhone 4 で 30 FPS を達成するのに十分な速度で動作するはずですが、これは元の iPhone や iPhone 3G にあったものよりもはるかに高速なプロセッサです。iPhone 3G はおそらく、この処理負荷にまだ苦労するでしょう。また、Symbian デバイスのプロセッサの速度についても言及していません。

色空間の変換を避けるために、処理アルゴリズムを作り直すことをお勧めします。色成分を処理するために色成分を並べ替える必要はありません。

さらに、画像の行と列内で特定の間隔でサンプリングすることにより、少数のピクセルのみを選択的に処理できます。

最後に、OpenGL ES 2.0 をサポートする新しい iOS デバイス (iPhone 3G S 以降) をターゲットにしている場合は、GLSL フラグメント シェーダーを使用してビデオ フレーム全体を GPU で処理することを検討してください。ここでは、リアルタイムの色ベースのオブジェクト トラッキングのサンプル コードとともに、そのプロセスについて説明します。私のベンチマークでは、GPU はこの種の処理を CPU よりも 14 倍から 28 倍高速に処理できます。

于 2010-11-23T19:53:25.123 に答える
1

免責事項:この回答は推測です:)

バッファがロックされている間、かなり多くの作業を行っています。これは、カメラから画像をキャプチャしているスレッドを保持していますか?

作業中にバッファからデータをコピーして、できるだけ早くロックを解除できるようにすることができます。

if (CVPixelBufferLockBaseAddress(imageBuffer, 0) == kCVReturnSuccess) {
    // Get the base address and size of the buffer
    UInt8 *buffer_base = (UInt8 *)CVPixelBufferGetBaseAddress(imageBuffer); //image buffer start address
    size_t width  = CVPixelBufferGetWidth(imageBuffer); 
    size_t height = CVPixelBufferGetHeight(imageBuffer);

    // Copy it's contents out
    Uint8 *base = malloc(width * height * 4);
    memcpy(base, buffer_base, size);

    // Unlock the buffer
    CVPixelBufferUnlockBaseAddress(imageBuffer,0);

    // base now points to a copy of the buffers' data - do what you want to it . . .
    ...

    // remember to free base once you're done ;)
    free(base);

キャプチャを保持しているのがロックである場合、これが役立ちます。

注意:すべてのバッファが同じサイズになることがわかっている場合は、これを高速化できます.mallocを1回呼び出してメモリを取得し、毎回再利用して、すべてのバッファの処理が終了したときにのみ解放します.


または、それが問題でない場合は、このスレッドの優先度を下げてみてください

[NSThread setThreadPriority:0.25];
于 2010-11-23T13:29:00.500 に答える
0

カメラ フレームの内容を専用のバッファにコピーし、そこから操作します。これにより、私の経験では速度が大幅に向上します。私の推測では、カメラ フレームが配置されているメモリ領域には、読み取り/書き込みアクセスを遅くする特別な保護機能があると思われます。

カメラフレームデータのメモリアドレスを確認してください。私のデバイスでは、カメラ バッファは にあり0x63ac000ます。他のヒープ オブジェクトが に近いアドレスにあることを除いて、これは私には何の意味もありません0x1300000。ロックの提案は速度低下を解決しませんでしたが、解決しましmemcpyた。

于 2010-12-08T12:22:54.977 に答える