#python #sockets #tcp #raspberry-pi
#python #сокеты #tcp #raspberry-pi
Вопрос:
Я получаю канал камеры с камеры на Raspberry PI на компьютер, используя сокет TCP, чтобы использовать его для OpenCV. Это работает хорошо с минимальной задержкой. Однако иногда кадр застревает (замораживается), и через некоторое время канал возвращается или окно OpenCV выходит из строя. Я искал везде и пробовал множество вещей, но я просто не знаю, что является причиной этого.
Сервер (ПК):
import socket
import struct
import numpy as np
import cv2
host = "192.168.0.12"
portCar = 8010
# Camera socket
camS = socket.socket()
camS.bind((host, portCar))
camS.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
# Listen for camera
camS.listen(0)
print("Waiting for camera connection...")
camCon = camS.accept()[0]
camFile = camCon.makefile("rb")
print("Connection made with camera")
camS.settimeout(0.00001)
numOfBytes = struct.calcsize("<L")
try:
while(True):
camS.setblocking(False)
imageLength = struct.unpack("<L", camFile.read(numOfBytes))[0]
if imageLength == 0:
break
nparr = np.frombuffer(camFile.read(imageLength), np.uint8)
frame = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
cv2.imshow('RC Car Video stream', frame)
if cv2.waitKey(1) amp; 0xFF == ord('q'):
break
finally:
camFile.close()
camS.close()
cv2.destroyAllWindows()
print("Server - Camera connection closed")
Клиент (PI):
import io
import socket
import struct
import time
import picamera
client_socket = socket.socket()
client_socket.connect(('192.168.0.12', 8010))
client_socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
connection = client_socket.makefile('wb')
class SplitFrames(object):
def __init__(self, connection):
self.connection = connection
self.stream = io.BytesIO()
def write(self, buf):
if buf.startswith(b'xffxd8'):
size = self.stream.tell()
if size > 0:
self.connection.write(struct.pack('<L', size))
self.connection.flush()
self.stream.seek(0)
self.connection.write(self.stream.read(size))
self.stream.seek(0)
self.stream.write(buf)
try:
output = SplitFrames(connection)
with picamera.PiCamera(resolution='VGA', framerate=30) as camera:
time.sleep(2)
camera.rotation = 180
camera.start_recording(output, format='mjpeg')
camera.wait_recording(2000)
camera.stop_recording()
# Write the terminating 0-length to the connection to let the
# server know we're done
connection.write(struct.pack('<L', 0))
finally:
connection.close()
client_socket.close()
print("Client - Connection closed")
Любая помощь будет высоко оценена.
Комментарии:
1. Linux не является операционной системой реального времени, и работа с SD-карты, скорее всего, вызовет задержки — так что, возможно, Pi просто не может плавно передавать видео без дополнительной буферизации — возможно, потребуется какая-то диагностика — пробовали ли вы в своем коде использовать фиктивный источник данных вместо камеры, пробовали ли вы добавить буферизацию?
2. @barny Нет, я не добавил буферизацию, я попробую это.