Unity3D视频绿幕抠图的实现及优化

展开

本文是通过Shader处理绿幕的方式来实现Unity中视频(VideoPlayer)的绿幕抠图。因为项目原因,不追究细节(能用就好能用就好)orz可是我连shader都不了解......项目完成之后有机会的话一定要去深入学习一下!

效果大概这样

           

好了就让我们开始叭ヽ(ー_ー)ノ

Unity版本 5.6.7

下面是我找的一些关于shader的博客,可以去了解下

https://onevcat.com/2013/07/shader-tutorial-1/

https://onevcat.com/2013/08/shader-tutorial-2/

https://blog.csdn.net/oskytonight/article/details/42241301

另外,在寻求去除绿幕的方法时,也想过用OpenCVForUnity来做,对本文效果不满意的话说不定可以寻求OpenCVForUnity的方式。以下是我通过shader完成视频绿幕抠图及优化参考的博文:

https://blog.csdn.net/an050602/article/details/56479741?utm_source=blogxgwz9

https://blog.csdn.net/macjeson/article/details/50035073#commentBox

感谢博主大大们,收获颇多!在此作自我整理与回顾。

1.创建VideoPlayer

具体过程可以参考我的博文  https://blog.csdn.net/cs874300/article/details/89294433

2.创建Shader

在Project下的自己想要的文件夹下右键Create -> shader ->(具体哪种无所谓,反正都要替换掉emmm看下面代码的类型应该是Image effect Shader?)。以下为第二个链接的博主代码

