unity gb28181 rtsp 视频孪生图像拉流和矫正插件(一)

目的是为了视频孪生,将视频放到三维里面,如果使用自己写的插件,有更好的灵活性,同时断线重连等等都更好控制了。

1、矫正算法和硬件解码

最好使用opencv制作,可以使用opencv的cuda加速,opencv的编译,必须用cuda cudnn, 都装好,再编译。硬件解码写在插件里面。
在这里插入图片描述
dll插件使用extern “C” 方式。使用_declspec(dllexport) 将函数输出。

2、gb28181 和 rtsp 流 插件

如果多线程?不要在插件里面使用多线程,插件里面保证简单,只是函数,使用unity c# 的多线程启动多个线程去拉流。尽量将插件做到简单的函数封装,不要封装过多的操作。gb28181 使用网络接收推流的方式接收数据,demux使用c++ 解封装,在插件里面解码。

2.1、rtsp 断线重连

还是使用ffmpeg制作,包含断线重连功能,这个必须有,生成unity的可执行程序的时候,一旦rtsp 链接断掉,就必须使用断线重连。否则unity 播放的部分就白了。

2.2、gb28181 接收

这个使用sip协议和流媒体协议,网内尽量使用udp,简单,单个线程接收所有输送的流, 接收到数据以后分流,unity中在update 函数里面去拉自己想要的流。

2.3 多路

界面

在这里插入图片描述
拉好场景,使用两个plane,每一个plane使用一个rtsp或者gb28181 链接,同时序列化结构体,使得c++和c# 能够使用结构体进行参数传递。


using System;
using System.Text;
using System.Threading;
using System.Collections;
using UnityEngine;
using System.Runtime.InteropServices;[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;
}

接口定义

 [DllImport("rtspPlugin")]public static extern bool rtsp_test([MarshalAs(UnmanagedType.LPStr)] string url);[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 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);

程序启动,界面上来两个控制按钮,开始线程和结束线程。
在这里插入图片描述
程序启动的时候启动两个按钮,一个使用矫正,一个不使用矫正,下图所示,左边的流已经经过矫正,图像被拉直,右图没有,以示区别。

在这里插入图片描述
增加一点三维的气氛
在这里插入图片描述
播放
在这里插入图片描述
视频贴图过程
由于使用了硬件解码,解码出来的是nv12格式,如果使用ffmpeg 的swscale,函数缩放和变成rgb24是可以的,效率不高, 也可以直接贴图nv12格式。

Texture2D tY = null,
Texture2D tU = null;
void trans_show(ref struct param)
{private Texture2D tY, tU;int w = param->width;int h = param->height;if(tY == null){tY = new Texture2D(w, h, TextureFormat.Alpha8, false);tU = new Texture2D(w/2, h/2, TextureFormat.RG16, false);}
}//在update里显示,y 和 uv 分别是 avframe 里面的y 数据指针和uv数据指针
tY.LoadRawTextureData(y);
tY.Apply();tU.LoadRawTextureData(uv);tU.Apply();rawImage.texture = tY;rawImage.material.SetTexture("_UTex", tU);

着色器代码显示

sampler2D _YTex;
sampler2D _UTex;
fixed4 frag (v2f i) : SV_Target
{fixed4  col;float  y = tex2D(_YTex, i.uv).a;fixed4  uvs = tex2D(_UTex, i.uv);float  u = uvs.r - 0.5;float  v = uvs.g - 0.5;float r = y + 1.403 * v;float g = y - 0.344  * u - 0.714 * v;float b = y + 1.770  * u;col.rgba = float4(r, g, b, 1.0f);return col;
}

不用shader 转换nv12

不用shader,使用cuda 直接转可以试试一下cuda函数

