Unity 绿幕抠图 摄像头抠图 单色抠图

原创 2017年07月04日 16:22:26
最近迷上了看直播,看到有些主播MM的背景很好看

所以就自己弄了一个非常好看的背景


首先,实验环境


背景图


最终效果


实现原理,就是将图片传入Shader,然后将材质放在一个物体上
Shader代码:

Shader "我的Shader/自定义/05过滤纯色"
{
        Properties
        {
                _MainTex("主纹理", 2D) = "white" { }
                _TransparentColourKey("过滤的颜色", Color) = (0,0,0,1)
                _TransparencyToleranceR("透明公差R", Range(0.01, 1.0)) = 0.01
                _TransparencyToleranceG("透明公差G", Range(0.01, 1.0)) = 0.01
                _TransparencyToleranceB("透明公差B", Range(0.01, 1.0)) = 0.01
        }
 
        SubShader
        {
                Pass
                {
                        Tags{ "RenderType" = "Opaque" "Queue" = "Transparent" }
                        //Tags{ "RenderType" = "Transparent" "Queue" = "Transparent" }
                        Blend SrcAlpha OneMinusSrcAlpha
                        //Blend One One
                        LOD 200
                        CGPROGRAM
 
                        #pragma vertex vert
                        #pragma fragment frag
                        #include "UnityCG.cginc"
 
                        struct vertInput
                        {
                                float4 pos : POSITION;
                                float2 uv : TEXCOORD0;
                        };
 
                        struct vertOnput
                        {
                                float4 pos : SV_POSITION;
                                float2 uv : TEXCOORD0;
                        };
 
                        vertOnput vert(vertInput input)
                        {
                                vertOnput output;
                                output.pos = mul(UNITY_MATRIX_MVP, input.pos);
                                output.uv = input.uv;
                                return output;
                        }
 
                        sampler2D _MainTex;
                        sampler2D _Background;
                        float3 _TransparentColourKey;
                        float _TransparencyToleranceR;
                        float _TransparencyToleranceG;
                        float _TransparencyToleranceB;
 
                /*        float Overlay(float base, float top)
                        {
                                if (base < 0.5)
                                {
                                        return 2 * base*top;
                                }
                                else 
                                {
                                        return 1 - 2 * (1 - base) * (1 - top);
                                }
                        }*/
 
                        float4 frag(vertInput input) : COLOR//SV_Target
                        {
                                float4 color = tex2D(_MainTex, input.uv);
                                float deltaR = abs(color.r - _TransparentColourKey.r);
                                float deltaG = abs(color.g - _TransparentColourKey.g);
                                float deltaB = abs(color.b - _TransparentColourKey.b);
                                if (deltaR < _TransparencyToleranceR && deltaG < _TransparencyToleranceG && deltaB < _TransparencyToleranceB)
                                {
                                        return float4(0.0f, 0.0f, 0.0f, 0.0f);
                                }
                                else
                                {
                                        //float4 col = fixed4(0, 0, 0, 0);
                                        //col.r = Overlay(color.r, color2.r);
                                        //col.g = Overlay(color.g, color2.g);
                                        //col.b = Overlay(color.b, color2.b);
                                        //col.a = color.a;                
                                        return color;
                                }                
                        }
                        ENDCG
                }
        }
        Fallback "Diffuse"
}


最后新建一个脚本,定义变量

public Material m_Material;
[Range(0, 255)]
public float transparentColourR = 1f;
[Range(0, 255)]
public float transparentColourG = 1f;
[Range(0, 255)]
public float transparentColourB = 1f;
[Range(0,100)]
public float transparencyToleranceR = 1f;
[Range(0, 100)]
public float transparencyToleranceG = 1f;
[Range(0, 100)]
public float transparencyToleranceB = 1f;
 
private int devId = 1;
public string deviceName;
private WebCamTexture photoTex;
static int FrameWidth = 1920;
static int FrameHeight = 1080;


在Update里写

transparentColour.r = transparentColourR / 255;
transparentColour.g = transparentColourG / 255;
transparentColour.b = transparentColourB / 255;
transparentColour.a = 1;
m_Material.SetColor("_TransparentColourKey", transparentColour);
m_Material.SetFloat("_TransparencyToleranceR", transparencyToleranceR / 100);
m_Material.SetFloat("_TransparencyToleranceG", transparencyToleranceG / 100);
m_Material.SetFloat("_TransparencyToleranceB", transparencyToleranceB / 100);
m_Material.SetTexture("_MainTex", photoTex);

