写点什么

短视频的色彩特效原来是这样做出来的

  • 2019-10-29
  • 本文字数:2521 字

    阅读完需:约 8 分钟

短视频的色彩特效原来是这样做出来的

从眼睛的进化说起

大约在 5 亿 4 千万年前的寒武纪,地球上一部分生物体开始进化出了感光细胞,这种细胞可以感应光线的强弱,并且直接驱动本体的运动细胞采取必要的规避动作,以确保脆弱的细胞不被紫外线所伤。


后来单个的感光细胞开始扎堆聚集并且形成了凹陷,随着凹陷程度的逐步加深,这些感光细胞也就渐渐地汇聚成了一个前部有孔隙的球状结构,“眼球”的雏形也就由此形成了。



随着球形的眼睛结构渐渐成型,中学物理课本中的“小孔成像”原理也就越来越能发挥作用:只要开孔足够小,光线就能准确地到达这些聚集的感光细胞进而成像,眼前的物体也就开始变得边界清晰。代表腾讯文化吉祥物之一的鹦鹉螺,就是采用了这种“以小为美”的进化策略,而且一直坚持到现在。


但是这种越来越小的策略也会导致光线进入量越来越小,所以鹦鹉螺们的世界想必是很昏暗的。我们的祖先可不希望放弃一个光明的世界,所以,我们给自己的眼睛安装了一个足够高级的光学部件 —— 晶状体,以期拥有一个光明而清晰地世界。


然而,当大家都能把世界看得很清楚的时候,色彩分辨能力也就演变成了新一轮的军备竞赛。


当我们的祖先踩着那些坚称“我就想健健康康地当个素食主义者”的同类尸体艰难前行的时候,他们并不知道,让自己活得更久的原因,竟然是因为那双能区分树叶是嫩叶还是成熟叶片的眼睛。因为成熟的叶片常常包含大量的植物性毒素,会让进食者身体遭受很大的伤害。所以,我们都是那一波“好色的”猴子的后代。


而眼睛对色彩的分辨能力,不仅在远古时代让我们活了下来,也让今天衣食无忧的我们,能看到更多色彩斑斓的效果。


比如短视频的移形换影特效,其本质原理就是一个充分利用色彩的小把戏。

三原色的修改和组合

人体有三种视觉锥细胞,所以我们看到的颜色都是由三原色组成的,并不是说世界上就只有这些颜色,而是更加绚丽的色彩空间我们也感知不到。


因此,液晶显示器的成像原理上也就是基于 R(红)G(绿)B(蓝) 三原色的组合而实现的,腾讯云短视频(UGSV)的移形换影特效,就是在这三种颜色空间上做了一些文章:


先以一幅静态的图片来举例:



Doloris


现在把图片中红色的分量去掉,放大 10%,再移动一些距离。



Doloris-strip-red


再把蓝色的分量去掉,放大 10%,并移动一些距离。



Doloris-strip-blue


再把绿色的分量去掉,放大 10%,并移动一些距离。



Doloris-strip-green


然后将这三副图片以 33%的透明度和源图叠加到一起,形成一种移形幻影的效果。



Doloris-blend

交给计算机来实现

上面这些图片是我用图片处理软件简单处理后得到的,但如果是视频文件,显然要交给计算机自动解决,如何做到呢?


首先我们先给这幅图片定义坐标,为了方便处理我们将图片的中心点定义为 (0,0),图片的 XY 轴最大值为 1,如下图所示:



坐标定义


然后开始处理上面提到的两个变换,一个是放大,一个是移动。


  • 放大如果定义图片上的任意象素坐标是(x,y),放大 s 倍后的坐标就是 (x’,y’) = s(x,y) = (sx, sy)

  • 移动如果定义图片上的任意象素坐标是(x,y),将其移动(?x,?y),移动后的坐标就是(x’,y’) = (x+?x, y+?y)

  • 合并将上面两个公式进行合并,得到的新坐标点就是 (x’,y’) = (s(x+?x), s(y+?y))

  • 叠加然后我们要将修改过的图片叠加到原图上,alpha 叠加的公式是 src * (1 - alpha) + overlay * alpha。

基于 OpenGL 的版本

短视频的特效处理,每秒钟要处理几十张甚至更多的视频画面,所以简单的 C 语言处理算法并不能满足性能上的要求,我们需要使用手机的硬件加速能力,目前除了常见的 OpenGL 等 API 之外,还有如 Vulkan, DirectX, Metal 等可选方案。就目前而言,OpenGL 在各平台上通用性最好,网上的资料也比较丰富,不论是桌面平台还是移动平台都有支持,本文就以 OpenGL 来讲讲特效的实现。


实现移形换影特效的时候,我们会用到 OpenGL 的 Fragment Shader, Fragment Shader 作用就是返回图像各点的色值,Fragment Shader 也有一套自己的编程语言,叫 Shading Language 简称 GLSL, GLSL 和 C 很像,增加了一些向量的数据类型,和一些图像相关的处理函数。Shading 和 C 比起来有一个比较特殊的地方是不支持隐含的类型转换,比如浮点点整型的转换(在使用浮点数时,一定要加上小数点,如 1.0)。


