欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解如何實現(xiàn)C#和Python間實時視頻數(shù)據(jù)交互

 更新時間:2024年10月12日 09:53:26   作者:音視頻牛哥  
我們在做RTSP|RTMP播放的時候,遇到好多開發(fā)者,他們的視覺算法大多運行在python下,需要高效率的實現(xiàn)C#和Python的視頻數(shù)據(jù)交互,本文給大家總結(jié)了一些常用的方法,感興趣的小伙伴跟著小編一起來看看吧

我們在做RTSP|RTMP播放的時候,遇到好多開發(fā)者,他們的視覺算法大多運行在python下,需要高效率的實現(xiàn)C#和Python的視頻數(shù)據(jù)交互,常用的方法如下:

方法一:通過HTTP請求傳輸視頻數(shù)據(jù)

服務(wù)器端(Python)

使用Flask或Django等Web框架創(chuàng)建一個HTTP服務(wù)器,通過API接口提供視頻數(shù)據(jù)。

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"  
  
    # 轉(zhuǎn)換為RGB格式  
    frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)  
  
    # 轉(zhuǎn)換為字節(jié)流  
    ret, buffer = cv2.imencode('.jpg', frame_rgb)  
    if not ret:  
        return None, "Could not encode frame"  
  
    # 將字節(jié)流轉(zhuǎn)換為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服務(wù)器獲取視頻幀,并將其顯示在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傳輸視頻數(shù)據(jù)

ZeroMQ是一種高性能的異步消息庫,適用于需要低延遲和高吞吐量的應(yīng)用。

服務(wù)器端(Python)

使用pyzmq庫發(fā)送視頻幀。

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());  
    }  
}

方法三:通過共享內(nèi)存或文件

如果C#和Python運行在同一臺機器上,可以通過共享內(nèi)存或文件系統(tǒng)進行數(shù)據(jù)交換。這種方法相對簡單,但性能可能不如前兩種方法。

以上就是詳解如何實現(xiàn)C#和Python間實時視頻數(shù)據(jù)交互的詳細內(nèi)容,更多關(guān)于C#和Python視頻數(shù)據(jù)交互的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • C# 獲取硬件參數(shù)的實現(xiàn)方法

    C# 獲取硬件參數(shù)的實現(xiàn)方法

    這篇文章主要介紹了C# 獲取硬件參數(shù)的實現(xiàn)方法的相關(guān)資料,希望通過本文能幫助到大家,讓大家實現(xiàn)這樣的功能,需要的朋友可以參考下
    2017-10-10
  • C#難點逐個擊破(8):可空類型System.Nullable

    C#難點逐個擊破(8):可空類型System.Nullable

    null值用來表示數(shù)據(jù)類型未被賦予任何值,它是一種引用類型;void表示沒有類型,或者說是沒有任何值。null與void的區(qū)別可以認為void是根本沒有,而null是一個空箱子,里面什么都沒有。
    2010-02-02
  • C#中Foreach循環(huán)遍歷的本質(zhì)與枚舉器詳解

    C#中Foreach循環(huán)遍歷的本質(zhì)與枚舉器詳解

    這篇文章主要給大家介紹了關(guān)于C#中Foreach循環(huán)遍歷本質(zhì)與枚舉器的相關(guān)資料,foreach循環(huán)用于列舉出集合中所有的元素,foreach語句中的表達式由關(guān)鍵字in隔開的兩個項組成,本文通過示例代碼介紹的非常詳細,需要的朋友可以參考下
    2021-08-08
  • C#使?XmlReader和XmlWriter操作XML?件

    C#使?XmlReader和XmlWriter操作XML?件

    這篇文章介紹了C#使?XmlReader和XmlWriter操作XML?件的方法,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-06-06
  • C# [ImportDll()] 知識小結(jié)

    C# [ImportDll()] 知識小結(jié)

    今天小編就為大家分享一篇關(guān)于C# [ImportDll()] 知識小結(jié),小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-01-01
  • C#使用log4net結(jié)合sqlite數(shù)據(jù)庫實現(xiàn)記錄日志

    C#使用log4net結(jié)合sqlite數(shù)據(jù)庫實現(xiàn)記錄日志

    因為結(jié)構(gòu)化的數(shù)據(jù)庫存儲的日志信息,可以寫專門的軟件讀取歷史日志信息,通過各種條件篩選,可操作性極大增強,有這方面需求的開發(fā)人員可以考慮,本文給大家介紹了C#使用log4net結(jié)合sqlite數(shù)據(jù)庫記錄日志,需要的朋友可以參考下
    2024-10-10
  • WPF通過線程使用ProcessBar的方法詳解

    WPF通過線程使用ProcessBar的方法詳解

    這篇文章主要給大家介紹了關(guān)于WPF通過線程使用ProcessBar的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家學習或者使用WPF具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧
    2019-04-04
  • C#解碼base64編碼二進制數(shù)據(jù)的方法

    C#解碼base64編碼二進制數(shù)據(jù)的方法

    這篇文章主要介紹了C#解碼base64編碼二進制數(shù)據(jù)的方法,涉及C#中Convert類的靜態(tài)方法Convert.FromBase64String使用技巧,需要的朋友可以參考下
    2015-04-04
  • C#中的Socket編程詳解

    C#中的Socket編程詳解

    本文詳細講解了C#中的Socket編程,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-01-01
  • 比較全的一個C#操作word文檔示例

    比較全的一個C#操作word文檔示例

    這篇文章主要介紹了比較全的一個C#操作word文檔示例,本文來自己項目心得總結(jié),本文還給出了一個示例,這個示例里面包括了一些常用的圖、文、表、公式的編輯與排版以及頁面設(shè)置、頁眉、頁碼的操作,需要的朋友可以參考下
    2015-06-06

最新評論