簡體   English   中英

使用Raspberry Pi中的OpenCV和套接字通過TCP發送視頻

[英]Send Video over TCP using OpenCV and sockets in Raspberry Pi

我一直在嘗試將我的客戶端(Raspberry Pi)的實時視頻幀發送到筆記本電腦上托管的服務器。 這兩個設備都連接到同一網絡。

Server.py

import socket
import sys
import cv2
import pickle
import numpy as np
import struct

HOST = '192.168.1.3'
PORT = 8083

s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print 'Socket created'

s.bind((HOST, PORT))
print 'Socket bind complete'
s.listen(10)
print 'Socket now listening'

conn, addr = s.accept()

data = ""
payload_size = struct.calcsize("L")

while True:
    while len(data) < payload_size:
        data += conn.recv(4096)
    packed_msg_size = data[:payload_size]

    data = data[payload_size:]
    msg_size = struct.unpack("L", packed_msg_size)[0]

    while len(data) < msg_size:
        data += conn.recv(4096)
    frame_data = data[:msg_size]
    data = data[msg_size:]

    frame=pickle.loads(frame_data)
    print frame.size
    # cv2.imshow('frame', frame)
    # cv2.waitKey(10)

Client.py

import cv2
import numpy as np
import socket
import sys
import pickle
import struct

cap = cv2.VideoCapture(0)
clientsocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
clientsocket.connect(('192.168.1.3', 8081))

while True:
    ret,frame = cap.read()
    data = pickle.dumps(frame)
    clientsocket.sendall(struct.pack("L", len(data)) + data)

筆記本電腦上的服務器沒有收到任何數據 但是當我在相同設備(例如筆記本電腦上的服務器和客戶端)上運行此客戶端和服務器時,它正常工作。

我能夠從覆盆子發送數據到筆記本電腦(測試回聲應用程序)。

誰能幫我這個 ?

根據我的理解,您應該為客戶端和服務器使用相同的端口,但您使用的是兩個不同的端口,8083和8081。

您是否檢查過防火牆是否為所使用的端口打開?

經過數小時的分析后,為什么server.py和client.py無法正常工作(即使在防火牆被禁用后),server.py代碼中也出現錯誤:“word不應該是字符串”。 因此,word =“”(這是一個字符串)應該更改為word = b''(這些是兩個單引號來表示一個字節)。

使用下面的代碼創建一個文件,通過運行例如python "C:\\path\\toFile\\streamTestServer.py"在Windows上的Powershell中運行服務器代碼

代碼是:

import socket
import sys
import cv2
import pickle
import numpy as np
import struct

HOST = '127.0.0.1'
PORT = 8083

s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print('Socket created')

s.bind((HOST, PORT))
print('Socket bind complete')
s.listen(10)
print('Socket now listening')

conn, addr = s.accept()

data = b''
payload_size = struct.calcsize("L")

while True:
    while len(data) < payload_size:
        data += conn.recv(4096)
    packed_msg_size = data[:payload_size]

    data = data[payload_size:]
    msg_size = struct.unpack("L", packed_msg_size)[0]

    while len(data) < msg_size:
        data += conn.recv(4096)
    frame_data = data[:msg_size]
    data = data[msg_size:]

    frame=pickle.loads(frame_data)
    print(frame.size)
    cv2.imshow('frame', frame)
    cv2.waitKey(10)

然后在Python IDLE或Powershell的另一個窗口中運行客戶端。 客戶代碼是:

import cv2
import numpy as np
import socket
import sys
import pickle
import struct

cap = cv2.VideoCapture(0)
clientsocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
clientsocket.connect(('127.0.0.1', 8083))

while True:
    ret,frame = cap.read()
    data = pickle.dumps(frame)
    clientsocket.sendall(struct.pack("L", len(data)) + data)

現在您從localhost客戶端流向localhost服務器。

使用這個相同的程序,我在覆盆子pi上接收數據時遇到了問題。 我發現這是因為在不同的機器上使用無符號長度的“L”之間的區別。 至少對我來說,他們在不同機器上的原生代表是不同的。 我通過在格式字符串中添加“=”來修復此問題,以強制struct使用標准大小“L”(4)解壓縮。

payload_size = struct.calcsize("=L")

clientsocket.sendall(struct.pack("=L", len(data)) + data)

等等

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM