untiy 实时人像抠图

最近公司要求做一个抠图程序,作者想到接一个百度AI来实现抠图,做出来之后效果不是太好,然后领导说想要实时抠图,让用户现场体验更好些,没办法,只能推倒重来,然后在网上找个shader,然后自己改改,就实现了。

 

 

首先是shader代码

Shader "UniversalChromaKey" {
        Properties {
                _MainTex ("Base (RGB)", 2D) = "white" {}
                _Sens ("Sensibilidad", Range (0,.9)) = .3
				_Cutoff ("Recorte", Range (0,.9)) = .2
				_Color ("Chroma", Color) = (0, 1.0, 0)
        }
        SubShader {
                Tags { "Queue"="Transparent" "RenderType"="Transparent" }
                LOD 200
               
               
                CGPROGRAM
                #pragma surface surf Lambert alpha
 
                sampler2D _MainTex;
                float _Cutoff;
                float _Sens;
                half3 _Color;

 
                struct Input {
                        float2 uv_MainTex;
                };
 
                void surf (Input IN, inout SurfaceOutput o) {
                        half4 c = tex2D (_MainTex, IN.uv_MainTex);
                        o.Emission = c.rgb;
                        
                        
                        float aR = abs(c.r - _Color.r) < _Sens ? abs(c.r - _Color.r) : 1;
                        float aG = abs(c.g - _Color.g) < _Sens ? abs(c.g - _Color.g) : 1;
                        float aB = abs(c.b - _Color.b) < _Sens ? abs(c.b - _Color.b) : 1;                        
                        
                        float a = (aR + aG + aB) / 3; 
                        
                        if(a < _Cutoff){
                        	o.Alpha = 0;
                        }else{
                        	o.Alpha = 1;
                        }
                          
                }
                ENDCG
        }
        FallBack "Diffuse"
}

控制shader脚本

using UnityEngine;
using System.Collections;
using UnityEngine.UI;

public class ShaderControls : MonoBehaviour {

	
	float sensS, cutoffS;
	Color colS;

	// Use this for initialization
	void Start () {
		sensS = GetComponent<RawImage>().material.GetFloat("_Sens");
		cutoffS = GetComponent<RawImage>().material.GetFloat("_Cutoff");
		colS = GetComponent<RawImage>().material.GetColor("_Color");

		sens = sensS;
		cutoff = cutoffS; 

	}
	
	// Update is called once per frame
	void Update () {
	
	}

	public float sens, cutoff;
	public string r = "99", g = "205", b ="77";
    //void OnGUI()
    //{
    //    sens = GUI.HorizontalSlider(new Rect(25, 25, 100, 30), sens, 0.0f, 1.0f);
    //    cutoff = GUI.HorizontalSlider(new Rect(25, 70, 100, 30), cutoff, 0.0f, 1.0f);

    //    r = GUI.TextField(new Rect(25, 120, 40, 20), r);
    //    g = GUI.TextField(new Rect(70, 120, 40, 20), g);
    //    b = GUI.TextField(new Rect(120, 120, 40, 20), b);

    //    if (GUI.Button(new Rect(25, 160, 100, 30), "Reset"))
    //    {
    //        sens = sensS;
    //        cutoff = cutoffS;

    //        r = (colS.r * 255f).ToString();
    //        g = (colS.g * 255f).ToString();
    //        b = (colS.b * 255f).ToString();
    //    }


    //    GetComponent<RawImage>().material.SetFloat("_Sens", sens);
    //    GetComponent<RawImage>().material.SetFloat("_Cutoff", cutoff);
    //    try
    //    {
    //        Color col = new Color(int.Parse(r) / 255f, int.Parse(g) / 255f, int.Parse(b) / 255f);
    //        //print (col);
    //        GetComponent<RawImage>().material.color = col;

    //    }
    //    catch (UnityException e)
    //    {
    //    }
    //}
}

控制外部摄像机脚本

using UnityEngine;
using System.Collections;
using UnityEngine.Video;
using UnityEngine.UI;
using System.IO;

public class CameraControl : MonoBehaviour {
    /// <summary>
    /// 外部摄像头
    /// </summary>
    private WebCamTexture webTex;
    /// <summary>
    /// UI父物体
    /// </summary>
    private Canvas canvas;
    /// <summary>
    /// 摄像头映射画面
    /// </summary>
    private RawImage Camera_image;


    private void Start()
    {
        canvas = GameObject.Find("Canvas").GetComponent<Canvas>();
        Camera_image = canvas.transform.Find("Camera_screen").GetComponent<RawImage>();

        StartCoroutine(CallCamera());


    }
    /// <summary>
    /// 打开摄像头
    /// </summary>
    /// <returns></returns>
    IEnumerator CallCamera()
    {
        //等待用户允许访问
        yield return Application.RequestUserAuthorization(UserAuthorization.WebCam);
        //如果用户允许访问,开始获取图像        
        if (Application.HasUserAuthorization(UserAuthorization.WebCam))
        {
            WebCamDevice[] devices = WebCamTexture.devices;
            string devicename = devices[0].name;
            webTex = new WebCamTexture(devicename, Screen.width, Screen.height);
            Camera_image.texture = webTex;
            webTex.Play();
        }
    }



}

控制shader脚本和打开摄像头脚本挂载到一个RawImage上面,shader脚本放在材质球上,然后把材质球也放在RawImage上面,

最后效果

 

由于绿幕不平和有阴影导致的绿幕没有扣掉(测试用的绿幕),如果现场绿幕是平的,效果会更好,作者把项目工程源文件分享出来了,想要的可以下载,如果有不明白的地方可以加QQ群:636926481(互相交流)。

Demo:https://download.csdn.net/download/qq_39954479/12330999

 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值