2013-10-14 27 views
8

bir CVPixelBufferRef gelen dönüştürebilirim nasıl CVPixelBufferRef için birkaç işlemleri gerçekleştirmek ve ölçekli ilgi Bir OpenCV cv :: Mat

  • bir bölgeye bir cv::Mat

    • kırpma ile gelmek istiyorum piksel (CV_8UC1)
    başına 8 bit - sabit bir boyuta
  • gri tonlama
  • dönüştürmek histogram eşitlenmiş

    Bunu yapmak için en etkili sıranın ne olduğundan emin değilim, ancak, tüm işlemler açık bir CV matrisinde kullanılabilir olduğunu biliyorum, bu yüzden nasıl dönüştürüleceğini bilmek istiyorum.

    - (void) captureOutput:(AVCaptureOutput *)captureOutput 
         didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer 
         fromConnection:(AVCaptureConnection *)connection 
    { 
        CVPixelBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); 
    
        cv::Mat frame = f(pixelBuffer); // how do I implement f()? 
    
  • cevap

    12

    Bazı excellent GitHub source code cevabını buldum. Basitlik için buraya uyarladım. Ayrıca benim için gri tonlama dönüşümü yapar.

    CVPixelBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); 
    OSType format = CVPixelBufferGetPixelFormatType(pixelBuffer); 
    
    // Set the following dict on AVCaptureVideoDataOutput's videoSettings to get YUV output 
    // @{ kCVPixelBufferPixelFormatTypeKey : kCVPixelFormatType_420YpCbCr8BiPlanarFullRange } 
    
    NSAssert(format == kCVPixelFormatType_420YpCbCr8BiPlanarFullRange, @"Only YUV is supported"); 
    
    // The first plane/channel (at index 0) is the grayscale plane 
    // See more infomation about the YUV format 
    // http://en.wikipedia.org/wiki/YUV 
    CVPixelBufferLockBaseAddress(pixelBuffer, 0); 
    void *baseaddress = CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 0); 
    
    CGFloat width = CVPixelBufferGetWidth(pixelBuffer); 
    CGFloat height = CVPixelBufferGetHeight(pixelBuffer); 
    
    cv::Mat mat(height, width, CV_8UC1, baseaddress, 0); 
    
    // Use the mat here 
    
    CVPixelBufferUnlockBaseAddress(pixelBuffer, 0); 
    

    Ben en iyi düzen olacağını düşünüyorum:

    1. dönüştürün (neredeyse otomatik olarak yapılır beri)
    2. Mahsul (bu hızlı operasyon olmalıdır gri tonlama ve sayısını azaltacaktır çalışmak için piksel)
    3. aşağı Ölçek
    4. histogram beraberliği
    +0

    Merhaba @Robert, size etmektir tersini yapabilir biliyor musunuz cv :: Mat'ı bir CVPixelBuffer'a veya örnek Buffer'a dönüştürelim mi? Teşekkür. – lilouch

    +0

    Aşağıdaki kod, en azından iPhone 6 ve iPhone 6 + üzerinde iOS 10.2 ile çalışamayacağım, çünkü temel piksel dizisi bellekte sürekli olmadığından test ettiğim. Lütfen güncellenmiş yanıtıma buradan ulaşabilirsiniz: http://stackoverflow.com/questions/12355257/open-cv-ios-video-processing/43523459#43523459. – PalmRobotZ

    +0

    Swift'den ne haber? – user924

    2

    Bunu kullanıyorum. Benim cv:Mat, BGR (8UC3) colorFormat yapılandırıldı.

    CVImageBufferRef -> cv :: Mat

    - (cv::Mat) matFromImageBuffer: (CVImageBufferRef) buffer { 
    
        cv::Mat mat ; 
    
        CVPixelBufferLockBaseAddress(buffer, 0); 
    
        void *address = CVPixelBufferGetBaseAddress(buffer); 
        int width = (int) CVPixelBufferGetWidth(buffer); 
        int height = (int) CVPixelBufferGetHeight(buffer); 
    
        mat = cv::Mat(height, width, CV_8UC4, address, 0); 
        //cv::cvtColor(mat, _mat, CV_BGRA2BGR); 
    
        CVPixelBufferUnlockBaseAddress(buffer, 0); 
    
        return mat; 
    } 
    

    cv :: Mat -> CVImageBufferRef (CVPixelBufferRef)

    - (CVImageBufferRef) getImageBufferFromMat: (cv::Mat) mat { 
    
        cv::cvtColor(mat, mat, CV_BGR2BGRA); 
    
        int width = mat.cols; 
        int height = self.rows; 
    
        NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys: 
              // [NSNumber numberWithBool:YES], kCVPixelBufferCGImageCompatibilityKey, 
              // [NSNumber numberWithBool:YES], kCVPixelBufferCGBitmapContextCompatibilityKey, 
              [NSNumber numberWithInt:width], kCVPixelBufferWidthKey, 
              [NSNumber numberWithInt:height], kCVPixelBufferHeightKey, 
              nil]; 
    
        CVPixelBufferRef imageBuffer; 
        CVReturn status = CVPixelBufferCreate(kCFAllocatorMalloc, width, height, kCVPixelFormatType_32BGRA, (CFDictionaryRef) CFBridgingRetain(options), &imageBuffer) ; 
    
    
        NSParameterAssert(status == kCVReturnSuccess && imageBuffer != NULL); 
    
        CVPixelBufferLockBaseAddress(imageBuffer, 0); 
        void *base = CVPixelBufferGetBaseAddress(imageBuffer) ; 
        memcpy(base, mat.data, _mat.total()*4); 
        CVPixelBufferUnlockBaseAddress(imageBuffer, 0); 
    
        return imageBuffer; 
    } 
    
    +0

    'self.rows' nedir? mat.rows' neden olmasın? Ayrıca bu 'CVImageBufferRef' den' CMSampleBufferRef' nasıl oluşturulur? – user924