AVCaptureSession изходна примерна буферна координата при четене на пиксел дава грешен цвят

Използвам AVCaptureSession, за да инициирам сесия за заснемане на видео и да чета цветовете на пикселите от видео кадрите. Видео настройката е такава.

NSDictionary* videoSettings = [NSDictionary dictionaryWithObjectsAndKeys:
                               [NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA],
                               kCVPixelBufferPixelFormatTypeKey,
                               nil];

с делегиран метод по-долу, за да получа примерен буфер, който по-късно ще прочета цветовете на пикселите.

- (void)captureOutput:(AVCaptureOutput *)captureOutput // captureOutput is only the AVCaptureVideoDataOutput
didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer 
       fromConnection:(AVCaptureConnection *)connection 
{ 

    NSAutoreleasePool * pool = [NSAutoreleasePool new]; // instrument tells it leaks

    /*******  START CALCULATION  *******/

    imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); 
    CVPixelBufferLockBaseAddress(imageBuffer,0); // lock image buffer
    buffer_baseAddress = (uint8_t *)CVPixelBufferGetBaseAddress(imageBuffer); // raw buffer data BGRA

...

Променливата buffer_baseAddress е масив, който съхранява цветовете на пикселите, в който при настройка kCVPixelFormatType_32BGRA масивът ще бъде подреден като [B][G][R][A][B][G][R][A][B]. ..[B][G][R][A]. Така че, за да получа цвят на пиксел на някаква координата, ще трябва да разбера 3 индекса в буфера. Така че при (x,y) = (10,0), BGR ще бъде при индекси 40, 41 и 42.

Тук е проблемът. Първият ред (y == 0) на примерния буфер изглежда дава правилен цвят през цялото време. Но когато се преместя на втория ред нататък (y > 0), получих грешни цветове на някои предварително зададени настройки или използвах предна/задна камера. Сякаш буферът има някакви неизвестни, допълнителни данни, добавени в края на всеки ред, в определена настройка. За щастие от моите експерименти откривам, че примерните буфери са изместени с известно количество във всеки ред, когато аз използвайте AVCaptureSessionPresetHigh на задната камера и AVCaptureSessionPresetMedium на двете предни/задни камери. Спомних си, че настройката на rowPadding = 0 в един от класовете AVCaptureSession също не помага. (Съжалявам, че забравих коя точно променлива беше. Беше преди няколко месеца.)

Какво причинява този проблем? И какво мога да направя, за да реша това?


person Hlung    schedule 05.12.2012    source източник


Отговори (2)


Разгледайте раздела Конвертиране на CMSampleBuffer в UIImage в тази страница от Apple Docs. Не съм го пробвал, но показва как да получите bytesPerRow - включително подложка - на буфера.

Нормално е буферът на изображението да бъде подплатен до оптимална стойност, независимо дали използвате CoreVideo, CoreImage, Quartz, Quicktime и т.н.. винаги ще има начин да разберете какво е това.

person hooleyhoop    schedule 05.12.2012

Това е текущото ми решение. Не е най-добрият, но ми помага да го преодолея. Просто тествам всеки от всеки AVCaptureSessionPreset и виждам кой има грешни прочетени пиксели. След това се опитвам да отгатна размера на тази допълнителна подложка и да я използвам, когато изчислявам индекса на примерния буфер. Това магическо число е 8, отне ми дни, за да разбера това. Така че се надяваме, че това ще бъде полезно за някого поне като заобиколно решение. :-)

    // Look like this magic padding is affected by AVCaptureSessionPreset and front/back camera
    if ([[self currentPresetSetting] isEqualToString:AVCaptureSessionPresetHigh] && ![self isUsingFrontFacingCamera]) {
        buffer_rowPixelPadding = 8;
    }
    else if ([[self currentPresetSetting] isEqualToString:AVCaptureSessionPresetMedium]) {
        buffer_rowPixelPadding = 8;
    }
    else {
        buffer_rowPixelPadding = 0; // default
    }
person Hlung    schedule 05.12.2012