有没有人有 iOS 上 vImage 处理的示例代码?

Posted

技术标签:

【中文标题】有没有人有 iOS 上 vImage 处理的示例代码?【英文标题】:Does anyone have example code for vImage processing on iOS? 【发布时间】:2010-12-09 19:19:30 【问题描述】:

我已经阅读了所有可以找到的文档,但无法让简单的 vImage 调用正常工作。我只需要一个真实的例子。文档非常稀少。

【问题讨论】:

查看http://***.com/questions/10068095/uiimage-become-fuzzy-when-it-was-scaled-whyios-5-0获取一些示例代码 【参考方案1】:

如果您正在实时处理视频,并且您的输入是在像素缓冲区中处理的,以下是如何将该缓冲区复制到 vImage 中,此时您可以调用任何您喜欢的命令:

- (CVPixelBufferRef)copyRenderedPixelBuffer:(CVPixelBufferRef)pixelBuffer
 
    CVPixelBufferLockBaseAddress( pixelBuffer, 0 );

    // vImage processing
    vImage_Error err;
    vImage_Buffer buffer;
    buffer.data = (unsigned char *)CVPixelBufferGetBaseAddress( pixelBuffer );
    buffer.rowBytes = CVPixelBufferGetBytesPerRow( pixelBuffer );
    buffer.width = CVPixelBufferGetWidth( pixelBuffer );
    buffer.height = CVPixelBufferGetHeight( pixelBuffer );
    vImageCVImageFormatRef vformat = vImageCVImageFormat_CreateWithCVPixelBuffer( pixelBuffer );
    vImage_CGImageFormat cgformat = 
        .bitsPerComponent = 8,
        .bitsPerPixel = 32,
        .bitmapInfo = kCGBitmapByteOrderDefault,
        .colorSpace = NULL,    //sRGB
    ;
    const CGFloat bgColor[3] = 0.0, 0.0, 0.0;
    vImageBuffer_InitWithCVPixelBuffer(&buffer, &cgformat, pixelBuffer, vformat, bgColor, kvImageNoAllocate);

    vImage_Buffer outbuffer;
    void *tempBuffer;
    tempBuffer = malloc(CVPixelBufferGetBytesPerRow( pixelBuffer ) * CVPixelBufferGetHeight( pixelBuffer ));
    outbuffer.data = tempBuffer;
    outbuffer.rowBytes = CVPixelBufferGetBytesPerRow( pixelBuffer );
    outbuffer.width = CVPixelBufferGetWidth( pixelBuffer );
    outbuffer.height = CVPixelBufferGetHeight( pixelBuffer );

    err = vImageEqualization_ARGB8888(&buffer, &outbuffer, kvImageNoFlags);

    if(err != -1)
        err = vImageContrastStretch_ARGB8888(&buffer, &outbuffer, kvImageNoFlags);

    if(err != -1)
        err = vImageBuffer_CopyToCVPixelBuffer(&outbuffer, &cgformat, pixelBuffer, vformat, bgColor, kvImageNoFlags);

    if(err != -1)
        free(tempBuffer);

    CVPixelBufferUnlockBaseAddress( pixelBuffer, 0 );

    return (CVPixelBufferRef)CFRetain( pixelBuffer );

【讨论】:

【参考方案2】:

更新 Ole Bermann 的回答:在 iOS 5.0 中添加了 Accelerate 框架。

【讨论】:

【参考方案3】:

