简体   繁体   English

使用Python中的套接字发送帧

[英]Sending frames using sockets in Python

I'm trying to get frames from client, send it to server and from there write it into a video. 我正在尝试从客户端获取帧,将其发送到服务器,然后从那里将其写入视频。 But I keep failing in sending part, getting TypeError: Expected Ptr<cv::UMat> for argument '%s' error in out.write(frame) . 但是我一直发送失败,在out.write(frame) TypeError: Expected Ptr<cv::UMat> for argument '%s'错误的TypeError: Expected Ptr<cv::UMat> for argument '%s'

I've also tried using pickle.dumps(frame) and then loading it in server side but it keeps getting truncated. 我也尝试过使用pickle.dumps(frame) ,然后在服务器端加载它,但它一直被截断。

Server: 服务器:

import numpy as np 
import cv2, socket

fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter("output.avi", fourcc, 19.0, (1366, 768))

s = socket.socket()
host = socket.gethostname()
port = 8080
s.bind((host,port))
s.listen(1)
print(host)
print("Waiting for any incoming connections ... ")
conn, addr = s.accept()
print(addr, "Has connected to the server")

while True:
    frame = conn.recv(1024)
    # write frame to video writer
    out.write(frame)

    if cv2.waitKey(1) == 27:
        break

out.release()
cv2.destroyAllWindows()

Client: 客户:

import numpy as np 
import cv2, socket
from PIL import ImageGrab

s = socket.socket()
host = input(str("Please enter the host address of the sender : "))
port = 8080
s.connect((host,port))
print("Connected ... ")


while True:
    img = ImageGrab.grab()
    img_np = np.array(img)
    frame = img_np
    s.send(frame)

Apparently in server, frame becomes <class 'bytes'> . 显然在服务器中,frame变为<class 'bytes'> So, I'm trying to find any way to fix this, including somehow converting bytes back into ndarray, or finding any other workaround. 因此,我正在尝试找到解决此问题的任何方法,包括以某种方式将字节转换回ndarray,或找到任何其他解决方法。

Thanks. 谢谢。

Lets separate your question into two parts: 让您将问题分为两个部分:

  1. How to send data over a socket? 如何通过套接字发送数据?
    You are using a socket with 1024 bytes buffer which means that in every iteration you get 1024 bytes data at maximum. 您正在使用具有1024字节缓冲区的套接字,这意味着在每次迭代中,您最多可以获得1024字节的数据。
    What you should do when working in low level networking, is to put a unique end identifier token in the end of the frame and iterate in the server side with .recv() until you reached it. 在低级网络中工作时,应该做的是在帧的末尾放置一个唯一的结束标识符令牌,并使用.recv()在服务器端进行迭代,直到到达为止。 Another option is to send the length of your message and count the received bytes. 另一种选择是发送消息的长度并计算接收到的字节数。 This way, you know when you have a complete frame, then you can break the while loop, convert it to numpy array and .write() it. 这样,当您拥有完整的帧时,就可以中断while循环,将其转换为numpy数组,并对其进行.write()。

  2. How to pass numpy array over network? 如何通过网络传递numpy数组?

    • You can pickle it and transfer the bytes into a io.BytesIO stream. 您可以对其进行腌制并将字节传输到io.BytesIO流中。 Then load the stream with np.load() function. 然后使用np.load()函数加载流。
    • You can also serialize the frame pixels as array of your pixel type, read them from the socket into io.BytesIO, then read them into numpy with np.fromfile(..., dtype= ...) 您还可以将帧像素序列化为像素类型的数组,将其从套接字读取到io.BytesIO中,然后使用np.fromfile(...,dtype = ...)读取到numpy中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM