2010-11-17 13 views
9

मैं एक आईफोन (आईओएस 4) प्रोग्राम लिख रहा हूं जो कैमरे से लाइव वीडियो कैप्चर करता है और इसे वास्तविक समय में संसाधित करता है।कैमरे से वाईयूवी स्वरूपित वीडियो को कैसे पकड़ें, इसे प्रदर्शित करें और इसे संसाधित करें

मैं आसान प्रसंस्करण (मुझे वाई चैनल को संसाधित करने की आवश्यकता है) के लिए केसीवी पिक्सेलफॉर्मैट टाइपइप 2020ppCbCr8BiPlanarFullRange प्रारूप में कैप्चर करना पसंद करते हैं। मैं इस प्रारूप में डेटा कैसे प्रदर्शित करूं? मुझे लगता है कि मुझे इसे किसी भी तरह से UIImage में परिवर्तित करने की आवश्यकता है और फिर इसे कुछ छवि दृश्य में डाल दें?

वर्तमान में मेरे पास कोड है जो kCVPixelFormatType_32BGRA डेटा प्रदर्शित करता है, लेकिन स्वाभाविक रूप से यह kCVPixelFormatType_420YpCbCr8BiPlanarFullRange के साथ काम नहीं करता है।

यह कोड है जिसे मैं अब परिवर्तन के लिए उपयोग करता हूं, किसी भी मदद/नमूना के बारे में kCVPixelFormatType_420YpCbCr8BiPlanarFullRange की सराहना की जाएगी। (मेरी वर्तमान विधि की भी आलोचना)।

// Create a UIImage from sample buffer data 
- (UIImage *) imageFromSampleBuffer:(CMSampleBufferRef) sampleBuffer 
{ 
    // Get a CMSampleBuffer's Core Video image buffer for the media data 
    CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); 
    // Lock the base address of the pixel buffer 
    CVPixelBufferLockBaseAddress(imageBuffer, 0); 

    // Get the number of bytes per row for the pixel buffer 
    void *baseAddress = CVPixelBufferGetBaseAddress(imageBuffer); 

    // Get the number of bytes per row for the pixel buffer 
    size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer); 
    // Get the pixel buffer width and height 
    size_t width = CVPixelBufferGetWidth(imageBuffer); 
    size_t height = CVPixelBufferGetHeight(imageBuffer); 

    // Create a device-dependent RGB color space 
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 

    // Create a bitmap graphics context with the sample buffer data 
    CGContextRef context = CGBitmapContextCreate(baseAddress, width, height, 8, 
               bytesPerRow, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst); 
    // Create a Quartz image from the pixel data in the bitmap graphics context 
    CGImageRef quartzImage = CGBitmapContextCreateImage(context); 

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

    // Free up the context and color space 
    CGContextRelease(context); 
    CGColorSpaceRelease(colorSpace); 

    // Create an image object from the Quartz image 
    UIImage *image = [UIImage imageWithCGImage:quartzImage]; 

    // Release the Quartz image 
    CGImageRelease(quartzImage); 

    return (image); 
} 
+0

बहुत बढ़िया उदाहरण! मैंने इस कोड को सभी apple.com के माध्यम से खोजा है –

उत्तर

6

मेरे अपने प्रश्न का उत्तर दें। इस समस्या मैं था (, YUV उत्पादन हड़पने यह प्रदर्शित करने और इसे संसाधित करने में था) हल, हालांकि इसके बिल्कुल सवाल का जवाब:

AVCaptureVideoDataOutput *videoOut = [[AVCaptureVideoDataOutput alloc] init]; 
[videoOut setAlwaysDiscardsLateVideoFrames:YES]; 
[videoOut setVideoSettings:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange] forKey:(id)kCVPixelBufferPixelFormatTypeKey]]; 
:

कैमरे से YUV उत्पादन हड़पने के लिए

इसे प्रदर्शित करने के लिए, AVCaptureVideoPreviewLayer का उपयोग करें, इसे किसी भी कोड की आवश्यकता नहीं है। (उदाहरण के लिए आप WWDC नमूने पैक में FindMyiCon नमूना देख सकते हैं)।

YUV y चैनल के संसाधन के लिए (इसलिए यह एक भी हिस्सा में सब है इस मामले में द्वि-चौरस करने का औज़ार, आप भी memcpy बजाय पाशन के उपयोग कर सकते हैं):

- (void)processPixelBuffer: (CVImageBufferRef)pixelBuffer { 

    CVPixelBufferLockBaseAddress(pixelBuffer, 0); 

    int bufferHeight = CVPixelBufferGetHeight(pixelBuffer); 
    int bufferWidth = CVPixelBufferGetWidth(pixelBuffer); 

    // allocate space for ychannel, reallocating as needed. 
    if (bufferWidth != y_channel.width || bufferHeight != y_channel.height) 
    { 
     if (y_channel.data) free(y_channel.data); 
     y_channel.width = bufferWidth; 
     y_channel.height = bufferHeight; 
     y_channel.data = malloc(y_channel.width * y_channel.height);   
    } 

    uint8_t *yc = CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 0); 
    int total = bufferWidth * bufferHeight; 
    for(int k=0;k<total;k++) 
    { 
     y_channel.data[k] = yc[k++]; // copy y channel 
    } 

    CVPixelBufferUnlockBaseAddress(pixelBuffer, 0); 
} 
संबंधित मुद्दे

 संबंधित मुद्दे