__global__ void YCrCb2RGBConver(uchar *pYdata, uchar *pUVdata,int stepY, int stepUV, uchar *pImgData, int width, int height, int channels)
{const int tidx = blockIdx.x * blockDim.x + threadIdx.x;const int tidy = blockIdx.y * blockDim.y + threadIdx.y;if (tidx < width && tidy < height){int indexY, indexU, indexV;uchar Y, U, V;indexY = tidy * stepY + tidx;    Y = pYdata[indexY];if (tidx % 2 == 0){indexU = tidy / 2 * stepUV + tidx;indexV = tidy / 2 * stepUV + tidx + 1;U = pUVdata[indexU];V = pUVdata[indexV];}else if (tidx % 2 == 1){indexV = tidy / 2 * stepUV + tidx;indexU = tidy / 2 * stepUV + tidx - 1;U = pUVdata[indexU];V = pUVdata[indexV];}pImgData[(tidy*width + tidx) * channels + 2] = uchar (Y + 1.402 * (V - 128));pImgData[(tidy*width + tidx) * channels + 1] = uchar (Y - 0.34413 * (U - 128) - 0.71414*(V - 128));pImgData[(tidy*width + tidx) * channels + 0] = uchar (Y + 1.772*(U - 128));}
}

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

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

相关文章

面试题:RocketMQ 如何保证消息不丢失,如何保证消息不被重复消费?

文章目录 1、消息整体处理过程Producer发送消息阶段手段一&#xff1a;提供SYNC的发送消息方式&#xff0c;等待broker处理结果。手段二&#xff1a;发送消息如果失败或者超时&#xff0c;则重新发送。手段三&#xff1a;broker提供多master模式&#xff0c;即使某台broker宕机…

聚观早报 | 杭州亚运开幕科技感拉满;腾讯官宣启动「青云计划」

【聚观365】9月25日消息 杭州亚运开幕科技感拉满 腾讯官宣启动「青云计划」 FF任命新全球CEO 比亚迪夺得多国销冠 iPhone 15/15 Pro销售低于预期 杭州亚运开幕科技感拉满 杭州第19届亚洲运动会开幕式23日晚在杭州奥体中心主体育馆举行&#xff0c;这届开幕式可谓科技感拉…

基于Yolov8的野外烟雾检测(2):多维协作注意模块MCA,效果秒杀ECA、SRM、CBAM等 | 2023.9最新发布

目录 1.Yolov8介绍 2.野外火灾烟雾数据集介绍 3.MCA介绍 4.训练结果分析 5.系列篇 1.Yolov8介绍 Ultralytics YOLOv8是Ultralytics公司开发的YOLO目标检测和图像分割模型的最新版本。YOLOv8是一种尖端的、最先进的&#xff08;SOTA&#xff09;模型&#xff0c;它建立在先前…

【Vue】vue-cli一站式搭建SPA项目

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是Java方文山&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的专栏《Vue快速入门》。&#x1f3af;&#x1f3af; &…

Python:获取当前目录下所有文件夹名称及文件夹下所有文件名称

获取当前目录下所有文件夹名称 def get_group_list(folder_path):group_list []for root, dirs, files in os.walk(folder_path):for dir in dirs:group_list.append(dir)return group_list获取文件夹下所有文件名称 def get_file_list(folder_path, group_name):file_list …

[Linux入门]---进程的概念

文章目录 1.进程的概念①描述进程-PCB②task_struct-PCB的一种③task_ struct内容分类 2.查看进程3.通过系统调用获取进程表示符4.通过系统调用创建进程---fork初识 1.进程的概念 在我们的电脑开机的时候&#xff0c;操作系统会被加载到内存中&#xff0c;点击多个应用进行时&a…

机器学习第十四课--神经网络

总结起来&#xff0c;对于深度学习的发展跟以下几点是离不开的: 大量的数据(大数据)计算资源(如GPU)训练方法(如预训练) 很多时候&#xff0c;我们也可以认为真正让深度学习爆发起来的是数据和算力&#xff0c;这并不是没道理的。 由于神经网络是深度学习的基础&#xff0c;学…

基于SSM的高校图书馆个性化服务的设计与实现(有报告)。Javaee项目。

演示视频&#xff1a; 基于SSM的高校图书馆个性化服务的设计与实现&#xff08;有报告&#xff09;。Javaee项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&#xff0c;通过S…

前端JavaScript中的 == 和 ===区别,以及他们的应用场景,快来看看吧,积累一点知识。

&#x1f3ac; 江城开朗的豌豆&#xff1a;个人主页 &#x1f525; 个人专栏 :《 VUE 》 《 javaScript 》 ⛺️ 生活的理想&#xff0c;就是为了理想的生活 ! 目录 一、等于操作符 二、全等操作符 三、区别 小结 一、等于操作符 等于操作符用两个等于号&#xff08; &am…