Shader "MyShader/FilterfColor" { Properties { _MainTex ("Base (RGB)", 2D) = "white" {} _FilterfColor("Ridof (RGB)",Color)=(1,1,1,1) } SubShader { Tags { "RenderType"="Opaque" } Blend SrcAlpha OneMinusSrcAlpha pass { CGPROGRAM #pragma vertex vertext_convert#pragma fragment fragment_convert#include "UnityCG.cginc" sampler2D  _MainTex; sampler2D  _MainTex1; float4  _FilterfColor; struct Inputvrite { float4 vertex : POSITION; float4 texcoord : TEXCOORD0; }; struct Inputfragment { float4 pos : SV_POSITION; float4 uv : TEXCOORD0; }; float ColorLerp(float3 tmp_nowcolor,float3 tmp_FilterfColor) { float3 dis = float3(abs(tmp_nowcolor.x - tmp_FilterfColor.x),abs(tmp_nowcolor.y - tmp_FilterfColor.y),abs(tmp_nowcolor.z - tmp_FilterfColor.z)); float dis0 =sqrt(pow(dis.x,2)+pow(dis.y,2)+pow(dis.z,2)); float maxdis = sqrt(3); float dis1 = lerp(0,maxdis,dis0); return dis1; } Inputfragment vertext_convert(Inputvrite i) { Inputfragment o; o.pos = mul(UNITY_MATRIX_MVP,i.vertex); o.uv = float4(i.texcoord.xy,1,1); return o; } float4 fragment_convert(Inputfragment o) : COLOR { float4 c = tex2D(_MainTex,o.uv); c.a *=ColorLerp(c.rgb,_FilterfColor.rgb); return c; } ENDCG } } FallBack "Diffuse"
}

然后按第一个链接的博主所说,将其中fragment_convert的方法做如下改动。其基本思路就是将绿色的部分Alpha通道设为0(即透明)。其中gbr代表green blue red,0.5为比值(  green/255  )

float4 fragment_convert(Inputfragment o) : COLOR{float4 c = tex2D(_MainTex,o.uv);//简单的判断材质的RGB值if (c.g >0.5&&c.b<0.5&&c.r<0.5){c.a = 0;//材质的绿色大到一定程度,并且蓝色和红色小到一定程度,就把该部分的材质的透明度设置为0}return c;}

就博主的视频抠图而言,已经完成了。但是对于我的视频来说,还没有完成,因为我最后的效果是这样的

          

我知道绿幕的部分容易解决,可是多出来的白门和白墙和白鞋子是同一个颜色的。可不可以有再Shader中确定位置的方法,来把除了人物的周围部分的其他部分都设置为透明。然后找了半天基本都是和上面代码差不多的,或者就直接是复制的代码,完全没有自己的想法......遂放弃。在大量找shader相关资料的时候发现了一篇博文,是讲shader的uv坐标的,链接如下:

https://blog.csdn.net/xiongwen_li/article/details/66474826

其中有    i.uv.x=i.uv.x * i.uv.y; 这样的注释。我就想能不能通过这样的方式来限定位置条件(其实只是因为这句注释给了我启发,这篇文章倒是和本文没啥大关系)。然后我就在代码中加了以下几句:

if (o.uv.x < 0.25 || o.uv.x> 0.65 ||o.uv.y < 0.2 || o.uv.y >0.8) {c.a = 0;
}

如图,显然,达到了我想要的位置约束的效果。(完全就是瞎猫碰到死耗子...蒙出来的效果,所以说!如果shader了解的通透的话,这种简单的处理完全就是信手拈来啊!果然还是要提升知识水平啊orz)

除此之外,还可以通过QQ截图来获取某一像素点的RGB值(就当取色器用,真的很好用!)来作背景优化的约束条件,比如说像我就添加了以下的约束条件。因为颜色越深的地方,green可能不到0.5,但是会比red高很多,用此来作为条件优化。

if (o.uv.y > 0.65) {if (c.g > 0.34 && c.g > 1.1 * c.r) {c.a = 0;}
}
else {//绿色>红色值1.1倍就设为透明,可以优化边缘绿色,参数可调if (c.g > 1.1 * c.r) {c.a = 0;}}if (o.uv.x < 0.25 || o.uv.x> 0.65 ||o.uv.y < 0.2 || o.uv.y >0.8) {c.a = 0;
}

因为深绿色和头部的黑色有冲突,所以我把上部分和下部分分开优化,(还不是为了帮大师保留更多的头发!摔桌(/"— _ —)/~┴┴)但是用了好多if语句啊,感觉代码还是可以有改进的地方.

以下为最终效果图(我觉得海星(????)):

3. 将shader运用到视频或图片上

我这里是视频,图片同理。

1.在Project下的自定义文件夹内Create-> Material

2.将shader拖入刚创建的材质球(Material),然后我看材质球里面有个Texture,就把视频VideoPlayer的Target Texture中添加的那个Render texture也添加进去了,因为我的视频是通过Render Mode为Render Texture的方法播放的,

3.把Material拖入RawImage里面的Material。(视频播放、Rendertexture相关可以见步骤1里的创建视频)

Unity3D视频绿幕抠图的实现及优化相关推荐

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

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

  2. html 像素 视频教程,canvas像素点操作之视频绿幕抠图

    本文介绍了canvas像素点操作之视频绿幕抠图,分享给大家,具体如下: 用法: context.putImageData(imgData, x, y, dX, dY, dWidth, dHeight) ...

  3. 通过OpenCV对视频进行绿幕抠图

    通过OpenCV对视频进行绿幕抠图 效果 代码 1.打开视频素材 2.保存视频路径及格式设置 3.读取一帧视频 4.寻找绿幕背景 5.融合 6.代码执行效果 效果 今天跟大家分享的是最近比较受大家喜欢 ...

  4. 视频编辑SDK,AE模版SDK,绿幕抠图SDK,AI人像分割SDK,VLOG模版SDK

    蓝松短视频SDK(视频编辑.AE模版.绿幕抠图.人像分割.人体抠图.VLOG模版): 高集成度:SDK中的大部分功能,都是一行代码设置 高完整度:提供常见视频编辑UI界面,可直接使用 高独立性:蓝松S ...

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

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

  6. 直播绿幕抠图的例子(绿幕抠图直播实例参考)

    阿酷TONY  / 2022-11-21 / 长沙 什么是绿幕抠图: 设定绿幕或绿布,做直播软件抠图,这时绿幕绿布就可以被实时的抠掉,绿色就变成透明了,只剩下绿幕外的人物,此时添加上直播的背景画质,就 ...

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

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

  8. 抖音直播画中画、绿幕抠图直播,如此简单

    抖音直播目前较火,但只单存的播放视频,很容易限流,无法加热... 目前较火的直播方式,无非就是画中画+绿幕直播了.可能会环节以上问题. 什么是画中画,就是两个媒体源叠加在一起 如下图: 如何把摄像头只 ...

  9. 虚拟直播、绿幕直播、绿幕抠图换背景虚拟直播介绍

    什么是虚拟直播: 是基于 绿幕抠图 技术(把所有绿色变成透明),实时换背景图片.背景视频(背景可以是产品特写.PPT宣传文案等),配合DY里的手机录屏功能,实现一个人的虚拟专业直播间(无须其他费用支出 ...

最新文章

  1. Quartus和Modelsim中使用`include包含头文件的对比
  2. 126篇殿堂级深度学习论文分类整理 从入门到应用(下)
  3. GridView如何设置View的初始样式
  4. c++清空输入缓冲区_干货 | C++的输入输出方法
  5. 三. 自动化测试用例设计
  6. 实验五 burpsuite重放攻击实验
  7. Java使用Selenium几个例子
  8. 七种场景下的软件作业量估计
  9. LR报错 No buffer space available Try changing the registry value 端口号不够用了
  10. 关于HTTP缓存的故事
  11. 流媒体协议(二):RTMP协议
  12. H5调用手机摄像头和相册更换头像
  13. word中无法取消图片组合
  14. 第十五篇,STM32的SPI串行通信协议
  15. 苹果手机有护眼模式吗_调节手机明暗度能起到护眼模式一样的效果?
  16. druid源码学习2-DruidDataSource.DestroyTask
  17. codeforces 581B Luxurious Houses(线段树点更新,区间查询)
  18. 西北工业大学遭到境外网络攻击,调查报告二发布
  19. 讲解MySQL最详细的一步一步安装教程
  20. CSDN保存草稿后,在哪里找到草稿

热门文章

  1. android studio 抽屉,Android Studio 的抽屉导航
  2. android侧滑抽屉滑动状态,android SlidingDrawer滑动抽屉
  3. 2022年武汉市助理工程师职称评定流程和评定条件是什么?甘建二
  4. STM32定时器中断实现
  5. 南阳oj入门题-数数
  6. 计算机属性无法查看无反应,Win7旗舰版右键查看计算机属性未反应的处理方法...
  7. windown10免安装版安装mysql5.7.20
  8. 绿盟赛—鲲鹏计算平台软件移植
  9. 【双评价】城镇建设指向的水资源评价
  10. java刷新透视表数据源,Excel数据透视表过滤源更新时更改的值