Android平台美颜相机/Camera实时滤镜/视频编解码/影像后期/人脸技术探索——1.2 GPGPU解决方案简述

时间:2023-02-07 20:30:40

Github项目地址

回到目录

滤镜原理

滤镜说白了就是数字图像处理在视频播放、照片拍摄、后期上的具体应用
一个效果好的滤镜往往来自一个优秀的设计师,而不是一个深谙算法的程序员(当然提升效率还得靠图形程序员的帮助),所以设计师想要抢程序员饭碗真是太容易了。。。

例如,四邻域拉普拉斯算子对一幅图像进行卷积(锐化处理,突出边缘)的效果如下(转载自这里):
Android平台美颜相机/Camera实时滤镜/视频编解码/影像后期/人脸技术探索——1.2  GPGPU解决方案简述

GPU加速方案

我们在使用滤镜时,往往希望能够实时看到效果,如果在使用相机预览或者播放视频的时候,能够直接看到叠加了滤镜的效果,那就更棒了。

这个需求就限制了每一帧数据的处理时间——不能大于16ms,如果实在慢的不行,怎么着也得有个24FPS吧(虽然24FPS肯定会看出卡顿的)

用GPU进行加速的原因是GPU最擅长做并行计算,GPU处理每个像素的时间可能会大于CPU,但是扛不住GPU核心数多呀(和CPU核心不是一个概念),这个并行计算是有一定限制的:

  • 向GPU传递数据需要一定时间
  • 算法必须符合或局部符合SIMD(Single Instruction Multiple Data,单指令多数据,可以近似理解成循环的每一步操作互不相关)
  • 如果是传统GPGPU方案(例如OpenGL),算法需要进行大量改写以便适应渲染管线的表达方式

好在现在有CUDA和OpenCL(还有Vulkan、D3D什么的),在移动端OpenGL的版本3.0以上也快所占过半了(2017.01.29),大部分GPU都支持OpenCL(部分功能)
使用GPU进行加速,就是对于图像处理算法进行适当的改写,让GPU能够理解并符合GPU的执行方式(例如少用判断和循环等复杂控制结构,用矩阵简化运算等)

例如,我们想要把全景视频显示出来的界面变成黑白(灰度图),只需要这样修改之前我们写的fragment_shader

#extension GL_OES_EGL_image_external : require
precision mediump float;
varying vec2 vTextureCoord;
uniform samplerExternalOES sTexture;
void main() {
vec3 centralColor = texture2D(sTexture, vTextureCoord).rgb;
gl_FragColor = vec4(0.299*centralColor.r+0.587*centralColor.g+0.114*centralColor.b);
}

0.299,0.587,0.114是CRT中转灰度的模型(心理学公式),效果如下图所示:

Android平台美颜相机/Camera实时滤镜/视频编解码/影像后期/人脸技术探索——1.2  GPGPU解决方案简述

Github项目地址

回到目录