【问题标题】:objective-c: cv::Mat to CVPixelBuffer目标-c: cv::Mat 到 CVPixelBuffer
【发布时间】:2021-05-31 17:03:43
【问题描述】:

以下代码将cv::Mat 转换为CVPixelBufferRef

CVPixelBufferRef getImageBufferFromMat(cv::Mat matimg) {
    cv::cvtColor(matimg, matimg, CV_BGR2BGRA);
    
    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
                                [NSNumber numberWithBool: YES], kCVPixelBufferMetalCompatibilityKey,
                                [NSNumber numberWithBool: YES], kCVPixelBufferCGImageCompatibilityKey,
                                [NSNumber numberWithBool: YES], kCVPixelBufferCGBitmapContextCompatibilityKey,
                                [NSNumber numberWithInt: matimg.cols], kCVPixelBufferWidthKey,
                                [NSNumber numberWithInt: matimg.rows], kCVPixelBufferHeightKey,
                                [NSNumber numberWithInt: matimg.step[0]], kCVPixelBufferBytesPerRowAlignmentKey,
                                nil];
    CVPixelBufferRef imageBuffer;

    CVReturn status = CVPixelBufferCreate(kCFAllocatorMalloc, matimg.cols, matimg.rows, kCVPixelFormatType_32BGRA, (CFDictionaryRef) CFBridgingRetain(options), &imageBuffer) ;

    CVPixelBufferLockBaseAddress(imageBuffer, 0);
    void *base = CVPixelBufferGetBaseAddress(imageBuffer);

    memcpy(base, matimg.data, matimg.total() * matimg.elemSize());
    CVPixelBufferUnlockBaseAddress(imageBuffer, 0);

    return imageBuffer;
}

问题是我得到了一半的图像

原图

转换后(我将CVPixelBufferRef 转换回UIImage 并使用UIImageWriteToSavedPhotosAlbum 存储它只是为了检查)

有趣的是,MatCVPixelBufferRef 的图片大小是一样的。

现在,我所做的是在 memcopy 之前调整图像大小,其中高度增加了 2 倍

    CVPixelBufferLockBaseAddress(imageBuffer, 0);
    void *base = CVPixelBufferGetBaseAddress(imageBuffer);

    cv::resize(matimg, matimg, cv::Size(), 1 , 2);
    memcpy(base, matimg.data, matimg.total() * matimg.elemSize());
    CVPixelBufferUnlockBaseAddress(imageBuffer, 0);

现在图片大小还是一样...

我很想知道是什么导致了这种行为,我确定我错过了什么......

【问题讨论】:

    标签: ios objective-c opencv


    【解决方案1】:

    看了this之后找到了解决这个问题的办法。

    系统希望图像是每行 64 字节的倍数,这可能是为了提高缓存行对齐的性能。由于图像分辨率为[1000 × 1000],而不是 64 的倍数,因此每行字节默认为27840 不知道为什么...这是导致问题的原因。

    无论如何,如果有人在寻找解决方案

    CVPixelBufferRef getImageBufferFromMat(cv::Mat matimg) {
        cv::cvtColor(matimg, matimg, CV_BGR2BGRA);
        
        int widthReminder = matimg.cols % 64, heightReminder = matimg.rows % 64;
        if (widthReminder != 0 || heightReminder != 0) {
            cv::resize(matimg, matimg, cv::Size(matimg.cols + (64 - widthReminder), matimg.rows + (64 - heightReminder)));
        }
    
        NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
                                    [NSNumber numberWithBool: YES], kCVPixelBufferMetalCompatibilityKey,
                                    [NSNumber numberWithBool: YES], kCVPixelBufferCGImageCompatibilityKey,
                                    [NSNumber numberWithBool: YES], kCVPixelBufferCGBitmapContextCompatibilityKey,
                                    [NSNumber numberWithInt: matimg.cols], kCVPixelBufferWidthKey,
                                    [NSNumber numberWithInt: matimg.rows], kCVPixelBufferHeightKey,
                                    [NSNumber numberWithInt: matimg.step[0]], kCVPixelBufferBytesPerRowAlignmentKey,
                                    nil];
        CVPixelBufferRef imageBuffer;
        CVReturn status = CVPixelBufferCreate(kCFAllocatorMalloc, matimg.cols, matimg.rows, kCVPixelFormatType_32BGRA, (CFDictionaryRef) CFBridgingRetain(options), &imageBuffer) ;
        NSParameterAssert(status == kCVReturnSuccess && imageBuffer != NULL);
        
        CVPixelBufferLockBaseAddress(imageBuffer, 0);
        void *base = CVPixelBufferGetBaseAddress(imageBuffer);
        memcpy(base, matimg.data, matimg.total() * matimg.elemSize());
        CVPixelBufferUnlockBaseAddress(imageBuffer, 0);
    
    //    UIImageWriteToSavedPhotosAlbum(converts(imageBuffer), nil, nil, nil);
        return imageBuffer;
    } 
    

    【讨论】:

      猜你喜欢
      • 2018-04-16
      • 1970-01-01
      • 2011-12-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-23
      • 2017-10-07
      • 2014-06-21
      相关资源
      最近更新 更多