2012-04-15 50 views
3

我正在使用AVFoundation拍攝視頻,並以kCVPixelFormatType_420YpCbCr8BiPlanarFullRange格式錄製。我想直接從YpCbCr格式的Y平面製作灰度圖像。AVFoundation - 從Y平面獲取灰度圖像(kCVPixelFormatType_420YpCbCr8BiPlanarFullRange)

我試圖通過調用CGBitmapContextCreate創建CGContextRef,但問題是,我不知道要選擇什麼顏色空間和像素格式。

- (void)captureOutput:(AVCaptureOutput *)captureOutput 
didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer 
     fromConnection:(AVCaptureConnection *)connection 
{  
    CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); 
    CVPixelBufferLockBaseAddress(imageBuffer,0);   

    /* Get informations about the Y plane */ 
    uint8_t *YPlaneAddress = CVPixelBufferGetBaseAddressOfPlane(imageBuffer, 0); 
    size_t bytesPerRow = CVPixelBufferGetBytesPerRowOfPlane(imageBuffer, 0); 
    size_t width = CVPixelBufferGetWidthOfPlane(imageBuffer, 0); 
    size_t height = CVPixelBufferGetHeightOfPlane(imageBuffer, 0); 

    /* the problematic part of code */ 
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray(); 

    CGContextRef newContext = CGBitmapContextCreate(YPlaneAddress, 
    width, height, 8, bytesPerRow, colorSpace, kCVPixelFormatType_1Monochrome); 

    CGImageRef newImage = CGBitmapContextCreateImage(newContext); 
    UIImage *grayscaleImage = [[UIImage alloc] initWithCGImage:newImage]; 

    // process the grayscale image ... 
} 

當我運行上面的代碼中,我得到了這個錯誤:

<Error>: CGBitmapContextCreateImage: invalid context 0x0 
<Error>: CGBitmapContextCreate: unsupported parameter combination: 8 integer bits/component; 16 bits/pixel; 1-component color space; kCGImageAlphaPremultipliedLast; 192 bytes/row. 

PS:對不起,我的英語水平。

回答

2

如果我沒有錯,你不應該通過CGContext去。相反,您應該創建數據提供者,然後直接創建圖像。

代碼中的另一個錯誤是使用kCVPixelFormatType_1Monochrome常量。這是一個用於視頻處理(AV庫)的常量,而不是Core Graphics(CG庫)。只需使用kCGImageAlphaNone即可。需要每個像素的單個分量(灰色)(而不是RGB的三個分量)是從色彩空間導出的。

它看起來是這樣的:

CGDataProviderRef dataProvider = CGDataProviderCreateWithData(NULL, YPlaneAdress, 
     height * bytesPerRow, NULL); 
CGImageRef newImage = CGImageCreate(width, height, 8, 8, bytesPerRow, 
     colorSpace, kCGImageAlphaNone, dataProvider, NULL, NO, kCGRenderingIntentDefault); 
CGDataProviderRelease(dataProvider); 
+0

非常感謝!是否正確,這是從相機獲取灰度圖像的最快方法? – user961912 2012-04-16 14:38:56

+0

@ user961912:在YpCbCr中訪問視頻幀應該是快速的,因爲它是原生格式(根據WWDC演示文稿)。對於以下步驟,這取決於您最終對圖像執行的操作。對於多個應用程序(如條形碼掃描),您不需要創建CGImage或UIImage。 – Codo 2012-04-16 15:13:20

+0

Hey Codo,謝謝你的回答!我試圖實現一些「相同」的結果,不同之處在於我試圖在每幀(實時視頻流)上實現灰度效果,有什麼機會可以指引我走向正確的方向? – 2016-05-31 15:26:35