unity 绿幕抠图

1.硬件:Insta360 Link 2C摄像机

2.引用shader

Shader "Demo/ChromaKey"
{
    Properties
    {
        _MainTex("Texture", 2D) = "white" {}
        _KeyColor("KeyColor", Color) = (0,1,0,0)
        _TintColor("TintColor", Color) = (1,1,1,1)
        _ColorCutoff("Cutoff", Range(0, 1)) = 0.2
        _ColorFeathering("ColorFeathering", Range(0, 1)) = 0.33
        _MaskFeathering("MaskFeathering", Range(0, 1)) = 1
        _Sharpening("Sharpening", Range(0, 1)) = 0.5

        _Despill("DespillStrength", Range(0, 1)) = 1
        _DespillLuminanceAdd("DespillLuminanceAdd", Range(0, 1)) = 0.2
    }
        SubShader
        {
            Tags
            {
                // "RenderPipeline"="HDRenderPipeline"
                // "RenderType"="HDUnlitShader"
                "Queue" = "Transparent+1"
            }

            Blend SrcAlpha OneMinusSrcAlpha
            ZWrite Off
            cull off

            Pass
            {
                CGPROGRAM

                #pragma vertex vert
                #pragma fragment frag

                #include "UnityCG.cginc"

                struct appdata
                {
                    float4 vertex : POSITION;
                    float2 uv : TEXCOORD0;
                };

                struct v2f
                {
                    float2 uv : TEXCOORD0;
                    float4 vertex : SV_POSITION;
                };

                sampler2D _MainTex;
                float4 _MainTex_TexelSize;
                float4 _MainTex_ST;
                float4 _KeyColor;
                float4 _TintColor;
                float _ColorCutoff;
                float _ColorFeathering;
                float _MaskFeathering;
                float _Sharpening;
                float _Despill;
                float _DespillLuminanceAdd;

                // Utility functions -----------

                float rgb2y(float3 c)
                {
                    return (0.299 * c.r + 0.587 * c.g + 0.114 * c.b);
                }

                float rgb2cb(float3 c)
                {
                    return (0.5 + -0.168736 * c.r - 0.331264 * c.g + 0.5 * c.b);
                }

                float rgb2cr(float3 c)
                {
                    return (0.5 + 0.5 * c.r - 0.418688 * c.g - 0.081312 * c.b);
                }

                float colorclose(float Cb_p, float Cr_p, float Cb_key, float Cr_key, float tola, float tolb)
                {
                    float temp = (Cb_key - Cb_p) * (Cb_key - Cb_p) + (Cr_key - Cr_p) * (Cr_key - Cr_p);
                    float tola2 = tola * tola;
                    float tolb2 = tolb * tolb;
                    if (temp < tola2) return (0);
                    if (temp < tolb2) return (temp - tola2) / (tolb2 - tola2);
                    return (1);
                }

                float maskedTex2D(sampler2D tex, float2 uv)
                {
                    float4 color = tex2D(tex, uv);

                    // Chroma key to CYK conversion
                    float key_cb = rgb2cb(_KeyColor.rgb);
                    float key_cr = rgb2cr(_KeyColor.rgb);
                    float pix_cb = rgb2cb(color.rgb);
                    float pix_cr = rgb2cr(color.rgb);

                    return colorclose(pix_cb, pix_cr, key_cb, key_cr, _ColorCutoff, _ColorFeathering);
                }

                //-------------------------

                v2f vert(appdata v)
                {
                    v2f o;
                    o.vertex = UnityObjectToClipPos(v.vertex);
                    o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                    return o;
                }

                float4 frag(v2f i) : SV_Target
                {
                    // Get pixel width
                    float2 pixelWidth = float2(1.0 / _MainTex_TexelSize.z, 0);
                    float2 pixelHeight = float2(0, 1.0 / _MainTex_TexelSize.w);

                    // Unmodified MainTex
                    float4 color = tex2D(_MainTex, i.uv);

                    // Unfeathered mask
                    float mask = maskedTex2D(_MainTex, i.uv);

                    // Feathering & smoothing
                    float c = mask;
                    float r = maskedTex2D(_MainTex, i.uv + pixelWidth);
                    float l = maskedTex2D(_MainTex, i.uv - pixelWidth);
                    float d = maskedTex2D(_MainTex, i.uv + pixelHeight);
                    float u = maskedTex2D(_MainTex, i.uv - pixelHeight);
                    float rd = maskedTex2D(_MainTex, i.uv + pixelWidth + pixelHeight) * .707;
                    float dl = maskedTex2D(_MainTex, i.uv - pixelWidth + pixelHeight) * .707;
                    float lu = maskedTex2D(_MainTex, i.uv - pixelHeight - pixelWidth) * .707;
                    float ur = maskedTex2D(_MainTex, i.uv + pixelWidth - pixelHeight) * .707;
                    float blurContribution = (r + l + d + u + rd + dl + lu + ur + c) * 0.12774655;
                    float smoothedMask = smoothstep(_Sharpening, 1, lerp(c, blurContribution, _MaskFeathering));
                    float4 result = color * smoothedMask;

                    // Despill
                    float v = (2 * result.b + result.r) / 4;
                    if (result.g > v) result.g = lerp(result.g, v, _Despill);
                    float4 dif = (color - result);
                    float desaturatedDif = rgb2y(dif.xyz);
                    result += lerp(0, desaturatedDif, _DespillLuminanceAdd);

                    return float4(result.xyz, smoothedMask) * _TintColor;
                }
                ENDCG
            }
        }
}

