【问题标题】:python receive image over socketpython通过套接字接收图像
【发布时间】:2017-02-25 22:35:06
【问题描述】:

我正在尝试通过套接字发送图像 - 我正在使用 pycam 在我的树莓派上捕获图像,发送到远程机器进行处理,然后发回响应。

在服务器(pi)上,我正在捕获图像、转换为数组、重新排列为一维数组并使用 tostring() 方法。

在服务器上,接收到的字符串长度不同。关于这里出了什么问题的任何想法?附上我运行的代码,以及服务端和客户端的输出

服务器代码:

from picamera.array import PiRGBArray
from picamera import PiCamera
import socket
import numpy as np
from time import sleep
import sys

camera = PiCamera()
camera.resolution = (640,480)

rawCapture = PiRGBArray(camera)

s = socket.socket()

host = 'myHost'
port = 12345
s.bind((host,port))
s.listen(1)
while True:
    c,addr = s.accept()

    signal = c.recv(1024)
    print 'received signal: ' + signal

    if signal == '1':
        camera.start_preview()
        sleep(2)

        camera.capture(rawCapture, format = 'bgr')
        image = rawCapture.array
        print np.shape(image)
        out = np.reshape(image,640*480*3)

        print out.dtype
        print 'sending file length: ' + str(len(out))

        c.send(str(len(out)))
        print 'sending file'
        c.send(out.tostring())


        print 'sent'

        c.close()
        break

客户代码:

import socket, pickle
import cv2
import numpy as np

host = '192.168.1.87'
port = 12345
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))

s.send('1')

#while true:
x = long(s.recv(1024))
rawPic = s.recv(x)

print 'Received'
print x

print len(rawPic)
type(rawPic)

#EDITED TO INCLUDE DTYPE
image = np.fromstring(rawPic,np.uint8)
s.close()

服务器输出:

received signal: 1
(480, 640, 3)
uint8
sending file length: 921600
sending file

客户端输出:

Received
921600
27740
str

ValueError                                Traceback (most recent call last)
<ipython-input-15-9c39eaa92454> in <module>()
----> 1 image = np.fromstring(rawPic)

ValueError: string size must be a multiple of element size

我想知道问题是否是我在 uint8 上调用 tostring(),如果 fromstring() 假设它是 uint32?我不明白为什么收到的字符串比发送的要小得多。

编辑 似乎由于某种原因,服务器没有完全发送文件。它从不打印“已发送”,它应该在完成时执行。如果我将发送行更改为:

c.send(str(len(out[0:100])))
print 'sending file'
c.send(out[0:100].tostring())

一切正常。想到什么可能会在中途切断我发送的文件?

【问题讨论】:

    标签: python sockets opencv raspberry-pi


    【解决方案1】:

    解码为正确的类型

    当您调用tostring() 时,数据类型(和形状)信息会丢失。您必须为 numpy 提供您期望的数据类型。

    例如:

    import numpy as np
    
    image = np.random.random((50, 50)).astype(np.uint8)
    image_str = image.tostring()
    
    # Works
    image_decoded = np.fromstring(image_str, np.uint8)
    
    # Error (dtype defaults to float)
    image_decoded = np.fromstring(image_str)
    

    恢复形状

    如果形状总是固定的,你可以这样做

    image_with_proper_shape = np.reshape(image_decoded, (480, 640, 3))
    

    在客户端中。

    否则,您必须在消息中包含形状信息,以便在客户端中进行解码。

    【讨论】:

    • 感谢您的回复 - 我修改了上面的代码 - 包括 dtype 没有任何区别,结果字符串的长度仍然是 27740,而发送的字符串是 921600
    • 嗯,我错过了。在 socket.recv(bufsize) 中,bufsizs 是要侦听的最大字节数,因此您在客户端中的第一个 recv 调用可能会丢弃消息的其余部分。因为网络是不可预测的,所以你不能指望一个 socket.send() 与一个 socket.recv() 完全对应。字节将以正确的顺序到达,但可能与发送者的分组方式不同。尝试 recv(..., socket.MSG_WAITALL) 其中 ... 是整个消息、标头和所有内容的长度。
    猜你喜欢
    • 2014-03-25
    • 1970-01-01
    • 2023-03-05
    • 1970-01-01
    • 2019-01-26
    • 2022-01-18
    • 2014-08-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多