我的OpenGL ES学习之路(六):GPUImage原理分析

如果自定义一个OpenGL ES程序来处理图片,步骤如下:

  • 初始化OpenGL ES环境,编译、链接Vertex ShaderFragment Shader
  • 缓存顶点、纹理坐标数据,传送图像数据到GPU
  • 绘制图元到特定的帧缓存
  • 在帧缓存中取出绘制的图像

其中GPUImageFilter负责的是第一、二、三步,
GPUImageFrameBuffer负责的是第四步。

GPUImageFilter

GPUImageFilter实现了 GPUImageInput协议,可以输出纹理参与GPUImage的响应链,或者从响应链的接受纹理数据并处理图像

GPUImageFrameBuffer

管理纹理缓存格式帧缓存的buffer

GPUImage是一个开源的基于OpenGL ES的图片视频处理框架,内置了非常多的常见滤镜效果,支持照相机和摄像头的实时滤镜,并且能够自定义图像滤镜
GPUImage采用链式方法来处理,通过addTarget方法添加对象到链中,处理完一个target,会把上一个环节处理好的数据图像传递到下一个target处理。

  • GPUImageVideoCamera: 是GPUImageOutput的子类,摄像头用于实时拍摄视频,提供来自摄像头的图像数据作为源数据,一般是响应链的源头。
  • GPUImageStillCamera: 摄像头用于实时拍摄照片
  • GPUImagePicture: 用于静态图像处理操作,可以是需要处理的静态图片,也可以是一张作为纹理使用的图片,调用它的processImage方法,进行图像滤镜处理
  • GPUImageMovie: 用于处理已经拍摄好的视频

  • GPUImageFilter: 用来接收源图像,通过自定义的Vertex ShaderFragment Shader来渲染新的图像,并在绘制完成后通知响应链的下一个对象
  • GPUImageFilter的子类或者父类: 继承于GPUImageOutput,遵守GPUImageInput协议,既可以流进数据,又可以流出数据
  • GPUImageView 和 GPUImageMovieWriter: 最终的输入目标,显示图片或者视频

混合滤镜

  • 方式一:直接添加多个滤镜
GPUImagePicture *result = [[GPUImagePicture alloc] initWithImage: originalImage];
[result addTarget: filter1];
[result processImage];
[result addTarget: filter2];
[result processImage];
  • 方式二:通过GPUImageFilterGroup,它是多个filter的集合

YUV

yuvConversionProgram: 将YUV颜色值转换成RGB值的程序(连接Vertex ShaderFragment Shader

美颜

磨皮

磨皮的本质实际上是模糊。而在图像处理领域,模糊就是将像素点的取值与周边的像素点取值相关联。而我们常见的高斯模糊 ,它的像素点取值则是由周边像素点求加权平均所得,而权重系数则是像素间的距离的高斯函数,大致关系是距离越小、权重系数越大。
如果单单使用高斯模糊来磨皮,得到的效果是不尽人意的。原因在于,高斯模糊只考虑了像素间的距离关系,没有考虑到像素值本身之间的差异。
举个例子来讲,头发与人脸分界处(颜色差异很大,黑色与人皮肤的颜色),如果采用高斯模糊则这个边缘也会模糊掉,这显然不是我们希望看到的。而双边滤波(Bilateral Filter) 则考虑到了颜色的差异,它的像素点取值也是周边像素点的加权平均,而且权重也是高斯函数。不同的是,这个权重不仅与像素间距离有关,还与像素值本身的差异有关,具体讲是,像素值差异越小,权重越大,也是这个特性让它具有了保持边缘的特性,因此它是一个很好的磨皮工具。

你可能感兴趣的:(我的OpenGL ES学习之路(六):GPUImage原理分析)