人像抠图 + OpenGL ES 还能这样玩?没想到吧

OpenGL ES 利用抠图算法实现人像留色

人像留色
人像留色

人像留色的原理

现在人像分割技术就像当初的人脸检测算法一样,称为广泛使用的基础算法。今天本文介绍的人像留色其实就是三年前某 AI 巨头利用 video 分割技术展示的应用场景:人体区域保留彩色,人体区域之外灰度化。所以人像留色的关键技术在于高精度高性能的分割算法。

OpenGL ES 利用抠图算法实现人像留色

首先利用分割算法获取到人像的 mask 图(灰度图),其中人像区域的灰度值大于 0 ,非人像区域的灰度值等于 0 。在 shader 中,首先对 mask 图采样判断采样点是否位于人像区域,然后分别进行不同的处理。

获取人像 mask 图

那么如何获取人像 mask 图?Github 上已经有很多大神开源了相关的分割或者抠图算法。

这里推荐 3 个比较受欢迎的开源项目

Multi-Human-Parsing

Multi-Human-Parsing

Multi-Human-Parsing 的优势在于支持多人不同部位的分割,同时支持目标检测和人体部位分割。

Multi-Human-Parsing 将人群场景图像划分为语义一致的属于身体部位或衣服物品的区域,从而为图像中的每个像素分配一个语义部位标签,以及它所属的身份. 有很多应用场景,如虚拟现实、视频监控、群体行为分析等。 Multi-Human-Parsing 的分割精度对于人体关键点检测其实够用了。

项目地址:
https://github.com/ZhaoJ9014/Multi-Human-Parsing

BackgroundMattingV2

Real-Time High-Resolution Background Matting

大名鼎鼎的 BackgroundMattingV2 算法,这也是本文所使用的抠图算法,主要特点就是实时、高分辨率、高精度的分割(Background Matting),项目免费可商用。

但是要在移动端落地的话,性能将会是很大的瓶颈,需要进行大量的算法优化,这也是目前大部分 AI 算法面临的问题:如何将 AI 算法落地到低算力平台。

项目地址:
https://github.com/PeterL1n/BackgroundMattingV2

TensorFlow Lite

TensorFlow Lite

TensorFlow Lite 是针对移动端的开源机器学习框架,支持 Android 和 iOS,提供了丰富的算法模型,包括图像分割、目标检测、图像分类、超分等模型。

其中分割模型支持的场景比较丰富,包括人体、宠物和物体等。

val labelsArrays = arrayOf(
  "background", "aeroplane", "bicycle", "bird", "boat", "bottle", "bus",
  "car", "cat", "chair", "cow", "dining table", "dog", "horse", "motorbike",
  "person", "potted plant", "sheep", "sofa", "train", "tv"
)

TensorFlow Lite 所提供的分割模型,使用 GPU 的话,单张 2K 的图处理时间在几百毫秒,基本上做不了 video 处理,另外分割精度也是 demo 级别的。

项目地址:
https://github.com/tensorflow/examples/tree/master/lite/examples/image_segmentation

人像留色的实现

人像留色 2

用于实现人像留色的简单 shader :

#version 300 es
precision mediump float;
in vec2 v_texCoord;
layout(location = 0) out vec4 outColor;
uniform sampler2D u_texture0;//rgba
uniform sampler2D u_texture1;//人像灰度图
uniform int u_renderType;
uniform float u_offset;
void main()
{
    float gray = texture(u_texture1, v_texCoord).r;//对 mask 进行采样
    vec4 rgba  = texture(u_texture0, v_texCoord);
    if(gray > 0.01) {
        outColor = rgba;
    }
    else
    {
        float Y = 0.299 * rgba.r + 0.587 * rgba.g + 0.114 * rgba.b;//RGB 灰度化
        vec4 grayColor = vec4(vec3(Y), 1.0);
        outColor = mix(grayColor, rgba, u_offset);//混合渐变
    }
}

shader 中首先对 mask 采样,然后判断采样点是否位于人像区域(灰度值是否大于 0 ),若采样点位于人像区域外,对颜色进行灰度化。

另外需要注意 OpenGL 访问的图像内存默认是 4 字节对齐,这样灰度 Mask 图的宽度不是 4 的整数倍的话,会有花屏现象,这里需要取消对齐设置:

glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, m_GrayTexId);
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, m_GrayImage.width, m_GrayImage.height, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, m_GrayImage.ppPlane[0]);
glBindTexture(GL_TEXTURE_2D, GL_NONE);

完整实现代码见项目:
https://github.com/githubhaohao/NDK_OpenGLES_3_0

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,233评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,013评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,030评论 0 241
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,827评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,221评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,542评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,814评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,513评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,225评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,497评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,998评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,342评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,986评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,812评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,560评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,461评论 2 266

推荐阅读更多精彩内容