не отображаются маринованные данные numpy в сокете Python

#python #sockets #opencv #python-sockets

#python #сокеты #opencv #python-сокеты

Вопрос:

Я пытаюсь отправить фреймы python-opencv через сокеты. Я собираю данные и удаляю их, но по какой-то причине они пустые или ничего не отображается.

Это мой терминал, когда я запускаю client.py

 new message length: b'720       '
  

Он должен транслировать веб-камеру с сервера, но ничего не отображается.

Вот мой код для клиента и сервера:

client.py

 import socket
import numpy as np
import cv2
import pickle

HEADERSIZE = 10

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((socket.gethostname(), 1232))

while True:
    full_msg = b''
    new_msg = True

    while True:
        msg = s.recv(16)
        if new_msg:
            print(f'new message length: {msg[:HEADERSIZE]}')
            msglen = int(msg[:HEADERSIZE])
            new_msg = False
                                                  
        full_msg  = msg

        if len(full_msg)-HEADERSIZE == msglen:
            print('full msg recvd')
            print(full_msg[HEADERSIZE:])

            d = pickle.loads(full_msg[HEADERSIZE:])
            print(d)

            cv2.namedWindow('Webcam', cv2.WINDOW_NORMAL)
            cv2.imshow('Webcam', full_msg[HEADERSIZE:])

            new_msg = True
            full_msg = b''

    print(full_msg)
  

server.py

 import socket
import numpy as np
import cv2
import time
import pickle
from signal import signal, SIGPIPE, SIG_DFL
signal(SIGPIPE, SIG_DFL)

HEADERSIZE = 10

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((socket.gethostname(), 1232))
s.listen(5)

cap = cv2.VideoCapture(0)

while True:
    clientsocket, address = s.accept()
    print(f"Connection from {address} has been established!")

    while True:                                                                   
        ret, frame = cap.read()                                       

        msg = pickle.dumps(frame)
        print(frame)
        msg = bytes(f'{len(frame):<{HEADERSIZE}}', "utf-8")   msg

        clientsocket.send(msg)
  

Я понятия не имею, почему ничего не отображается. Я даже не знаю, приходит ли что-нибудь. Связано ли это с данными numpy? Я слышал, что это может быть сложно.

Ответ №1:

Когда вы передаете кадры объемом 720 байт с сервера, вы фактически отправляете 730 байт (длина 10 байт данные 720 байт) на кадр непрерывно, один кадр за другим.
В клиенте вы читаете 16 байт на recv() . Следовательно, ваше условие if len(full_msg)-HEADERSIZE == msglen: никогда не будет истинным, с размером заголовка 10, поскольку 730 не делится на 16.

Итак, ваша программа бесконечно зацикливается на while True: в клиенте.

Попробуйте приведенную ниже программу для клиента. Я тестировал с фиктивными данными.

client.py

 import socket
import numpy as np
import cv2
import pickle

HEADERSIZE = 10

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((socket.gethostname(), 1232))

while True:
    msg_length=int(s.recv(HEADERSIZE))
    full_msg=b''
    while len(full_msg)<msg_length:
        full_msg =s.recv(msg_length-len(full_msg))
    
    print(full_msg)
    
    d = pickle.loads(full_msg)
    cv2.namedWindow('Webcam', cv2.WINDOW_NORMAL)
    cv2.imshow('Webcam', full_msg)
  

Комментарии:

1. Это решило проблему, о которой я спрашивал изначально, но теперь у меня возникла новая проблема. На самом деле, когда вы ответили своим решением, я переделал свою программу, но вместо этого я не использовал pickle и самостоятельно преобразовал в байты. Я попал в то же место, что и ваше решение: Traceback (most recent call last): File "client.py", line 21, in <module> cv2.imshow('Webcam', full_msg) TypeError: Expected Ptr<cv::UMat> for argument 'mat'