日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

Python >>> 基于UDP 协议的实时网络视频传输

發(fā)布時間:2023/12/9 python 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Python >>> 基于UDP 协议的实时网络视频传输 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

一、前言

最近想寫一個實時的視頻傳輸程序,然后上網找了很久沒有找到合適的

我想用OpenCV 進行圖像采集,然后用pygame 將視頻信號轉化為可通過UDP 網絡傳輸?shù)淖址?#xff0c;然后到達終端后再通過pygame 對字符流進行解析,進而將圖像顯示出來

之所以使用UDP 傳輸而不是TCP 傳輸,是因為UDP 在視頻傳輸方面擁有快速、無需連接等優(yōu)點,適合密集傳送大量信息的場合
但UDP 傳輸有一個問題,就是一次傳輸量有限,這就直接導致后續(xù)傳輸?shù)囊曨l信號需要進行一定壓縮

所以我就開始自己搗鼓了 😃

本文內容若有不懂可查閱如下教程:
Windows 安裝pygame 模塊
樹莓派 與 Xbox360手柄 基于pygame 的一次邂逅
樹莓派Camera 的使用
【手把手教學—超簡單】樹莓派安裝OpenCV 3
Python + OpenCV 學習筆記(二)>>> 加載視頻流
Python >>> UDP 網絡編程

我是用樹莓派作為視頻采集端,然后筆記本作為信號接收端的


注意:PC端需關閉防火墻后方可成功接收數(shù)據(jù)!

二、開始

1)整體思路

  • 在發(fā)送端使用OpenCV 打開攝像頭采集視頻幀信號;
  • 將視頻幀信號輸出為jpg 圖片文件;
  • pygame 模塊將該jpg 圖片轉化為字符流;
  • 將該字符流通過UDP 傳輸?shù)浇邮斩?#xff1b;
  • 接收端同樣使用pygame 對字符流進行解析,最終即可獲得圖像信息。
  • 2)攝像頭采集視頻幀

    import cv2 as cvcapture = cv.VideoCapture(0) while True:# 獲得圖像幀ret, frame = capture.read()# 圖像翻轉frame = cv.flip(frame, -1)# 將圖像尺寸縮小,便于傳輸frame = cv.resize(frame, (160, 120))

    3)將圖像幀輸出為圖片

    cv.imwrite("test.jpg", frame)

    4)將圖片轉化為字符流

    # 加載圖片 Img = pygame.image.load('/home/pi/test.jpg') # 圖片轉化字符串 string = pygame.image.tostring(Img, "RGB")

    5)通過UDP 傳輸字符流

    我創(chuàng)建了一個進程用于傳輸數(shù)據(jù):

    def mythread(sock, data, addr):sock.sendto(data, addr)print("已發(fā)送 " + str(len(data)) + " bytes")sock.close()# socket.SOCK_DGRAM 代表是使用UDP協(xié)議 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) t = threading.Thread(target=mythread, args=(sock, string, ('192.168.0.196', 9999))) t.start()

    注意:當發(fā)送密集數(shù)據(jù)時,如圖像數(shù)據(jù)等。需要控制圖像大小(例如160*120),不然發(fā)不出去。

    6)接收端接收數(shù)據(jù)并解析

    # 創(chuàng)建連接 s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # 綁定端口 s.bind(('192.168.0.196', 9999)) # 接收數(shù)據(jù) data, addr = s.recvfrom(60000)# 字符串再轉化為圖片 img = pygame.image.frombuffer(data, (180, 160), "RGB")

    7)將圖像顯示出來

    # 窗口內設置白色底色和圖片,并更新顯示 gameDisplay.fill(WHITE) gameDisplay.blit(img, (0, 0)) pygame.display.update()

    三、完整程序

    1)發(fā)送端

    #coding:utf-8 import pygame import cv2 as cv from picamera import PiCamera import time import threading import socketpygame.init()# 傳輸視頻信號的UDP 連接進程 def mythread(sock, data, addr):sock.sendto(data, addr)print("已發(fā)送 " + str(len(data)) + " bytes")sock.close()def main():print("begin")start = time.clock()capture = cv.VideoCapture(0)while True:ret, frame = capture.read()frame = cv.flip(frame, -1)frame = cv.resize(frame, (160, 120))cv.imwrite("test.jpg", frame)# 加載圖片Img = pygame.image.load('/home/pi/test.jpg')# 圖片轉化字符串string = pygame.image.tostring(Img, "RGB")sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)t = threading.Thread(target=mythread, args=(sock, string, ('192.168.0.196', 9999)))t.start()if cv.waitKey(10) & 0xff == ord('q'):breakmain() cv.destroyAllWindows()

    2)接收端

    #coding=utf-8 import socket import time import threading import pygame# 顏色 WHITE = (255,255,255) GREEN = ( 0, 255, 0) BLUE = ( 0, 0, 128) BLACK = ( 0, 0, 0)# 創(chuàng)建連接 s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # 綁定端口 s.bind(('192.168.0.196', 9999))print('Waiting for connection...')pygame.init()# 設置標題 pygame.display.set_caption('UDP 視頻傳輸')# 開啟窗口 display_width = 300 display_height = 200 gameDisplay = pygame.display.set_mode((display_width,display_height))# 判斷是否結束pygame gamefinish = False # 幀率 frame_rate = 0# 通過字體文件獲得字體對象 fontObj = pygame.font.Font('C:/Windows/Fonts/comici.ttf', 20) # 配置要顯示的文字 textSurfaceObj = fontObj.render('FPS', True, BLACK, WHITE) # 獲得要顯示的對象的rect textRectObj = textSurfaceObj.get_rect() # 設置顯示對象的坐標 textRectObj.center = (200, 10)# 用于視頻顯示delay clock = pygame.time.Clock() # 用于幀率計算 start = time.perf_counter()while not gamefinish:for event in pygame.event.get():if event.type == pygame.QUIT:gamefinish = Trueprint(event)# 無數(shù)據(jù)接收則線程掛起,等待數(shù)據(jù)data, addr = s.recvfrom(60000)frame_rate = frame_rate + 1if time.perf_counter() - start > 1:start = time.perf_counter()# 配置要顯示的文字textSurfaceObj = fontObj.render(("FPS: " + str(frame_rate)), True, BLACK, WHITE)frame_rate = 0print('Received from %s:%s.' % addr)# 字符串再轉化為圖片img = pygame.image.frombuffer(data, (160, 120), "RGB")# 窗口內設置白色底色和圖片,并更新顯示gameDisplay.fill(WHITE)gameDisplay.blit(img, (0, 0))gameDisplay.blit(textSurfaceObj, textRectObj)pygame.display.update()clock.tick(60)pygame.quit()

    四、結果

    在實際測試中,我發(fā)現(xiàn)160*120的分辨率對網絡要求較高,而當分辨率降為80*60時則效果好一點(幀率基本在30左右):
    當然,這樣的話視頻窗口顯得很小。


    我們可以在接收端對圖像進行放大:
    (成像質量下降)

    # 指定size 放大 img = pygame.transform.scale(img, (160, 120)) # 直接放大兩倍 img = pygame.transform.scale2x(img)


    總結

    以上是生活随笔為你收集整理的Python >>> 基于UDP 协议的实时网络视频传输的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。