3.代码

public RawImage rawImage;//相机渲染的UI
    private string WebCamName = @"Insta360 Virtual Camera";
    private WebCamTexture webCamTexture;
    void Start()
    {
        ToOpenCamera();
    }

    /// <summary>
    /// 打开摄像机
    /// </summary>
    public void ToOpenCamera()
    {
        StartCoroutine("OpenCamera");
    }
    public IEnumerator OpenCamera()
    {

        int maxl = Screen.width;
        if (Screen.height > Screen.width)
        {
            maxl = Screen.height;
        }

        // 申请摄像头权限
        yield return Application.RequestUserAuthorization(UserAuthorization.WebCam);

        if (Application.HasUserAuthorization(UserAuthorization.WebCam))
        {
            if (webCamTexture != null)
            {
                webCamTexture.Stop();
            }

            // 监控第一次授权,是否获得到设备(因为很可能第一次授权了,但是获得不到设备,这里这样避免)
            // 多次 都没有获得设备,可能就是真没有摄像头,结束获取 camera
            int i = 0;
            while (WebCamTexture.devices.Length <= 0 && 1 < 300)
            {
                yield return new WaitForEndOfFrame();
                i++;
            }

            if (WebCamTexture.devices.Length <= 0)
            {
                Debug.LogError("没有摄像头设备,请检查");
            }
            else
            {
                webCamTexture = new WebCamTexture(WebCamName, maxl == Screen.height ? Screen.width : Screen.height, maxl,  30)
                {
                    //使纹理平铺
                    wrapMode = TextureWrapMode.Repeat
                };

                // 渲染到 UI 或者 游戏物体上
                if (rawImage != null)
                {
                    rawImage.texture = webCamTexture;
                }

                webCamTexture.Play();
            }

        }
        else
        {
            Debug.LogError("未获得读取摄像头权限");
        }
    }

    private void OnApplicationPause(bool pause)
    {
        // 应用暂停的时候暂停camera,继续的时候继续使用
        if (webCamTexture != null)
        {
            if (pause)
            {
                webCamTexture.Pause();
            }
            else
            {
                webCamTexture.Play();
            }
        }

    }


    private void OnDestroy()
    {
        if (webCamTexture != null)
        {
            webCamTexture.Stop();
        }
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/480007.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux中离线安装gcc

gcc在安装一些其他工具的经常用到&#xff0c;在此记录下如何安装gcc。 1.在线安装 yum -y install gcc 2.离线安装 2.1 获取安装包链接&#xff1a; https://pan.baidu.com/s/1oDvt64ByWs1w-evz5TXU7w?pwd9cfo mpfr-3.1.1-4.el7.x86_64.rpmlibmpc-1.0.1-3.el7.x86_64.rp…

继续完善wsl相关内容:基础指令

文章目录 前言一、我们需要安装wsl,这也是安装docker desktop的前提,因此我们在这篇文章里做了介绍:二、虽然我们在以安装docker desktop为目的时,不需要安装wsl的分发(distribution),但是装一个分发也是有诸多好处的:三、在使用wsl时,不建议把东西直接放到系统里,因…

GITEX GLOBAL聚焦AI创新,Soul App创始人张璐团队带来多模态社交新体验

2024年10月,全球瞩目的科技盛会GITEX GLOBAL在迪拜举行。作为全球三大IT展之一,GITEX GLOBAL一直是展示全球尖端科技的重要平台,今年吸引了全球超6700家科技企业及创新公司参展。 在此次展会中,Soul App创始人张璐团队携自主研发的多模态大模型首次在国际大型展会亮相,展示了其…

C++——map相关的oj题

前言&#xff1a;菜鸟写博客给自己看&#xff0c;我是菜鸟。 1&#xff1a;随机链表的复制 1.1题目要求&#xff1a; 1.2解题思路&#xff1a; 可以分两步来实现代码&#xff1a; ①先将示例1链表中的val值以及next的指向关系深拷贝到另一个新的链表当中 ②再处理新链表中&am…

go web单体项目 学习总结

为什么学习go 博主的主语言是Java&#xff0c;目前的工作也是做Java web开发&#xff0c;有了Java的经验后就想着再学一门语言&#xff0c;其实有两个原因&#xff0c;第一是基于兴趣&#xff0c;也想和Java对比下到底有什么不同&#xff0c;在学习go的时候让我更加了解了Java…

paimon的四种changelog模式(2)-none模式

# 请先了解input模式 环境创建 CREATE CATALOG fs_catalog WITH (typepaimon,warehousefile:/data/soft/paimon/catalog );USE CATALOG fs_catalog;drop table if exists t_changelog_none ;CREATE TABLE t_changelog_none (age BIGINT,money BIGINT,hh STRING,PRIMARY KEY (h…

新型大语言模型的预训练与后训练范式,阿里Qwen

前言&#xff1a;大型语言模型&#xff08;LLMs&#xff09;的发展历程可以说是非常长&#xff0c;从早期的GPT模型一路走到了今天这些复杂的、公开权重的大型语言模型。最初&#xff0c;LLM的训练过程只关注预训练&#xff0c;但后来逐步扩展到了包括预训练和后训练在内的完整…

NAT:连接私有与公共网络的关键技术(4/10)

一、NAT 的工作原理 NAT 技术的核心功能是将私有 IP 地址转换为公有 IP 地址&#xff0c;使得内部网络中的设备能够与外部互联网通信。其工作原理主要包括私有 IP 地址到公有 IP 地址的转换、端口号映射以及会话表维护这几个步骤。 私有 IP 地址到公有 IP 地址的转换&#xff1…

notepad++文件github下载

1、github下载网址&#xff1a;Releases notepad-plus-plus/notepad-plus-plus GitHub 2、找到操作系统支持的软件&#xff1a; 3、CSDN下载链接&#xff1a;https://download.csdn.net/download/u013083576/90046203

【AI绘画】Midjourney进阶:色调详解(下)

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: AI绘画 | Midjourney 文章目录 &#x1f4af;前言&#x1f4af;Midjourney中的色彩控制为什么要控制色彩&#xff1f;为什么要在Midjourney中控制色彩&#xff1f; &#x1f4af;色调纯色调灰色调暗色调 &#x1f4af…

【MySQL篇】持久化和非持久化统计信息的深度剖析(第一篇,总共六篇)

&#x1f4ab;《博主介绍》&#xff1a;✨又是一天没白过&#xff0c;我是奈斯&#xff0c;DBA一名✨ &#x1f4ab;《擅长领域》&#xff1a;✌️擅长Oracle、MySQL、SQLserver、阿里云AnalyticDB for MySQL(分布式数据仓库)、Linux&#xff0c;也在扩展大数据方向的知识面✌️…

PH热榜 | 2024-11-27

DevNow 是一个精简的开源技术博客项目模版&#xff0c;支持 Vercel 一键部署&#xff0c;支持评论、搜索等功能&#xff0c;欢迎大家体验。 在线预览 1. Agentplace 标语&#xff1a;这是一个能创建互动式AI网站和应用的平台。 介绍&#xff1a;Agentplace是一个平台&#xf…

ffmpeg 增亮 docker 使用

使用最新的 docker pull jrottenberg/ffmpeg docker run -it --rm -v /path/to/input:/input -v /path/to/output:/output jrottenberg/ffmpeg <ffmpeg command>比如我想增亮 在 /home 目录下 有一个 video.mp4 docker run --rm -v /home:/home jrottenberg/ffmpeg:7…

单片机学习笔记 11. 外部中断

更多单片机学习笔记&#xff1a;单片机学习笔记 1. 点亮一个LED灯单片机学习笔记 2. LED灯闪烁单片机学习笔记 3. LED灯流水灯单片机学习笔记 4. 蜂鸣器滴~滴~滴~单片机学习笔记 5. 数码管静态显示单片机学习笔记 6. 数码管动态显示单片机学习笔记 7. 独立键盘单片机学习笔记 8…

【PyTorch】(基础一)----pytorch环境搭建

PyTorch环境搭建 该系列笔记主要参考了小土堆的视频教程&#xff0c;传送门&#xff1a;P1. PyTorch环境的配置及安装&#xff08;Configuration and Installation of PyTorch)【PyTorch教程】_哔哩哔哩_bilibili PyTorch 是一个开源的机器学习库&#xff0c;主要用 Python 编…

uniapp开发支付宝小程序自定义tabbar样式异常

解决方案&#xff1a; 这个问题应该是支付宝基础库的问题&#xff0c;除了依赖于官方更新之外&#xff0c;开发者可以利用《自定义 tabBar》曲线救国 也就是创建一个空内容的自定义tabBar&#xff0c;这样即使 tabBar 被渲染出来&#xff0c;但从视觉上也不会有问题 1.官方文…

YOLOv11融合PIDNet中的PagFM模块及相关改进思路

YOLOv11v10v8使用教程&#xff1a; YOLOv11入门到入土使用教程 YOLOv11改进汇总贴&#xff1a;YOLOv11及自研模型更新汇总 《PIDNet: A Real-time Semantic Segmentation Network Inspired by PID Controllers》 一、 模块介绍 论文链接&#xff1a;https://arxiv.org/pdf/2…

NSCTF 做题笔记

[GWCTF 2019]pyre 下载附件&#xff0c;是一个pyc文件。 转换为py文件。 在用vscode打开。 分析源码。源码就是进行了异或和数值转换。 有一点很坑&#xff0c;凑得中的值要转换为ASCII值否则就是一串乱码。 编写脚本&#xff1a; #include<iostream> #include<s…

java——spring容器启动流程

Spring容器的启动流程是一个复杂但有序的过程&#xff0c;它涉及多个步骤来确保应用程序的组件被正确加载、配置和初始化。以下是Spring容器启动的主要步骤&#xff1a; 一、加载配置文件 Spring容器首先会加载配置文件&#xff0c;这些配置文件通常包含了应用程序的组件、依…

九、Ubuntu Linux操作系统

一、Ubuntu简介 Ubuntu Linux是由南非人马克沙特尔沃思(Mark Shutteworth)创办的基于Debian Linux的操作系统&#xff0c;于2004年10月公布Ubuntu是一个以桌面应用为主的Linux发行版操作系统Ubuntu拥有庞大的社区力量&#xff0c;用户可以方便地从社区获得帮助其官方网站:http…