2013-10-14 28 views
8

にCVPixelBufferRefから変換するにはどうすればよい私はCVPixelBufferRefにいくつかの操作を実行し、スケール関心 私はOpenCVのCV ::マット

  • の領域にcv::Mat

    • 作物で出てくるしたいと思います画素当たり8ビット(CV_8UC1
    - を固定寸法に
  • はグレースケールするヒストグラム
  • 変換等化しました

    最も効率的な命令がこれを行うことがわかりませんが、私はすべての操作がオープン:CVマトリックスで利用できることを知っていますので、変換方法を知りたいと思います。

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

    12

    回答は一部ではexcellent GitHub source codeです。わかりやすくするために私はここにそれを適用しました。それは私のグレースケール変換も行います。

    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); 
    

    私は最高の注文が可能になることを考えています。(それは、ほぼ自動的に行われるので)グレースケールに

    1. 変換
    2. クロップ(これは高速動作する必要がありますし、数を減らしますで動作するようにピクセル)の
    3. ダウンスケール
    4. ヒストグラムをイコライズ
    +0

    こんにちは@Robert、あなたはあなたにある反対のことを行うことができますどのように知っています例えば、cv :: MatをCVPixelBufferまたはサンプルバッファに変換しますか?感謝。 – lilouch

    +0

    基本的なピクセル配列がメモリ内で連続していないため、以下のコードは、iPhone 6およびiPhone 6 +とiOS 10.2で動作しません。私の更新された回答はこちらhttp://stackoverflow.com/questions/12355257/open-cv-ios-video-processing/43523459#43523459をご覧ください。 – PalmRobotZ

    +0

    スウィフトはどうですか? – user924

    2

    私はこれを使用しています。私のcv:MatはBGR(8UC3)colorFormatに設定されています。

    CVImageBufferRef - > CV ::マット

    - (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 ::マット - > 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'とは何ですか?どうして 'mat.rows'?この 'CVImageBufferRef'から' CMSampleBufferRef'をどのように作成するのでしょうか? – user924

    関連する問題