numpy 使用Python套接字从网络摄像头发送检测到的帧

jv4diomz  于 2023-11-18  发布在  Python
关注(0)|答案(1)|浏览(127)

我会将从摄像头检测到的帧发送到另一个设备。该设备将使用YOLOv5检查对象,并将有多少对象发送到带摄像头的设备。我开始将图像发送到另一个设备,但我在Python套接字方面遇到了一些问题。
服务器代码:

import socket
import cv2
import io
import numpy as np
from PIL import Image

HOST = "127.0.0.1" 
PORT = 65432

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen()
conn, addr = s.accept()
print(f"Connected by {addr}")

camera = cv2.VideoCapture(0)

while True:
    ret, frame = camera.read()
    frame = cv2.resize(frame, (640, 480))
    frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
    frame = Image.fromarray(frame)
    frame_bytes = io.BytesIO()
    frame.save(frame_bytes, format="JPEG")
    frame_bytes = frame_bytes.getvalue()
    conn.sendall(frame_bytes)
    data = conn.recv(4096)
    print(data)
    if cv2.waitKey(1) & 0xFF == ord("q"):
        break

字符串
客户代码:

import socket
import time
import cv2
import io
import numpy as np
from PIL import Image
import random

HOST = "127.0.0.1" 
PORT = 65432 

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))

while True:
    data = s.recv(8192)
    frame = Image.open(io.BytesIO(data))
    frame = np.array(frame)
    frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
    cv2.imshow("frame", frame)
    cv2.waitKey(1)
    s.sendall(b"OK")


当我运行这些代码时,client.py返回一个错误:

Traceback (most recent call last):
  File "C:\Users\ASUS\Desktop\test\client.py", line 18, in <module>
    frame = np.array(frame)
            ^^^^^^^^^^^^^^^
  File "C:\Users\ASUS\AppData\Local\Programs\Python\Python311\Lib\site-packages\PIL\Image.py", line 696, in __array_interface__
    new["data"] = self.tobytes()
                  ^^^^^^^^^^^^^^
  File "C:\Users\ASUS\AppData\Local\Programs\Python\Python311\Lib\site-packages\PIL\Image.py", line 754, in tobytes
    self.load()
  File "C:\Users\ASUS\AppData\Local\Programs\Python\Python311\Lib\site-packages\PIL\ImageFile.py", line 266, in load
    raise OSError(msg)
OSError: image file is truncated (31 bytes not processed)
PS C:\Users\ASUS\Desktop\test> python client.py
Traceback (most recent call last):
  File "C:\Users\ASUS\Desktop\test\client.py", line 18, in <module>
    frame = np.array(frame)
            ^^^^^^^^^^^^^^^
  File "C:\Users\ASUS\AppData\Local\Programs\Python\Python311\Lib\site-packages\PIL\Image.py", line 696, in __array_interface__
    new["data"] = self.tobytes()
                  ^^^^^^^^^^^^^^
  File "C:\Users\ASUS\AppData\Local\Programs\Python\Python311\Lib\site-packages\PIL\Image.py", line 754, in tobytes
    self.load()
  File "C:\Users\ASUS\AppData\Local\Programs\Python\Python311\Lib\site-packages\PIL\ImageFile.py", line 266, in load
    raise OSError(msg)
OSError: image file is truncated (35 bytes not processed)


我试着改变接收缓冲区的大小,但我不能解决我的问题。

qnzebej0

qnzebej01#

我用TLV方案解决了这个问题。
客户代码:

import io
import cv2
import socket
import struct
import time
import numpy as np
from PIL import Image

cl_socket = socket.socket()
cl_socket.connect(('127.0.0.1', 8000))
connection = cl_socket.makefile('wb')

try:
    camera = cv2.VideoCapture(0)
    stream = io.BytesIO()
    
    while True:
        ret, frame = camera.read()
        frame = cv2.resize(frame, (640, 480))
        frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
        frame = Image.fromarray(frame)
        frame.save(stream, format="JPEG")
        stream.seek(0)
        image_bytes = stream.read()
        connection.write(struct.pack('<L', len(image_bytes))) 
        connection.flush()
        stream.seek(0)
        connection.write(stream.read())
        stream.seek(0)
        stream.truncate()   
    connection.write(struct.pack('<L', 0))
        
finally:
    connection.close()
    cl_socket.close()

字符串
服务器代码:

import cv2
import io
import socket
import struct
from PIL import Image
import numpy as np

server_socket = socket.socket()
server_socket.bind(('0.0.0.0', 8000))
server_socket.listen(0)

connection = server_socket.accept()[0].makefile('rb')

try:
    img = None
    while True:
        image_len = struct.unpack('<L', connection.read(struct.calcsize('<L')))[0]
        if not image_len:
            break
        image_stream = io.BytesIO()
        image_stream.write(connection.read(image_len))
        image_stream.seek(0)
        image = Image.open(image_stream).convert('RGB')
        image = np.array(image)
        cv2.imshow('Image', cv2.cvtColor(image, cv2.COLOR_RGB2BGR))
        cv2.waitKey(1)  

        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
finally:
    connection.close()
    server_socket.close()

相关问题