绿幕抠像技术早已不是什么高大上的新兴技术,但是应用场景还是非常多的,今天我们基于ffmpeg滤镜一起探讨一下绿幕抠图原理。

RGB颜色模型

如图用三维空间坐标表示rgb颜色,以rgb24为例rgb各自取值范围为0~255,argb、rgba等带透明度的格式也是在三维rgb基础上加上一个透明度维度,不详细讨论。坐标轴上每一个点代表一个颜色,两点之间的距离可以认为是两个颜色之间的相识度,为了方便表示经常以颜色间距离和灰度线的百分比来表示。

YUV颜色空间

yuv颜色空间是u分量和v分量,可以想象到是一个简单的二维空间,空间内部两点间距离就是两个颜色间的相似程度,一般以相识距离和中轴线的百分比来表示相似度。

ffmpeg源码

  1. ffmpeg滤镜chromakey针对yuv处理,将对应像素点标记透明。
static uint8_t do_chromakey_pixel(ChromakeyContext *ctx, uint8_t u[9], uint8_t v[9])
{double diff = 0.0;int du, dv, i;for (i = 0; i < 9; ++i) {du = (int)u[i] - ctx->chromakey_uv[0];dv = (int)v[i] - ctx->chromakey_uv[1];diff += sqrt((du * du + dv * dv) / (255.0 * 255.0 * 2));}diff /= 9.0;if (ctx->blend > 0.0001) {return av_clipd((diff - ctx->similarity) / ctx->blend, 0.0, 1.0) * 255.0;} else {return (diff > ctx->similarity) ? 255 : 0;}
}
static int do_chromakey_slice(AVFilterContext *avctx, void *arg, int jobnr, int nb_jobs)
{AVFrame *frame = arg;const int slice_start = (frame->height * jobnr) / nb_jobs;const int slice_end = (frame->height * (jobnr + 1)) / nb_jobs;ChromakeyContext *ctx = avctx->priv;int x, y, xo, yo;uint8_t u[9], v[9];memset(u, ctx->chromakey_uv[0], sizeof(u));memset(v, ctx->chromakey_uv[1], sizeof(v));for (y = slice_start; y < slice_end; ++y) {for (x = 0; x < frame->width; ++x) {for (yo = 0; yo < 3; ++yo) {for (xo = 0; xo < 3; ++xo) {get_pixel_uv(frame, ctx->hsub_log2, ctx->vsub_log2, x + xo - 1, y + yo - 1, &u[yo * 3 + xo], &v[yo * 3 + xo]);}}frame->data[3][frame->linesize[3] * y + x] = do_chromakey_pixel(ctx, u, v);}}return 0;
}

通过源码可以看到ffmpeg的处理是遍历像素点计算和给定色键的相识度并将范围内的像素点做透明标记。

2.ffmpeg滤镜colorkey针对rgb处理,将目标像素点设置为透明。

