2016-04-25 11 views
3

Ich benutze die iPhone-Kamera, um Live-Video aufzunehmen und den Pixelpuffer in ein Netzwerk zu leiten, das eine Objekterkennung durchführt. Hier ist der relevante Code: (Ich werde nicht nach dem Code für den Aufbau der AVCaptureSession usw., da dies ziemlich normal ist.)Ersetze einen Teil des Pixelpuffers durch weiße Pixel in iOS

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection { 
    CVPixelBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); 

    OSType sourcePixelFormat = CVPixelBufferGetPixelFormatType(pixelBuffer); 
    int doReverseChannels; 
    if (kCVPixelFormatType_32ARGB == sourcePixelFormat) { 
     doReverseChannels = 1; 
    } else if (kCVPixelFormatType_32BGRA == sourcePixelFormat) { 
     doReverseChannels = 0; 
    } else { 
     assert(false); 
    } 

    const int sourceRowBytes = (int)CVPixelBufferGetBytesPerRow(pixelBuffer); 
    const int width = (int)CVPixelBufferGetWidth(pixelBuffer); 
    const int fullHeight = (int)CVPixelBufferGetHeight(pixelBuffer); 
    CVPixelBufferLockBaseAddress(pixelBuffer, 0); 
    unsigned char* sourceBaseAddr = CVPixelBufferGetBaseAddress(pixelBuffer); 
    int height; 
    unsigned char* sourceStartAddr; 
    if (fullHeight <= width) { 
     height = fullHeight; 
     sourceStartAddr = sourceBaseAddr; 
    } else { 
     height = width; 
     const int marginY = ((fullHeight - width)/2); 
     sourceStartAddr = (sourceBaseAddr + (marginY * sourceRowBytes)); 
    } 
} 

Das Netzwerk nimmt dann sourceStartAddr, width, height, sourceRowBytes & doReverseChannels als Eingaben.

Meine Frage ist die folgende: Was wäre die einfachste und/oder effizienteste Möglichkeit, einen Teil der Bilddaten mit allen weißen 'Pixel' zu ersetzen oder zu löschen? Ist es möglich, einen Teil der Pixelpufferdaten direkt zu überschreiben und wenn ja wie?

Ich habe nur ein sehr rudimentäres Verständnis davon, wie dieser Pixelpuffer funktioniert, also entschuldige ich mich, wenn ich hier etwas sehr Grundlegendes verpasse. Die Frage, die am ehesten mit der von mir auf Stackoverflow gefundenen Frage zusammenhing, war this one, wo ein EAGLContext verwendet wird, um Text zu einem Videoframe hinzuzufügen. Während dies für mein Ziel funktionieren würde, das nur diesen Ersatz für einzelne Bilder benötigt, gehe ich davon aus, dass dieser Schritt die Leistung bei jedem Video-Frame beeinträchtigen würde, und ich würde gerne herausfinden, ob es eine andere Methode gibt. Jede Hilfe hier würde geschätzt werden.

Antwort

5

Hier ist eine einfache Möglichkeit, ein CVPixelBufferRef ohne Verwendung von anderen Bibliotheken wie Core Graphics oder OpenGL zu manipulieren:

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection { 
    CVPixelBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); 

    const int kBytesPerPixel = 4; 
    CVPixelBufferLockBaseAddress(pixelBuffer, 0); 
    int bufferWidth = (int)CVPixelBufferGetWidth(pixelBuffer); 
    int bufferHeight = (int)CVPixelBufferGetHeight(pixelBuffer); 
    size_t bytesPerRow = CVPixelBufferGetBytesPerRow(pixelBuffer); 
    uint8_t *baseAddress = CVPixelBufferGetBaseAddress(pixelBuffer); 

    for (int row = 0; row < bufferHeight; row++) 
    { 
     uint8_t *pixel = baseAddress + row * bytesPerRow; 
     for (int column = 0; column < bufferWidth; column++) 
     { 
      if ((row < 100) && (column < 100) { 
       pixel[0] = 255; // BGRA, Blue value 
       pixel[1] = 255; // Green value 
       pixel[2] = 255; // Red value 
      } 
      pixel += kBytesPerPixel; 
     } 
    } 

    CVPixelBufferUnlockBaseAddress(pixelBuffer, 0); 

    // Do whatever needs to be done with the pixel buffer 
} 

Das überschreibt die linke obere Patch von 100 x 100 Pixel im Bild mit weißen Pixeln.

Ich fand diese Lösung in diesem Apple Developer Beispiel RosyWriter genannt.

Art von erstaunt, ich habe keine Antworten hier erhalten, wenn man bedenkt, wie einfach das war. Hoffe, das hilft jemandem.