rtsp视频在使用unity三维融合播放后的修正
1 rtsp 接入
我们使用unity UE 等三维渲染引擎中使用c++编写插件来接入rtsp 视频。同时做融合的时候,和背景的三维颜色要一致,这就要使用视频融合修正技术。包括亮度,对比度,饱和度的修正。在单纯颜色上的修正可以简单使用rgb->hsv去修改,这里不做累赘说明了。
2 播放技术
使用unity 的纹理渲染来播放多路 视频,视频接入最大可达到30路,同时在untiy , UE5 中渲染。播放后有很多视频的颜色不一致,如何调整颜色成了一个问题
3 untiy 渲染过程
建立一个材质,如命名为m2

将m2 赋值给我们的面片,如pp

接下来创建一个shader,控制渲染的亮度,对比度,饱和度,分别是 Brightness, Saturation, Contrast, unity shader的基础不再啰嗦,各位可以稍稍看一下,不难。
Shader "self/BrightnessSaturationAndContrast"
{Properties{_MainTex ("Base(RGB", 2D) = "white" {}//从脚本传递更好,这里可以直接省略这些值的展示_Brightness ("Brightness", float) = 1_Saturation ("Saturation", float) = 1_Contrast ("Contrast", float) = 1}SubShader{Pass{//关闭深度写入//ZTest Always Cull Off Zwrite OffCGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"//propertiessampler2D _MainTex;half _Brightness;half _Saturation;half _Contrast;struct v2f {float4 pos : SV_POSITION;half2 uv : TEXCOORD0; };//使用了内置的appdata_img结构体作为顶点着色器的输入v2f vert(appdata_img v) {v2f o;o.pos = UnityObjectToClipPos(v.vertex);o.uv = v.texcoord;return o;}fixed4 frag(v2f i) : SV_Target {//获得屏幕图像的采样fixed4 renderTex = tex2D(_MainTex, i.uv);//亮度fixed3 finalColor = renderTex.rgb * _Brightness;//饱和度fixed luminance = 0.2125 * renderTex.r + 0.7154 * renderTex.g + 0.0721 * renderTex.b; //计算该像素的亮度值fixed3 luminanceColor = fixed3(luminance, luminance, luminance); //创建饱和度为0的颜色finalColor = lerp(luminanceColor, finalColor, _Saturation);//contrastfixed3 avgColor = fixed3(0.5, 0.5, 0.5);finalColor = lerp(avgColor, finalColor, _Contrast);return fixed4(finalColor, renderTex.a);}ENDCG}}FallBack Off
}
写好shader以后, 写一个脚本,调入我们的c#脚本,脚本一为控制我们的c++插件,二是可以修改,以下的插件脚本负责调入c++ 的插件,插件会在线程里面启动,获取图像,赋值给面片。插件本身可以接入实时视频,播放视频,倒放视频,支持国标gb28181和onvif协议,可以支持矫正视频,支持多组矫正参数,同时增加三个变量,改变亮度,对比度,饱和度,便于在里面实时修改观察。
//author: 钱波
using System;
using System.Text;
using System.Threading;
using System.Collections;
using UnityEngine;
using System.Runtime.InteropServices;
using UnityEngine.UI;
using System.Linq;
using System.Collections.Generic;
using Unity.VisualScripting;
using System.IO;[StructLayout(LayoutKind.Sequential)]
public struct FRAME
{public int width;public int height;public int len;public IntPtr Frame;public IntPtr data;//public byte[] data;//[MarshalAs(UnmanagedType.LPArray)]
}
[StructLayout(LayoutKind.Sequential)]
public struct PARAM
{public double p1;public double p2;public double p3;public double p4;public double p5;public double p6;public double p7;public double p8;public double p9;public double c1;public double c2;public double c3;public double c4;public double c5;
}public class rtspin : MonoBehaviour
{[DllImport("rtspPlugin")]public static extern bool rtsp_test([MarshalAs(UnmanagedType.LPStr)] string url, int isnv12);[DllImport("rtspPlugin")]public static extern bool rtsp_test_data([MarshalAs(UnmanagedType.LPStr)] string url,[MarshalAs(UnmanagedType.LPArray)] byte[] data, ref FRAME frame);[DllImport("rtspPlugin")]public static extern bool rtsp_test_data_nv12([MarshalAs(UnmanagedType.LPStr)] string url,[MarshalAs(UnmanagedType.LPArray)] byte[] data0, [MarshalAs(UnmanagedType.LPArray)] byte[] data1);[DllImport("rtspPlugin")]public static extern void rtsp_test_stop([MarshalAs(UnmanagedType.LPStr)] string url);[DllImport("rtspPlugin")]public static extern void rtsp_test_setparam([MarshalAs(UnmanagedType.LPStr)] string url, ref PARAM param);static string[] stringArray = {"rtsp://127.0.0.1/front.mkv" };static string[] stringPlanes = { "pp"};//Texture2D[] texture2Ds;int w1 = 1920;int h1 = 1080;int number = 1;[Range(0.0f, 3.0f)]public float brightness = 1.0f;[Range(0.0f, 3.0f)]public float saturation = 1.0f;[Range(0.0f, 3.0f)]public float contrast = 1.0f;public Material briSatConMaterial;class cmd{public int v_w1 = 1920;public int v_h1 = 1080;public byte[] v_data;public Texture2D v_texture2Ds;public cmd(){v_data = new byte[v_w1 * v_h1 * 3];v_texture2Ds = new Texture2D(v_w1, v_h1, TextureFormat.RGB24, false);//RGB24}}PARAM v_param;//byte[][] v_datas;Dictionary<int, cmd> hashMap_datas = new Dictionary<int, cmd>();//byte[][] hashMap_datas;void rtspThreading(string url){Debug.Log(url);rtsp_test(url, 1);}void Start(){//string path = Application.dataPath + "/rtsp.txt";//path = path.Replace("/", "\\");//if (File.Exists(path))//{// Debug.Log("FileExists");// stringArray = File.ReadAllLines(path);//}//else//{// Debug.Log("FileNotExists");// File.CreateText(path);//}stringArray[0] = "rtsp://127.0.0.1/front.mkv";for (int i = 0; i < number; i++){cmd c1 = new cmd();hashMap_datas.Add(i, c1);}v_param = new PARAM();//v_param.p1 = 6.5746697810243404e+002;//v_param.p2 = 0.0;//v_param.p3 = 3.1950000000000000e+002;//v_param.p4 = 0.0;//v_param.p5 = 6.5746697810243404e+002;//v_param.p6 = 2.3950000000000000e+002;//v_param.p7 = 0.0;//v_param.p8 = 0.0;//v_param.p9 = 1.0;//v_param.c1 = -0.5180232701824102559;//v_param.c2 = 0.5071524380583312119;//v_param.c3 = 0.0;//v_param.c4 = 0.0;//v_param.c5 = -0.5784359684793970446;//1281.48 0 975.5 0 1997.48 0 0 0 1 -0.6 0.4 0.1 0 -0.198v_param.p1 = 1281.48;v_param.p2 = 0.0;v_param.p3 = 975.5;v_param.p4 = 0.0;v_param.p5 = 1997.48;v_param.p6 = 0.0;v_param.p7 = 0.0;v_param.p8 = 0.0;v_param.p9 = 1.0;v_param.c1 = -0.6;v_param.c2 = 0.4;v_param.c3 = 0.1;v_param.c4 = 0.0;v_param.c5 = -0.198;GameObject go = GameObject.Find("pp");briSatConMaterial = go.GetComponent<MeshRenderer>().material;}private void OnGUI(){if (GUI.Button(new Rect(120, 10, 80, 30), "开始线程")){Debug.Log("开始rtsp......");for (int i = 0; i < number; i++){int currentIndex = i;Thread rtspthread1 = new Thread(() => rtspThreading(stringArray[currentIndex]));rtspthread1.Start();Thread.Sleep(1);}}//绘制按钮,以及按下断开连接按钮,发送断开连接请求if (GUI.Button(new Rect(210, 10, 80, 30), "结束线程")){Debug.Log("结束rtsp......");for (int i = 0; i < number; i++){int currentIndex = i;rtsp_test_stop(stringArray[currentIndex]);}}}//float delta_x, delta_y, delta_z; //计算移动量//float distance = 5;//float ZoomSpeed = 5f; //拉近拉远速度//public bool isFar = true;void Update(){FRAME frame = new FRAME();if (briSatConMaterial != null){briSatConMaterial.SetFloat("_Brightness", brightness);briSatConMaterial.SetFloat("_Saturation", saturation);briSatConMaterial.SetFloat("_Contrast", contrast);}for (int i = 0; i < number; i++){if (rtsp_test_data(stringArray[i], hashMap_datas[i].v_data, ref frame)){rtsp_test_setparam(stringArray[i], ref v_param);//Texture2D original = new Texture2D(w1, h1, TextureFormat.RGB24, false);//original.LoadRawTextureData(hashMap_datas[i].v_data);//FlipTexture(original, hashMap_datas[i].v_texture2Ds);hashMap_datas[i].v_texture2Ds.LoadRawTextureData(hashMap_datas[i].v_data);hashMap_datas[i].v_texture2Ds.Apply();GameObject go = GameObject.Find(stringPlanes[i]);go.GetComponent<MeshRenderer>().material.mainTexture = hashMap_datas[i].v_texture2Ds;}}}void OnDestroy(){Debug.Log("Destory, 结束rtsp......");for (int i = 0; i < number; i++){int currentIndex = i;rtsp_test_stop(stringArray[currentIndex]);}}
}
结果
点击开始播放,rtsp线程开始播放,inspector里面可以调整三个值,可以直观地看到视频播放的亮度和对比度饱和度的改变。

修改一下亮度

同时修改三个参数的变化

相关文章:
rtsp视频在使用unity三维融合播放后的修正
1 rtsp 接入 我们使用unity UE 等三维渲染引擎中使用c编写插件来接入rtsp 视频。同时做融合的时候,和背景的三维颜色要一致,这就要使用视频融合修正技术。包括亮度,对比度,饱和度的修正。在单纯颜色上的修正可以简单使用rgb->…...
【已解决】解决Springboot项目访问本地图片等静态资源无法访问的问题
今天在开发一个招聘系统的时候,有投递简历功能,有投递就会有随之而来的查看简历对吧,我投递过的简历,另存为一个文件夹,就是说本地磁盘(或者服务器)有一个专门存放投递过的简历的文件夹,用于存放PDF&#x…...
运维笔记之centos部署Go-FastDfs
安装Go-FastDfs 当前最新版本为1.4.5,但发布的最新版本为1.4.4 # 下载文件 wget --no-check-certificate https://github.com/sjqzhang/go-fastdfs/releases/download/v1.4.4/fileserver -O fileserver # 赋权限 chmod x fileserver # 运行 ./fileserver server服…...
C#基础——线程(线程池、线程锁、线程抢占、多线程)
线程 进程(Process)是由操作系统分配资源并执行的一个独立的程序实,属于Windows的概念,进程结束就表示程序关闭了。 线程(Thread)是程序中执行的最小单位。一个线程代表了一个独立的执行流,可…...
C# WPF上位机开发(QT vs WPF)
【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 最近经常收到朋友们的私信,他们对C# WPF开发很感兴趣,但是呢,正当准备学习的时候,又有人告诉他们应…...
2-高可用-负载均衡、反向代理
负载均衡、反向代理 upstream server即上游服务器,指Nginx负载均衡到的处理业务的服务器,也可以称之为real server,即真实处理业务的服务器。 对于负载均衡我们要关心的几个方面如下: 上游服务器配置:使用upstream server配置上…...
STM32 使用ARM仿真器设置
STM32单片机程序下载到单片机芯片中有两种方式,①编译生成HEX,使用程序烧录软件刷到单片机芯片里。②使用ARM仿真器下载程序。使用ARM仿真器的优势是,在工程编译没问题直接在Keil软件里就可以将程序下载到单片机里,并且程序可以在…...
【Java】spring
一、spring spring是一个很大的生态圈,里面有很多技术。 其中最基础的是spring framework,主要的技术 是springboot以及springcloud。 1、spring framework spring framework是spring生态圈中最基础的项目,是其他项目的基础。 1.1、核心…...
C语言中关于操作符的理解
本篇文章只会列出大家在生活中经常使用的操作符 算术操作符 在算数操作符中常用的有,,-,*,/,% ,我们重点讲一讲 / (除) 和 % (模) " / "运算 #include <stdio.h>int main() {int a5/2;fl…...
Flutter本地化(国际化)之App名称
文章目录 Android国际化IOS国际化 Flutter开发的App,如果名称想要跟随着系统的语言自动改变,则必须同时配置Android和IOS原生。 Android国际化 打开android\app\src\main\res\values 创建strings.xml 在values上右键,选择New>Values Res…...
Redis哨兵源码分析
在Redis server启动过程中,实现了实例化和初始化 1、哨兵实例化过程,采用redis sentinel指令实例化还是redis server下的参数实例化--sentinel。 // 检查服务器是否以 Sentinel 模式启动 server.sentinel_mode checkForSentinelMode(argc,argv);/* Re…...
安装Neo4j
jdk1.8对应的neo4j的版本是3.5 自行下载3.5版本的zip文件 地址 解压添加环境变量 变量名:NEO4J_HOME 变量值:D:\neo4j-community-3.5.0 (你自己的地址) PATH添加: %NEO4J_HOME%\bin (如果是挨着的注意前后英…...
华为鸿蒙开发适合哪些人学习?
随着鸿蒙系统的崛起,越来越多的人开始关注鸿蒙开发,并希望成为鸿蒙开发者。然而,鸿蒙开发并不适合所有人,那么哪些人最适合学习鸿蒙开发呢?本文将为您总结鸿蒙开发适合的人群。 一、具备编程基础的人 学习鸿蒙开发需要…...
深信服技术认证“SCSA-S”划重点:命令执行漏洞
为帮助大家更加系统化地学习网络安全知识,以及更高效地通过深信服安全服务认证工程师考核,深信服特别推出“SCSA-S认证备考秘笈”共十期内容,“考试重点”内容框架,帮助大家快速get重点知识~ 划重点来啦 *点击图片放大展示 深信服…...
Flink系列之:Savepoints
Flink系列之:Savepoints 一、Savepoints二、分配算子ID三、Savepoint 状态四、算子五、触发Savepoint六、Savepoint 格式七、触发 Savepoint八、使用 YARN 触发 Savepoint九、使用 Savepoint 停止作业十、从 Savepoint 恢复十一、跳过无法映射的状态恢复十二、Resto…...
使用宝塔面板部署前端项目到服务器
目录 文章目录 前言 一、第一步:创建文件夹 二、第二步:部署前端项目 三、第三步:打开防火墙 文章目录 前言第一步:创建文件夹第二步:部署前端项目第三步:打开防火墙总结 前言 在此之前,我…...
Enge问题解决教程
目录 解决问题的一般步骤: 针对"Enge问题"的具体建议: 以下是一些普遍适用的解决问题的方法: 以下是一些更深入的Enge浏览器问题和解决办法: 浏览器性能问题: 浏览器插件与网站冲突: 浏览…...
使用yarn安装electron时手动选择版本
访问1Password或者其他可以提供随机字符的网站,获取随机密码运行安装命令 操作要点,必须触发Couldnt find any versions for "electron" that matches "*"才算成功 将复制的随机密码粘贴到后面 例如:yarn add --dev elec…...
AIGC:阿里开源大模型通义千问部署与实战
1 引言 通义千问-7B(Qwen-7B)是阿里云研发的通义千问大模型系列的70亿参数规模的模型。Qwen-7B是基于Transformer的大语言模型, 在超大规模的预训练数据上进行训练得到。预训练数据类型多样,覆盖广泛,包括大量网络文本、专业书籍…...
Java小案例-Java实现人事管理系统
前言 《人事管理系统》该项目采用技术jsp、Struts2、Mybatis、dwr、tomcat服务器、mysql数据库 开发工具eclipse/idea。 【项目使用技术】 Struts2Mybatisdwrjqueryjscss等技术 前端使用技术:JSP, dwr、jquery、js、css等 后端使用技术:Struts2Myba…...
可靠性+灵活性:电力载波技术在楼宇自控中的核心价值
可靠性灵活性:电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中,电力载波技术(PLC)凭借其独特的优势,正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据,无需额外布…...
postgresql|数据库|只读用户的创建和删除(备忘)
CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...
【git】把本地更改提交远程新分支feature_g
创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...
Java 二维码
Java 二维码 **技术:**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...
SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题
分区配置 (ptab.json) img 属性介绍: img 属性指定分区存放的 image 名称,指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件,则以 proj_name:binary_name 格式指定文件名, proj_name 为工程 名&…...
Linux nano命令的基本使用
参考资料 GNU nanoを使いこなすnano基础 目录 一. 简介二. 文件打开2.1 普通方式打开文件2.2 只读方式打开文件 三. 文件查看3.1 打开文件时,显示行号3.2 翻页查看 四. 文件编辑4.1 Ctrl K 复制 和 Ctrl U 粘贴4.2 Alt/Esc U 撤回 五. 文件保存与退出5.1 Ctrl …...
TSN交换机正在重构工业网络,PROFINET和EtherCAT会被取代吗?
在工业自动化持续演进的今天,通信网络的角色正变得愈发关键。 2025年6月6日,为期三天的华南国际工业博览会在深圳国际会展中心(宝安)圆满落幕。作为国内工业通信领域的技术型企业,光路科技(Fiberroad&…...
Python 训练营打卡 Day 47
注意力热力图可视化 在day 46代码的基础上,对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...
es6+和css3新增的特性有哪些
一:ECMAScript 新特性(ES6) ES6 (2015) - 革命性更新 1,记住的方法,从一个方法里面用到了哪些技术 1,let /const块级作用域声明2,**默认参数**:函数参数可以设置默认值。3&#x…...
STM32标准库-ADC数模转换器
文章目录 一、ADC1.1简介1. 2逐次逼近型ADC1.3ADC框图1.4ADC基本结构1.4.1 信号 “上车点”:输入模块(GPIO、温度、V_REFINT)1.4.2 信号 “调度站”:多路开关1.4.3 信号 “加工厂”:ADC 转换器(规则组 注入…...
