GPUImage raw数据直接进入filter,再获取raw数据

GPUImage 是强大的图像处理库,基于其架构可以很简单的搭建起图像,视频采集,处理的应用。但如果要把其加入到一个成熟的商业系统中,则比较麻烦,需要修改已有的图像处理框架适应GPUImage的框架。
本博介绍一种简单的方法,直接把已有系统中的raw数据导入GPUImage的filter中,再读取回已有系统。
上代码:

  1. 先加入头文件:
#import <GPUImage/GPUImage.h>
  1. 在已有类中加入,GPUImage filter对象,GPUImageRawDataOutput是必须的,其他filter根据自己需要选择:在已有类中加入,GPUImage filter对象,GPUImageRawDataOutput是必须的,其他filter根据自己需要选择:
GPUImageBilateralFilter *_bilateralFilter;
GPUImageRawDataOutput *_rawdataOutput;
  1. 在已有类中加入,两个属性,semaphore用于主程序和gpuimage处理同步,rawBytesForImage用于gpuimage返回raw数据:
@property (nonatomic, strong) dispatch_semaphore_t semaphore;
@property (nonatomic) GLubyte *rawBytesForImage;
  1. 已有类初始化时,初始化GPUImage对象:
//setup:
        _rawBytesForImage = (unsigned char*)malloc(1280*720*4);
        _semaphore = dispatch_semaphore_create(0);
        _rawdataOutput = [[GPUImageRawDataOutput alloc] initWithImageSize:CGSizeMake(1280.0,720.0) resultsInBGRAFormat:YES];

        _bilateralFilter = [[GPUImageBilateralFilter alloc] init];
        [_bilateralFilter setDistanceNormalizationFactor:(5)];
        [_bilateralFilter addTarget:_rawdataOutput];
        __weak GPUImageRawDataOutput *weakOutput = _rawdataOutput;
        __weak typeof(self) ws = self;
        __unsafe_unretained GPUImageRawDataOutput *_rawDataOutputFilter = _rawdataOutput;
        [_rawdataOutput setNewFrameAvailableBlock:^{
            __strong GPUImageRawDataOutput *strongOutput = weakOutput;
            
            [_rawDataOutputFilter lockFramebufferForReading];
            
            GLubyte *data  = [_rawDataOutputFilter rawBytesForImage];
            memcpy(ws.rawBytesForImage, data, 1280*720*4);
            CGSize bufSize = [_rawDataOutputFilter maximumOutputSize];
            
            [_rawDataOutputFilter unlockFramebufferAfterReading];
            dispatch_semaphore_signal(ws.semaphore);       
            [_rawDataOutputFilter setImageSize:CGSizeMake(1280.0,720.0)];
        }];
  1. 在已有类的图像处理函数中,调用GPUImage filter处理sampleBuffer中的数据,sampleBuffer是CMSampleBufferRef类型数据
    CVImageBufferRef videoFrame = CMSampleBufferGetImageBuffer(sampleBuffer);
    CVPixelBufferLockBaseAddress(videoFrame, 0);

    uint8_t *baseAddress = (uint8_t *) CVPixelBufferGetBaseAddress(videoFrame);
    size_t stride = CVPixelBufferGetBytesPerRow(videoFrame);
    size_t width = CVPixelBufferGetWidth(videoFrame);
    size_t height = CVPixelBufferGetHeight(videoFrame);

    [GPUImageContext useImageProcessingContext];


    GPUImageFramebuffer *outputFramebuffer = [[GPUImageContext sharedFramebufferCache] fetchFramebufferForSize:CGSizeMake(stride / 4, height) onlyTexture:YES];
    [outputFramebuffer activateFramebuffer];
   
    glBindTexture(GL_TEXTURE_2D, [outputFramebuffer texture]);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, stride / 4, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, CVPixelBufferGetBaseAddress(videoFrame));

    CVPixelBufferUnlockBaseAddress(videoFrame, 0);

    CMTime time = CMSampleBufferGetPresentationTimeStamp(sampleBuffer);
    //simulate GPUImage call
    [_bilateralFilter setInputSize:CGSizeMake(width, height) atIndex:0];
    [_bilateralFilter setInputFramebuffer:outputFramebuffer atIndex:0];
    [_bilateralFilter newFrameReadyAtTime:time atIndex:0];    
    size_t size = 1280*720*4;
    dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
    memcpy(baseAddress, self.rawBytesForImage, size);
    
    CVPixelBufferUnlockBaseAddress(videoFrame, 0);

最后重点:PC上数据从CPU导入GPU真是耗费CPU啊,尤其是在有独立显卡的机器上,GPU处理节约的时间还不够内存导入导出的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值