如何实现C#和Python之间实时视频数据交互

我们在做RTSP|RTMP播放的时候,遇到好多开发者,他们的视觉算法大多运行在python下,需要高效率的实现C#和Python的视频数据交互,常用的方法如下:

方法一:通过HTTP请求传输视频数据

服务器端(Python)

使用Flask或Django等Web框架创建一个HTTP服务器,通过API接口提供视频数据。

from flask import Flask, send_file, request, jsonify  
import cv2  
import io  
import base64  app = Flask(__name__)  def get_video_frame():  # 读取视频帧  cap = cv2.VideoCapture('your_video.mp4')  ret, frame = cap.read()  cap.release()  if not ret:  return None, "No more frames"  # 转换为RGB格式  frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)  # 转换为字节流  ret, buffer = cv2.imencode('.jpg', frame_rgb)  if not ret:  return None, "Could not encode frame"  # 将字节流转换为base64字符串  img_str = base64.b64encode(buffer).decode('utf-8')  return img_str, 200  @app.route('/video_frame', methods=['GET'])  
def video_frame():  img_str, status_code = get_video_frame()  if img_str is None:  return jsonify({"error": status_code}), status_code  return jsonify({"image": img_str})  if __name__ == '__main__':  app.run(debug=True)
客户端(C#)

使用HttpClient从Python服务器获取视频帧,并将其显示在PictureBox中。

using System;  
using System.Drawing;  
using System.Drawing.Imaging;  
using System.IO;  
using System.Net.Http;  
using System.Windows.Forms;  public class VideoForm : Form  
{  private PictureBox pictureBox;  private HttpClient httpClient;  public VideoForm()  {  pictureBox = new PictureBox  {  Dock = DockStyle.Fill,  SizeMode = PictureBoxSizeMode.StretchImage  };  this.Controls.Add(pictureBox);  httpClient = new HttpClient();  Timer timer = new Timer();  timer.Interval = 100; // Adjust the interval as needed  timer.Tick += Timer_Tick;  timer.Start();  }  private async void Timer_Tick(object sender, EventArgs e)  {  try  {  HttpResponseMessage response = await httpClient.GetAsync("http://localhost:5000/video_frame");  response.EnsureSuccessStatusCode();  string jsonResponse = await response.Content.ReadAsStringAsync();  dynamic jsonData = Newtonsoft.Json.JsonConvert.DeserializeObject(jsonResponse);  string base64String = jsonData.image;  byte[] imageBytes = Convert.FromBase64String(base64String);  using (MemoryStream ms = new MemoryStream(imageBytes))  {  Image image = Image.FromStream(ms);  pictureBox.Image = image;  }  }  catch (Exception ex)  {  MessageBox.Show($"Error: {ex.Message}");  }  }  [STAThread]  public static void Main()  {  Application.EnableVisualStyles();  Application.Run(new VideoForm());  }  
}

方法二:通过ZeroMQ传输视频数据

ZeroMQ是一种高性能的异步消息库,适用于需要低延迟和高吞吐量的应用。

服务器端(Python)

使用pyzmq库发送视频帧。

import zmq  
import cv2  
import numpy as np  context = zmq.Context()  
socket = context.socket(zmq.PUB)  
socket.bind("tcp://*:5555")  cap = cv2.VideoCapture('your_video.mp4')  while True:  ret, frame = cap.read()  if not ret:  break  frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)  frame_bytes = frame_rgb.tobytes()  socket.send_string("FRAME", zmq.SNDMORE)  socket.send(frame_bytes, flags=0, copy=False)
客户端(C#)

使用NetMQ库接收视频帧。

using System;  
using System.Drawing;  
using System.Drawing.Imaging;  
using System.Runtime.InteropServices;  
using System.Threading.Tasks;  
using System.Windows.Forms;  
using NetMQ;  
using NetMQ.Sockets;  public class VideoForm : Form  
{  private PictureBox pictureBox;  private SubscriberSocket subscriber;  public VideoForm()  {  pictureBox = new PictureBox  {  Dock = DockStyle.Fill,  SizeMode = PictureBoxSizeMode.StretchImage  };  this.Controls.Add(pictureBox);  var address = "tcp://localhost:5555";  using (var context = NetMQContext.Create())  {  subscriber = context.CreateSubscriberSocket();  subscriber.Connect(address);  subscriber.Subscribe("FRAME");  Task.Run(() => ReceiveFramesAsync(subscriber));  }  }  private async Task ReceiveFramesAsync(SubscriberSocket subscriber)  {  while (true)  {  var topic = await subscriber.ReceiveFrameStringAsync();  var frameBytes = await subscriber.ReceiveFrameBytesAsync();  if (topic == "FRAME")  {  int width = 640; // Adjust based on your video resolution  int height = 480; // Adjust based on your video resolution  int stride = width * 3;  Bitmap bitmap = new Bitmap(width, height, PixelFormat.Format24bppRgb);  BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, bitmap.PixelFormat);  Marshal.Copy(frameBytes, 0, bitmapData.Scan0, frameBytes.Length);  bitmap.UnlockBits(bitmapData);  pictureBox.Image = bitmap;  }  }  }  [STAThread]  public static void Main()  {  Application.EnableVisualStyles();  Application.Run(new VideoForm());  }  
}

方法三:通过共享内存或文件

如果C#和Python运行在同一台机器上,可以通过共享内存或文件系统进行数据交换。这种方法相对简单,但性能可能不如前两种方法。

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

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

相关文章

浙江省发规院产业发展研究所调研组莅临迪捷软件考察调研

2024年10月10日下午,浙江省发展与规划院产业发展研究所调研组一行莅临迪捷软件考察调研,绍兴市府办、区发改、区经信、迪荡街道等相关领导陪同。 调研组一行参观了迪捷软件的展厅与办公区,深入了解了迪捷软件的公司发展历程、运营状况、产品…

『网络游戏』数据库表格转储【25】

避免勿删数据库表格,可以将表格存储 放到桌面即可 现在将表格删除后点击 浏览桌面表格保存即可 修改客户端脚本:NetSvc.cs 目的是在数据库更新异常时弹出提示以便修改 本章结束

一文区分SSTI 和 CSTI

前言 有时,SSTI(服务器端模板注入)和 CSTI(客户端模板注入)可能会由于它们相似的负载语法而混淆。这种混乱可能会导致渗透测试人员浪费时间尝试实现反向 shell,即使payload仅限于客户端。 定义 &#x1d…

【AI系统】AI系统的组成

AI系统的组成是实现其设计目标的基础。本文将详细介绍AI系统的各个组成部分,以及它们如何协同工作以支持AI应用程序的开发和运行。 I. 引言 AI系统的复杂性要求其组成不仅要关注单一的硬件或软件,而是需要一个多层次、多维度的架构设计。这包括从应用与…

安卓13禁止用户打开开发者选项 android13禁止用户打开开发者选项

总纲 android13 rom 开发总纲说明 文章目录 1.前言2.问题分析3.代码分析4.代码修改5.编译6.彩蛋1.前言 设置 =》关于平板电脑 =》版本号,一般的话,在这里连续点击就可以打开我们的开发者选项了。但是有些系统要进行保密,因此要禁止用户进入。 2.问题分析 这里我们是通过点…

vue3.5系列之响应式props解构的几点技巧对比

在最新的版本3.5x中&#xff0c;对props的能力也进行了加强。下面&#xff0c;我们具体看下有哪些变化&#xff0c;给我们带来的新的体验&#xff01; 体验一 3.5之前解构props的效果 // 子组件 <template><div><h1>响应式props</h1><p>{{ co…

Linux工具的使用——yum和vim的理解和使用

目录 linux工具的使用1.linux软件包管理器yum1.1yum的背景了解关于yum的拓展 1.2yum的使用 2.Linux编辑器-vim使用2.1vim的基本概念2.2vim的基本操作2.3命令模式命令集2.3.1关于光标的命令&#xff1a;2.3.2关于复制粘贴的命令2.3.3关于删除的命令2.3.4关于文本编辑的命令 2.4插…

ElasticSearch备考 -- Update by query Reindex

一、题目 有个索引task&#xff0c;里面的文档长这样 现在需要添加一个字段all&#xff0c;这个字段的值是以下 a、b、c、d字段的值连在一起 二、思考 需要把四个字段拼接到一起&#xff0c;组成一个新的字段&#xff0c;这个就需要脚本&#xff0c; 这里有两种方案&#xff…

Python进阶--正则表达式

目录 1. 基础匹配 2. 元字符匹配 1. 基础匹配 正则表达式&#xff0c;又称规则表达式&#xff08;Regular Expression&#xff09;&#xff0c;是使用单个字符串来描述、匹配某个句法规则的字符串&#xff0c;常被用来检索、替换那些符合某个模式&#xff08;规则&#xff…

zotero使用koofr+google drive/onedrive同步

最早了解到这个思路是来自 知乎-【从零开始使用Zotero】(3) Zotero文献同步方式 和 How to Sync Zotero Files Using WebDAV and Google Drive with Koofr: A Step-by-Step Guide 虽然周围很多人都在用Readpaper这种web端的了&#xff0c;但是经常逛Arxiv而且zotero的web插…

计算机网络——email

pop3拉出来 超出ASCII码范围就不让传了 这样就可以传更大的文件

与 MySQL 建立连接

命令行连接 MySQL 前面介绍了在 Windows 下安装最新版 MySQL 初始化安装步骤&#xff0c;启动 MySQL 服务&#xff0c;记录的初始密码可用于 “root” 账户登录进行相关操作&#xff0c;Windows 和 Linux 命令行操作步骤一样: 上图为 MySQL 的初始密码。在 Windows 下打开 CMD …

EdgeNAT: 高效边缘检测的 Transformer

EdgeNAT: Transformer for Efficient Edge Detection 介绍了一种名为EdgeNAT的基于Transformer的边缘检测方法。 1. 背景与动机 EdgeNAT预测结果示例。(a, b):来自BSDS500的数据集的输入图像。(c, d):对应的真实标签。(e, f):由EdgeNAT检测到的边缘。(e)显示了由于颜色变化…

小学期中考试老师怎么发成绩

随着期中考试的落幕&#xff0c;老师们面临着一项既耗时又易出错的任务——发布成绩。传统的手动统计和通知方式不仅效率低下&#xff0c;还容易出错。现在&#xff0c;有了一种新的在线平台&#xff0c;可以帮助老师们简化这一流程。 这个平台叫做“易查分”&#xff0c;它是一…

【LLM】Agent在智能客服的实践(AI agent、记忆、快捷回复 | ReAct)

note 内容概况&#xff1a;结合京粉app学习agent的实践 Agent架构&#xff1a;通过模型训练提升LLM识别工具的准确性&#xff1b;设计可扩展并安全可控的agent架构扩展业务能力。记忆&#xff1a;多轮对话应用中如何组织、存储和检索记忆来提升大模型对用户的理解。快捷回复&…

Prescan中的缓和曲线道路spiral road

我主要是针对城市道路作设计&#xff0c;所以主要依据参考&#xff1a;城市道路工程设计规范 CJJ37 -2012 城市道路工程设计规范CJJ37-2012(2016年版) (soujianzhu.cn) 道路的平面线形主要包括直线和平曲线两种形式。直线的几何形状相对固定&#xff0c;缺乏灵活性&#xff0…

水深探测仪的作用和使用方法

在水域救援的行动里&#xff0c;救援人员时刻面临着复杂多变、充满未知的水域状况。当接到救援任务奔赴现场&#xff0c;那片需要涉足的水域就像一个神秘莫测的异世界&#xff0c;挑战着所有人的认知与勇气。 水深探测仪作为一种专用于测量水域深度的设备&#xff0c;通过声波和…

用户和组管理

用户管理 用户管理包括创建用户、修改用户属性、删除用户等操作。 创建用户 使用 useradd 命令可以创建新用户。 格式&#xff1a;useradd [选项] username 步骤1&#xff1a;创建新用户 useradd tom 步骤 2: 设置用户密码 新用户创建后&#xff0c;需要设置一个密码才能…

No.15 笔记 | CSRF 跨站请求伪造

目录 一、基础知识 &#xff08;一&#xff09;cookie 和 session、同源策略 &#xff08;二&#xff09;CSRF 原理 二、CSRF 类型 &#xff08;一&#xff09;GET 类型 &#xff08;二&#xff09;POST 类型 三、CSRF 实例讲解 &#xff08;一&#xff09;真实案例 &am…

springboot如何自动生成mybatis映射文件、dao、pojo层文件?

背景&#xff1a;以前一直是直接cv一个项目中现成的xml文件&#xff0c;然后再去自己配置mapper等数据。自己准备做一个单独的例子试一下。 步骤1&#xff1a;在pom.xml文件中插入mybatis-generator插件&#xff0c;这里选的版本是1.3.2&#xff0c;然后指定的generator文件是在…