为了账号安全,请及时绑定邮箱和手机立即绑定

Cv2:从套接字接收完整数据的问题

Cv2:从套接字接收完整数据的问题

吃鸡游戏 2022-10-05 17:05:37
我正在尝试通过套接字发送帧,并且在编码后它们通常是 50 000 - 80 000 字节,所以我通过循环接收数据,但是由于客户端总是发送帧,所以下面代码中的循环不会中断,所以当我运行时没有任何反应并且接收循环继续客户import socketimport cv2import times = socket.socket(socket.AF_INET , socket.SOCK_STREAM)s.connect(("127.0.0.1",60124))camera = cv2.VideoCapture(0)while True :    r , f = camera.read()    f = cv2.imencode(".jpg",f)[1].tostring()    s.sendall(f)服务器import socketimport numpy as npimport cv2s = socket.socket(socket.AF_INET , socket.SOCK_STREAM)s.bind(("127.0.0.1",60124))s.listen(5)c , a = s.accept()while True :    data = ""    while True:        f = c.recv(1024)        if not f :            break        data += f    x = np.fromstring(data , np.uint8)    var = cv2.imdecode(x , cv2.IMREAD_COLOR)    cv2.imshow("Camera" , var)    cv2.waitKey(1)请帮助
查看完整描述

1 回答

?
波斯汪

TA贡献1811条经验 获得超4个赞

我建议你先发送长度,然后发送数据。
当服务器接收到“有效负载”长度时,它知道需要多少数据字节。

客户端:

  • len(f)8字节形式发送

  • 发送数据f

服务器:

  • 接收8字节以获取len_f.

  • 接收len_f数据字节。
    无需以 1024 字节块的形式接收数据。

在我的示例中,len_f被编码为base64格式。
发送的字节数len_f始终为 8 个字节(由于 base64 自动填充)。

data您也可以编码base64
如果您通过 HTTP 发送数据,这一点很重要。
我将base64图像数据的编码/解码放在注释中。
只有长度被编码为base64(您也可以将长度作为文本格式发送)。


客户:

import socket

import numpy as np

import cv2

import base64


s = socket.socket(socket.AF_INET , socket.SOCK_STREAM)

s.connect(("127.0.0.1", 60124))


width, height, n_frames = 640, 480, 100  # 100 frames, resolution 640x480


for i in range(n_frames):

    # Generate synthetic image:

    img = np.full((height, width, 3), 60, np.uint8)

    cv2.putText(img, str(i+1), (width//2-100*len(str(i+1)), height//2+100), cv2.FONT_HERSHEY_DUPLEX, 10, (30, 255, 30), 20)  # Green number


    # JPEG Encode img into f

    _, f = cv2.imencode('.JPEG', img)


    # Encode jpeg_img to base64 format

    #f = base64.b64encode(f)

    # Get length of f and encode to base64

    #f_len = base64.b64encode((len(f)).to_bytes(4, byteorder='little'))


    f_len = base64.b64encode((len(f)).to_bytes(4, byteorder='little'))


    # Send the length first - so the server knows how many bytes to expect.

    s.sendall(f_len) # Send 8 bytes (assumption: b64encode of 4 bytes will be 8 bytes due to the automatic padding feature).


    s.sendall(f)


s.close()

服务器:


import socket

import numpy as np

import cv2

import base64


s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

s.bind(("127.0.0.1", 60124))

s.listen(5)

c, a = s.accept()


while True:

    # Read 8 bytes that tells the length of encoded image to be expected.

    data = c.recv(8)


    if len(data) != 8:

        break


    # Decode f_len from base64

    f_len = base64.decodebytes(data)


    # Convet from array of 4 bytes to integer value.

    f_len = int.from_bytes(f_len, byteorder='little')


    #f = c.recv(1024)

    # Receive the encoded image.

    data = c.recv(f_len)


    if len(data) != f_len:

        break


    #x = base64.decodebytes(data)  # Decode base64

    #x = np.fromstring(x , np.uint8)

    x = np.fromstring(data, np.uint8)

    var = cv2.imdecode(x, cv2.IMREAD_COLOR)


    if var is None:

        print('Invalid image')

    else:

        cv2.imshow("Camera" , var)

        cv2.waitKey(100)


s.close()

cv2.destroyAllWindows()


查看完整回答
反对 回复 2022-10-05
  • 1 回答
  • 0 关注
  • 85 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信