GaussDB数据库SQL系列-定义重载函数

目录 一、前言 二、函数重载的定义 三、GaussDB创建自定义函数的事项说明 四、GaussDB数据库中的自定义函数示例 示例一&#xff1a;创建package属性重载函数&#xff0c;根据不同的SQL条件获取生成视图 示例二&#xff1a;创建package属性重载函数&#xff0c;根据不同的…

SpringMVC+入门案例

一、入门案例 1.依赖导入 <!--1. 导入SpringMVC与servlet的坐标--> <dependencies> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scop…

uni-app:实现元素中实现竖直居中

效果展示 前&#xff1a; 后&#xff1a; 未实现前代码 <template><view class"container"><view class"centered-element">我是要被居中的元素</view></view> </template><script>export default {data() {r…

3D目标检测实战 | 图解KITTI数据集与数据格式

目录 1 数据集简介2 传感器坐标系3 数据集下载与组织4 数据内容说明4.1 矫正文件calib4.2 图像文件image4.3 点云文件velodyne4.4 标签文件label4.5 平面文件plane 1 数据集简介 KITTI数据集是一个广泛应用于自动驾驶和计算机视觉领域的公开数据集。该数据集由德国卡尔斯鲁厄理…

Elasticsearch(Es搜索(简单使用、全文查询、复合查询)、地理位置查询、特殊查询、聚合操作、桶聚合、管道聚合)

Elasticsearch&#xff08;三&#xff09;——Es搜索&#xff08;简单使用、全文查询、复合查询&#xff09;、地理位置查询、特殊查询、聚合操作、桶聚合、管道聚合 一、Es搜索 这里的 Es 数据博主自己上网找的&#xff0c;为了练习 Es 搜索。 1、Elasticsearch 搜索入门 …

6、SpringBoot_项目的打包与运行

七、SpringBoot项目的打包与运行 1.目前项目怎么运行的 通过浏览器访问idea 将jar部署到服务器 2.maven 打包项目 命令 mvn package使用命令后会得到如下的jar 3.程序运行 命令 java -jar 项目.jar启动如下 4.springboot打包需要插件 插件 <plugin><group…

【AI视野·今日Robot 机器人论文速览 第三十六期】Tue, 19 Sep 2023

AI视野今日CS.Robotics 机器人学论文速览 Tue, 19 Sep 2023 (showing first 100 of 112 entries) Totally 112 papers &#x1f449;上期速览✈更多精彩请移步主页 Interesting: &#x1f4da;In-Hand Object Rotation, RotateIt 提出了一种基于视觉与触觉的物体旋转朝向的方法…

vtk- 数据类型(一) 三角链实例代码

三角链实例代码 #include <iostream> #include <string> #include <regex> #include "tuex.h" #include "vtkCylinderSource.h" #include "vtkPolyDataMapper.h" #include "vtkActor.h" #include "vtkRendere…

Tensorflow-gpu保姆级安装教程(Win11, Anaconda3,Python3.9)

Tensorflow-gpu 保姆级安装教程&#xff08;Win11, Anaconda3&#xff0c;Python3.9&#xff09; 前言Tensorflow-gpu版本安装的准备工作(一)、查看电脑的显卡&#xff1a;(二) 、Anaconda的安装(三)、cuda下载和安装(四)、cudnn下载安装(五)、配置环境变量(六)、创建 tensorfl…

数据结构之【泛型】

泛型&#xff1a;定义阶段不明确具体类型&#xff0c;产生对象时明确具体类型。 //Object是Java中的最高参数统一化&#xff0c;能够接受所有的引用类型&#xff1b; //有了包装类的自动拆装箱之后&#xff0c;Object还能够接收基本类型数值&#xff08;自动装箱&#xff09; …

常见限流算法学习

文章目录 常见限流算法学习前言限流算法基本介绍固定窗口计数器限流算法计数器限流算法相关介绍计数器限流算法的实现&#xff08;基于共享变量&#xff09;计数器限流算法的实现&#xff08;基于Redis&#xff09; 滑动窗口计数器算法滑动时间窗口算法相关介绍介绍滑动时间窗口…