objective-c - vImageConvert 提取一个 channel

标签 objective-c image cocoa image-processing vimage

如何使用 vImage 从图像中仅“提取”一个 channel ? 我现在的做法是:

vImage_Buffer redBuffer;
redBuffer.data = (void*)redImageData.bytes;
redBuffer.width = size.width;
redBuffer.height = size.height;
redBuffer.rowBytes = [redImageData length]/size.height;
vImage_Buffer redBuffer2;
redBuffer2.width = size.width;
redBuffer2.height = size.height;
redBuffer2.rowBytes = size.width;
vImageConvert_RGB888toPlanar8(&redBuffer, &redBuffer2, nil, nil, kvImageNoFlags);
redBuffer 是一个工作图像,没有错误,但 vImageConvert 给了我一个 EXC_BAD_ACCESS,我尝试了很多选项,有些会导致 EXC_BAD_ACCESS,有些会导致输出图像损坏。我做错了什么?

感谢 Rob Keniger,我成功地提取了 channel ,但如果我尝试将它们与其他 channel 放回一起,图像会水平拉伸(stretch)并在其中出现 RGB 条纹。为什么它们没有正确地重新组合在一起?这是提取 channel 然后将它们重新组合在一起的示例:

    vImage_Buffer blueBuffer;
    blueBuffer.data = (void*)blueImageData.bytes;
    blueBuffer.width = size.width;
    blueBuffer.height = size.height;
    blueBuffer.rowBytes = [blueImageData length]/size.height;

    vImage_Buffer rBuffer;
    rBuffer.width = size.width;
    rBuffer.height = size.height;
    rBuffer.rowBytes = size.width;
    void *rPixelBuffer = malloc(size.width * size.height);
    if(rPixelBuffer == NULL)
    {
        NSLog(@"No pixelbuffer");
    }
    rBuffer.data = rPixelBuffer;

    vImage_Buffer gBuffer;
    gBuffer.width = size.width;
    gBuffer.height = size.height;
    gBuffer.rowBytes = size.width;
    void *gPixelBuffer = malloc(size.width * size.height);
    if(gPixelBuffer == NULL)
    {
        NSLog(@"No pixelbuffer");
    }
    gBuffer.data = gPixelBuffer;

    vImage_Buffer bBuffer;
    bBuffer.width = size.width;
    bBuffer.height = size.height;
    bBuffer.rowBytes = size.width;
    void *bPixelBuffer = malloc(size.width * size.height);
    if(bPixelBuffer == NULL)
    {
        NSLog(@"No pixelbuffer");
    }
    bBuffer.data = bPixelBuffer;

    vImageConvert_RGB888toPlanar8(&blueBuffer, &rBuffer, &gBuffer, &bBuffer, kvImageNoFlags);

    size_t destinationImageBytesLength = size.width*size.height*3;
    const void* destinationImageBytes = valloc(destinationImageBytesLength);
    NSData* destinationImageData = [[NSData alloc] initWithBytes:destinationImageBytes length:destinationImageBytesLength];
    vImage_Buffer destinationBuffer;
    destinationBuffer.data = (void*)destinationImageData.bytes;
    destinationBuffer.width = size.width;
    destinationBuffer.height = size.height;
    destinationBuffer.rowBytes = [destinationImageData length]/size.height;

    vImage_Error result = vImageConvert_Planar8toRGB888(&rBuffer, &gBuffer, &bBuffer, &destinationBuffer, 0);
    NSImage* image = nil;
    if(result == kvImageNoError)
    {
        //TODO: If you need color matching, use an appropriate colorspace here
        CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
        CGDataProviderRef dataProvider = CGDataProviderCreateWithCFData((__bridge CFDataRef)(destinationImageData));
        CGImageRef finalImageRef = CGImageCreate(size.width, size.height, 8, 24, destinationBuffer.rowBytes, colorSpace, kCGBitmapByteOrder32Big|kCGImageAlphaNone, dataProvider, NULL, NO, kCGRenderingIntentDefault);
        CGColorSpaceRelease(colorSpace);
        CGDataProviderRelease(dataProvider);
        image = [[NSImage alloc] initWithCGImage:finalImageRef size:NSMakeSize(size.width, size.height)];
        CGImageRelease(finalImageRef);
    }
    free((void*)destinationImageBytes);
    return image;

最佳答案

解决方案(或者至少是一个解决方案的开始):

err = vImageExtractChannel_ARGB8888(&_src, &_blu, 2, kvImageNoError);
...
uint8_t copyMask = 1;
vImageOverwriteChannels_ARGB8888(&_blu, &_src, &_dst, copyMask, kvImageNoFlags);

这对我有用,除了我正在开发的 iOS 相机应用程序的 OpenCV 版本;预览窗口在一侧显示一条白色条纹,每次 OpenCV 不喜欢我做某事的方式时它都会这样做。我认为这不会是您的问题,并且鉴于您的多行代码只需要三行代码,因此值得尝试。

关于objective-c - vImageConvert 提取一个 channel ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17683403/

相关文章:

ios - Apple Pay 应用内配置卡

objective-c - 是否可以在现有 XCode 项目 (OS X) 中用 Chromium (CefBrowser) 替换 WebView?

objective-c - 如何在 Objective-C (OS X) 中使用静态库?

ios - 使用 renderInContext 的 Obj-C

objective-c - Cocoa - 计算两个日期之间的工作日

cocoa - 仅显示一次密码提示 - 如何?

objective-c - Swift 中 NSDictionary 函数的问题

android 将图像设置为联系人图标/墙纸

Jquery照片比较

macos - 为什么 TrueType 字体在 Mac 上仅使用 "Quadratic Curves"?