打开摄像头

yield return Application.RequestUserAuthorization(UserAuthorization.WebCam);
 
if (Application.HasUserAuthorization(UserAuthorization.WebCam))
{
    WebCamDevice[] devices = WebCamTexture.devices; ;
 
    //如果有后置摄像头,调用后置摄像头    
    for (int i = 0; i < devices.Length; i++)
    {
        if (!devices[i].isFrontFacing)
        {
            deviceName = devices[i].name;
            break;
        }
    }
 
    photoTex = new WebCamTexture(deviceName, FrameWidth, FrameHeight, 24);
    photoTex.Play();
}

Demo:
链接:http://pan.baidu.com/s/1i4QuTyl 密码:lee6
至此完结!!!


Unity 绿幕抠图 摄像头抠图 单色抠图

最近迷上了看直播,看到有些主播MM的背景很好看 所以就自己弄了一个非常好看的背景 首先,实验环境   背景图   最终效果   实现原理,就是将图片传入Shader,然后将材质放在一个...
  • weixin_36080451
  • weixin_36080451
  • 2017年07月03日 09:17
  • 243

Shader学习历程(五)——Sprite Shader之简单抠图

前言还在苦于自己写的shader不能被sprite使用吗? 对,这个问题也困扰过我,所以我将它解决了。 然后顺便实现了简单抠图。。。。真的是简单抠图。。。正文按照习惯,首先放图,放代码。 这...
  • AbstractSky
  • AbstractSky
  • 2015年12月24日 15:44
  • 2987

opencv自由抠图

此篇跟上篇画矩形框类似。画框改为画点。用floodfill和带有掩码的copyTo得到抠图。右击确定floodFill中的种子点。 参考自http://blog.csdn.net/cv_yuippe...
  • maryhuan
  • maryhuan
  • 2013年10月29日 21:36
  • 3666

opencv 绿背景抠图

ps:写之前废话一下,到新公司
  • chenxun2009
  • chenxun2009
  • 2014年08月06日 16:56
  • 7077

自然图像抠图/视频抠像技术发展情况梳理

自然图像抠图/视频抠像技术发展情况梳理(image matting, alpha matting, video matting)--计算机视觉专题1              分类:      ...
  • wangyaninglm
  • wangyaninglm
  • 2014年08月19日 16:09
  • 2453

绿幕换背景、绿幕视频实时换背景

绿幕抠像技术目前技术已经很成熟,大多应用与VR环境、影视、照相合成领域,目前大多都需要调节很多的参数,基于这个考虑,我一直在研究自动绿幕抠图的方法,技术上的瓶颈很是很多,希望大家一起交流。...
  • zhulong1984
  • zhulong1984
  • 2017年08月02日 17:18
  • 935

CorelDRAW中如何实现抠图

我们都知道Photoshop能抠图,而且方法很多,因为它是位图图像处理软件,说到CorelDRAW,更对人对它的印象是做矢量图形的...
  • coreldraw2016
  • coreldraw2016
  • 2016年05月13日 13:58
  • 2999

python 网站自动抠图

python 网站自动抠图 翻东西, 突然找到了以前用python写的自动下载网站图片的一个脚本 很好用, 如果修改的话, 只要将路径改成自己的即可! picdown.py #...
  • u012687934
  • u012687934
  • 2014年03月23日 12:55
  • 2357

Unity3D消除视频绿幕

PS:本文首发于简书,系本人文章,再在CSDN发布。 以前主管就告诉我们,做一个专门的技术博客,对以后成长有很大帮助,但是一直没有去做,工作一年,知识杂且乱,感觉收获不大,决定从写技术博客开始。...
  • an050602
  • an050602
  • 2017年02月22日 09:55
  • 617

基于OpenCV的抠图程序

最近为了建立图片数据库,要进行抠图,在使用了Windows自带的截图软件之后,发现非常的麻烦,每次都要直接打开图片,抠图,然后还要输入保存的文件名字,这种纯手工的方式,要多长时间才能搞定十万张图片。 ...
  • shengno1
  • shengno1
  • 2014年08月28日 22:45
  • 2715
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Unity 绿幕抠图 摄像头抠图 单色抠图
举报原因:
原因补充:

(最多只允许输入30个字)