一个更高级的例子,优化了均衡和拉伸函数(忽略注释掉的代码,虽然你可以使用它——它也可以工作:

- (CVPixelBufferRef)copyRenderedPixelBuffer:(CVPixelBufferRef)pixelBuffer 

CVPixelBufferLockBaseAddress( pixelBuffer, 0 );

unsigned char *base = (unsigned char *)CVPixelBufferGetBaseAddress( pixelBuffer );
size_t width = CVPixelBufferGetWidth( pixelBuffer );
size_t height = CVPixelBufferGetHeight( pixelBuffer );
size_t stride = CVPixelBufferGetBytesPerRow( pixelBuffer );

vImage_Buffer _img = 
    .data = base,
    .height = height,
    .width = width,
    .rowBytes = stride
;

vImage_Error err;
vImage_Buffer _dstA, _dstR, _dstG, _dstB;

err = vImageBuffer_Init( &_dstA, height, width, 8 * sizeof( uint8_t ), kvImageNoFlags);
if (err != kvImageNoError)
    NSLog(@"vImageBuffer_Init (alpha) error: %ld", err);

err = vImageBuffer_Init( &_dstR, height, width, 8 * sizeof( uint8_t ), kvImageNoFlags);
if (err != kvImageNoError)
    NSLog(@"vImageBuffer_Init (red) error: %ld", err);

err = vImageBuffer_Init( &_dstG, height, width, 8 * sizeof( uint8_t ), kvImageNoFlags);
if (err != kvImageNoError)
    NSLog(@"vImageBuffer_Init (green) error: %ld", err);

err = vImageBuffer_Init( &_dstB, height, width, 8 * sizeof( uint8_t ), kvImageNoFlags);
if (err != kvImageNoError)
    NSLog(@"vImageBuffer_Init (blue) error: %ld", err);

err = vImageConvert_ARGB8888toPlanar8(&_img, &_dstA, &_dstR, &_dstG, &_dstB, kvImageNoFlags);
if (err != kvImageNoError)
    NSLog(@"vImageConvert_ARGB8888toPlanar8 error: %ld", err);

err = vImageEqualization_Planar8(&_dstR, &_dstR, kvImageNoFlags);
if (err != kvImageNoError)
    NSLog(@"vImageEqualization_Planar8 (red) error: %ld", err);

err = vImageEqualization_Planar8(&_dstG, &_dstG, kvImageNoFlags);
if (err != kvImageNoError)
    NSLog(@"vImageEqualization_Planar8 (green) error: %ld", err);

err = vImageEqualization_Planar8(&_dstB, &_dstB, kvImageNoFlags);
if (err != kvImageNoError)
    NSLog(@"vImageEqualization_Planar8 (blue) error: %ld", err);

err = vImageConvert_Planar8toARGB8888(&_dstA, &_dstR, &_dstG, &_dstB, &_img, kvImageNoFlags);
if (err != kvImageNoError)
    NSLog(@"vImageConvert_Planar8toARGB8888 error: %ld", err);

err = vImageContrastStretch_ARGB8888( &_img, &_img, kvImageNoError );
if (err != kvImageNoError)
    NSLog(@"vImageContrastStretch_ARGB8888 error: %ld", err);

err = vImagePermuteChannels_ARGB8888(&_img, &_img, map, kvImageNoFlags);
if (err != kvImageNoError)
    NSLog(@"vImagePermuteChannels_ARGB8888 error: %ld", err);

free(_dstA.data);
free(_dstR.data);
free(_dstG.data);
free(_dstB.data);

CVPixelBufferUnlockBaseAddress( pixelBuffer, 0 );

return (CVPixelBufferRef)CFRetain( pixelBuffer );

【讨论】:

【参考方案4】:

文档不存在,因为 vImage 库在 iOS 上不可用。

vImage 自 5.0 起可在 iOS 上使用。 The documentation is here.

【讨论】:

我相信它们是 Accelerate 框架的一部分。我可以得到 vImage_Buffer 之类的东西来编译。 @akaru - 这是在 Mac 上,而不是 iOS。 vDSP 和 BLAS 在 iOS 上,但不在其他库上:developer.apple.com/library/ios/#documentation/Accelerate/… 如果您以模拟器为目标,您可能会编译与 vImage 相关的代码,因为它在 Mac 上运行,但在 iOS 设备上无法运行。 @brad 感谢您的提醒。我正在使用模拟器。哦! vImage 自 5.0 起在 iOS 上可用

以上是关于有没有人有 iOS 上 vImage 处理的示例代码?的主要内容,如果未能解决你的问题,请参考以下文章

IOS操作完成后如何释放vImage缓冲区

对于IOS,如何使用vImage将ARGB图像转换为灰度图像

Accelerate 的 vImage 与 vDSP

如何从 vImage_Buffer 到 CVPixelBufferRef

如何编译vImage浮雕效果示例代码?

iOS和Windows Phone的Android Renderscript等效于什么?