篇幅原因,我不在这里把所有的特效代码都一一列举了,仅附上放大和位移的部分实现:


varying vec2 textureCoordinate;uniform sampler2D inputImageTexture;void main() {  vec2 offset = vec2(0.05, 0.05);  float scale = 1.1;  vec2 coordinate;  coordinate.x = (textureCoordinate.x - offset.x) / scale;  coordinate.y = (textureCoordinate.y - offset.y) / scale;  gl_FragColor = texture2D(inputImageTexture, coordinate);}
复制代码


考虑到不是所有读者都学过 Shading Language,这里做一个简单的解读:


  • 我们在这里定义了一个变量 coordinate,这个就是前面提到的(x,y),它的值就是 ((x - ?x)/s, (y-?y)/s)。

  • 函数 texture2D 的作用就是从图片中获取某个坐标的颜色。这里从 inputImageTexture 中的 coodinate 坐标点获取了颜色。

  • gl_FragColor, 这是 Fragment Shader 的输出的值, gl_FragColor 是一个 GLSL 预定义的全局变量, 类型是 vec4 既 (r,g,b,a) 这四个量,也就是一个 RGBA 颜色。

  • 程序运行后在 textureCoordinate 这个坐标就会显示 gl_FragColor 这个颜色。


上面讲了单幅图的处理,对于视频我们可以做些更有意思的效果,比如我们可以把当前帧和上一帧的图片进行叠加,这样就可以作出一些更有意思的效果。


更多特效

本文介绍了腾讯云短视频(UGSV)众多视频特效中的一种,如果要实现更加复杂的特效,还是需要继续深入研究 OpenGL 和人脸识别等相关领域的知识,这需要一段时间的学习和努力,也不可避免的需要踩很多坑。


作者介绍:


常青, 2008 年毕业加入腾讯,一直从事客户端研发相关工作,先后参与过 PC QQ、手机 QQ、QQ 物联 等产品项目,目前在腾讯视频云团队负责音视频终端解决方案的优化和落地工作,帮助客户在可控的研发成本投入之下,获得业内一流的音视频解决方案,目前我们的产品线包括:互动直播、点播、短视频、实时视频通话,图像处理,AI 等等。


本文转载自公众号云加社区(ID:QcloudCommunity)。


原文链接:


https://mp.weixin.qq.com/s/qEF8syevmQ25Ot2G9KMlyg


2019-10-29 14:321097

评论

发布
暂无评论
发现更多内容

太为难我了,阿里面试了7轮(5年经验,拿下P7岗offer)

Java 程序员 架构 面试

双非渣本后端,三个月逆袭字节,入职那天“泪目”了

Java架构师迁哥

架构实战营 模块六:课后作业

Ahu

架构实战营

Redis入门一:简介

打工人!

数据库 nosql redis 6月日更

排序算法之冒泡排序

xcbeyond

排序算法 冒泡排序 6月日更

窥见AI工业化开发黎明:华为云如何将AI进行到底

脑极体

Linux之pwd命令

入门小站

Linux

Angular | 浅谈Angular错误处理方式

devpoint

angular.js angular 6月日更

经济日报刊评:数字人民币应用场景拓展

CECBC

电商系统微服务拆分设计

Lane

模块6 学习总结

TH

前端 JavaScript 之『节流』的简单代码实现

编程三昧

JavaScript 大前端 js 防抖节流 代码实现

冯 · 诺依曼结构原理及层次结构分析

若尘

计算机组成原理

setTimeout(〒︿〒) 请原谅我一直以来对你的忽视

编程三昧

JavaScript 大前端 定时器 基础知识

韩信大招:一致性哈希

悟空聊架构

分布式 一致性hash 6月日更 hash算法

三星T5 格式化成APFS

SamGo

学习 硬件产品

模块6作业 拆分电商系统为微服务

TH

架构实战营

手写一个简单的SpringBoot Starter

赵镇

🌏【架构师指南】分布式事务(XA)与一致性算法(Paxos、Raft、Zab、NWR)

码界西柚

ZAB raft协议 paxos协议 6月日更

如何应对不好回应的沟通场景?

石云升

读书笔记 沟通 6月日更

1年半经验,2本学历,Curd背景,竟给30K,我的美团Offer终于来了

Java 程序员 架构 面试

现在后端开发都在用什么数据库存储数据?

Linux服务器开发

MySQL 数据库 后端 中间件 Linux服务器开发

拆分电商系统为微服务

唐江

架构实战营

金融科技加速经济低碳转型 但面临政策、市场、技术等多方挑战

CECBC

「SQL数据分析系列」8. 分组和聚合

Databri_AI

数据库 sql 大数据 存储 计算

网络攻防学习笔记 Day49

穿过生命散发芬芳

网络攻防 6月日更

作为程序员,你会使用Notion吗?

Bob

程序员 Notion 笔记

Three.js杂记(十二)—— VR全景效果制作·中

空城机

大前端 three.js 6月日更

架构实战营 模块六作业

netspecial

架构实战营

模块6课后作业

方堃

堆与堆排序

wzh

Java 数据结构 算法 堆排序 数据结构与算法

短视频的色彩特效原来是这样做出来的_文化 & 方法_常青_InfoQ精选文章