static uint8_t do_colorkey_pixel(ColorkeyContext *ctx, uint8_t r, uint8_t g, uint8_t b)
{int dr = (int)r - ctx->colorkey_rgba[0];int dg = (int)g - ctx->colorkey_rgba[1];int db = (int)b - ctx->colorkey_rgba[2];//计算相似度double diff = sqrt((dr * dr + dg * dg + db * db) / (255.0 * 255.0 * 3.0));if (ctx->blend > 0.0001) {return av_clipd((diff - ctx->similarity) / ctx->blend, 0.0, 1.0) * 255.0;} else {return (diff > ctx->similarity) ? 255 : 0;}
}
static int do_colorkey_slice(AVFilterContext *avctx, void *arg, int jobnr, int nb_jobs)
{AVFrame *frame = arg;const int slice_start = (frame->height * jobnr) / nb_jobs;const int slice_end = (frame->height * (jobnr + 1)) / nb_jobs;ColorkeyContext *ctx = avctx->priv;int o, x, y;for (y = slice_start; y < slice_end; ++y) {for (x = 0; x < frame->width; ++x) {o = frame->linesize[0] * y + x * 4;// 修改rgba a数据frame->data[0][o + ctx->co[3]] =do_colorkey_pixel(ctx,frame->data[0][o + ctx->co[0]],frame->data[0][o + ctx->co[1]],frame->data[0][o + ctx->co[2]]);}}return 0;
}

通过源码可以看到和chromakey类似也是遍历像素点,逐一计算像素点和色键的相似度,将范围内的像素标记为透明。

ffmpeg绿幕抠图原理解析相关推荐

  1. OpenGL绿幕抠图原理

    1.计算当前像素点RGB值对应的HSV值 2.设定HSV三个分量的权重,根据权重计算当前像素点的HSV值到给定背景色的HSV值的欧式距离 3.将欧式距离用smoothstep做平滑,0.5以下的一定要 ...

  2. 编程去除背景绿幕抠图,基于.NET+OpenCVSharp

    摘要:本文介绍了一种使用OpenCVSharp对摄像头中的绿幕视频进行实时"抠人像.替换背景"的方式,对于项目中的算法进行了分析.本文中给出了简化OpenCVSharp中Mat.M ...

  3. 绿幕抠图在手机上使用认识.

    简单介绍 疑问1: 绿幕技术在手机APP上合适吗? 毕竟带着绿布在户外不现实. 是的, 太不现实了, 我们之前不做也是这样想的, 用户量不大, 使用场景不大. 没有谁愿意在户外先支好绿布,然后再拍视频 ...

  4. 绿幕抠图SDK技术对比

    复杂度 现实环境的影响:绿色不是一个固定的像素值, 它会随光线亮暗,绿布的颜色, 相机的成像质量,反光,色溢等各种因素影响,所以不能用简单的判断一个像素值,就认为是绿或不绿:也不是一个平滑过度的值,比 ...

  5. [小脚本] 基于opencv 的绿幕抠图

    网上有一些 基于 opencv-python 的绿幕抠图算法,大多比较简单,只写明了最简单的原理,比如就是选择指定范围的颜色,然后在这个范围内的就抠掉. 但是简单的这样有一些问题,就是比如: 1)有些 ...

  6. html5 自动扣图,canvas像素点操作之视频绿幕抠图

    本文介绍了canvas像素点操作之视频绿幕抠图,分享给大家,具体如下: 用法: context.putimagedata(imgdata, x, y, dx, dy, dwidth, dheight) ...

  7. Direct3D 11 总结 —— 8 实现简单的绿幕抠图效果

    介绍 绿幕抠图指将图片中的绿色扣去,并将该处的 alpha 分量设为 0,并将另外一张图片作为背景,以实现背景替换的功能,常用于电影和电视的制作场景. 最终效果 原始图片 绿幕抠图后效果 代码 这一块 ...

  8. 【我的OpenGL学习进阶之旅】 OpenGL ES 实现 绿幕抠图 以及 替换绿幕背景的功能

    一.绿幕抠图 "近来,我们总是不经意间看到一些自媒体公众号,影评人在谈到某部上映的影视剧制作如何稀烂,演员如何不敬业时总会用到"抠图"这个词.似乎"抠图&quo ...

  9. 蓝松绿幕抠图使用说明

    文章目录 提供两种形式. 方式1: 业务功能型 形式2: 纯净API类型 集成说明 常见问答 1. 如何支持多机位. 2. 如何支持合流 3. 绿色物体不想被抠去怎么办? 4. 如何推流 5. 如何外 ...

最新文章

  1. 方便的boost_python
  2. 调试代码 2017-03-13
  3. PyQt5 技术篇-QTableWidget表格组件指定行的隐藏与显示控制实例演示,设置表格指定列的列宽方法
  4. C语言 memset()函数(内存初始化函数)
  5. oracle 9i aix 迁移,Oracle 9i 在AIX上的安装 (转)
  6. 使用蚂蚁借呗会影响房贷申请吗?
  7. shell脚本中取消高亮显示_Linux中强大的top命令
  8. IDEA或Webstorm设置Terminal终端字体大小
  9. 大坑:用SQLyog连mysql的部分操作不能同步到从库
  10. 100道Python练习题集合,拿去刷
  11. 关于阿狸狗破戒大师自动安装完cadence17.4后licence不可用问题
  12. Python程序设计——基本语法
  13. 阿里巴巴著名的“管理三板斧”
  14. 项目2-Time类中的运算符重载
  15. uniapp uniCloud 云开发上传图片与查看图片
  16. firefox浏览器linuxwin10安装,数据互通,firefox国际版
  17. 可拖拽的弹出窗口Js插件
  18. 电信:自娱自乐的全员揽装,让人心寒!
  19. 将电脑调成护眼色不一定起到护眼的功能
  20. windows聚焦壁纸不更新_Win10无法自动更换聚焦锁屏壁纸怎么办?

热门文章

  1. matlab基础编程学习
  2. c语言:判断某人是否属于肥胖体型。根据身高与体重因素,医务工作者经广泛的调查分析给出了以下按“体指数”对肥胖程度的划分:体指数t=w/(h*h)(w为体重,单位为kg,h为身高,单位为m)。
  3. 301重定向存在的问题
  4. 会声会影2019专业序列号激活版(视频制作软件)V22.3.0.439 简体中文
  5. WiFi 射频测试指标学习之路
  6. 第十六章 BIRT疑难杂惑清理
  7. 想开抖音小店无货源的朋友看过来,教你零成本开店
  8. Mycat2.0搭建教程
  9. Android ListView嵌套ListView的实现方式
  10. 圆弧防线用计算机怎么算,圆弧放线计算公式