Python 3.x 通过MQTT将图像作为numpy阵列发送到AWS IoT核心
我正在从网络摄像头捕获图像,并使用AWS物联网设备Python SDK将这些图像作为numpy阵列发送到AWS物联网核心。在AWS物联网核心,该numpy阵列被传输至lamda功能,用于图像处理(通过RESNET模型) 但numpy阵列的大小太大,无法通过MQTT发送,这就是为什么AWS IoT Core不接收它的原因 所以我的问题是:Python 3.x 通过MQTT将图像作为numpy阵列发送到AWS IoT核心,python-3.x,amazon-web-services,image-processing,mqtt,aws-iot,Python 3.x,Amazon Web Services,Image Processing,Mqtt,Aws Iot,我正在从网络摄像头捕获图像,并使用AWS物联网设备Python SDK将这些图像作为numpy阵列发送到AWS物联网核心。在AWS物联网核心,该numpy阵列被传输至lamda功能,用于图像处理(通过RESNET模型) 但numpy阵列的大小太大,无法通过MQTT发送,这就是为什么AWS IoT Core不接收它的原因 所以我的问题是: 有没有办法增加SDK中的MQTT TX缓冲区大小?我找不到 如果没有,那么通过MQTT发送并接收大numpy阵列的最佳方式是什么 发布代码: cam =
cam = cv2.VideoCapture(0)
ret, frame = cam.read()
message['image'] = frame.tolist() #numpy array converted to list to make it work with json.dumps
messageJson = json.dumps(message)
myAWSIoTMQTTClient.publish(topic, messageJson, 0)
帧numpy数组:
[0:480] :[array([[156, 168, 20...ype=uint8), array([[155, 167, 20...ype=uint8), array([[144, 168, 20...ype=uint8), array([[144, 168, 20...ype=uint8), array([[138, 168, 20...ype=uint8), array([[138, 168, 20...ype=uint8), array([[149, 170, 20...ype=uint8), array([[151, 172, 20...ype=uint8), array([[156, 174, 20...ype=uint8), array([[156, 174, 20...ype=uint8), array([[153, 174, 20...ype=uint8), array([[152, 173, 20...ype=uint8), array([[153, 172, 20...ype=uint8), array([[154, 173, 20...ype=uint8), ...]
dtype:dtype('uint8')
max:222
min:0
shape:(480, 640, 3)
size:921600
你好像有点卡住了。我不知道AWS方面的事情,但可以告诉你成像方面。我建议您将图像
帧
(是一个Numpy数组)转换为JPEG图像进行传输,因为这样会占用较少的带宽并产生较小的MQTT消息。然而,JPEG是二进制的,所以除非先对其进行base64编码,否则不能将其作为JSON发送。在下面的示例中,我展示了一种拍摄图像的方法(Numpy数组)和:
- 将其转换为JPEG格式。请注意,您可以同样使用PNG—特别是如果您想要无损的话—但通常速度会较慢。注意:您同样可以使用PIL/Pillow而不是OpenCV。请注意,您也可以改变质量,这将影响大小
- base64编码它
- 转换为JSON
#!/usr/bin/env python3
import cv2
import numpy as np
from base64 import b64encode
# Get any old image, 640x480 pixels - corresponds to your "frame"
na = cv2.imread('start.jpg', cv2.IMREAD_COLOR)
print(f'DEBUG: Size as Numpy array: {na.nbytes}')
# Convert to "in-memory" JPEG
_, JPEG = cv2.imencode(".jpg", na, [int(cv2.IMWRITE_JPEG_QUALITY), 80])
print(f'DEBUG: Size as JPEG: {JPEG.nbytes}')
JPEG.tofile('DEBUG-original.jpg')
# Base64 encode
b64 = b64encode(JPEG)
print(f'DEBUG: Size as base64: {len(b64)}')
print(f'DEBUG: Start of base64: {b64[:32]}...')
# JSON-encode
message = { "image": b64.decode("utf-8") }
messageJSON = json.dumps(message)
print(f'DEBUG: Start of JSON: {messageJSON[:32]}')
样本输出
DEBUG: Size as Numpy array: 921600
DEBUG: Size as JPEG: 49456
DEBUG: Size as base64: 65944
DEBUG: Start of base64: b'/9j/4AAQSkZJRgABAQAAAQABAAD/2wBD'...
DEBUG: Start of JSON: {"image": "/9j/4AAQSkZJRgABAQAAA
接收器端将如下所示:
### RECEIVER: All variables suffixed with '_r' to denote receiver ###
import cv2
import numpy as np
from base64 import b64decode
# Extract base64 from JSON
b64_r = json.loads(messageJSON)
# Extract JPEG-encoded image from base64-encoded string
JPEG_r = b64decode(b64_r["image"])
# Decode JPEG back into Numpy array
na_r = cv2.imdecode(np.frombuffer(JPEG_r,dtype=np.uint8), cv2.IMREAD_COLOR)
注意:如果要转换为灰度,则需要在JPEG编码之前执行此操作:
# Convert to greyscale
grey = cv2.cvtColor(na, cv2. COLOR_BGR2GRAY)
# JPEG-encode
_, JPEG = cv2.imencode(".jpg", grey, [int(cv2.IMWRITE_JPEG_QUALITY), 80])
关键词:Python、MQTT、AWS、图像处理、JSON、base64、编码、解码、带宽、最小化、最小化、减少、素数。阵列有多大?MQTT的最大有效负载大小为256mb,AWS可能有较小的限制。我已经添加了质疑中的数组信息。是的,但是在转换为JSON后,它有多大?我们已经是5mb的纯原始字节,将其转换为JSON表示可以轻松增加一个或多个数量级。您还可以利用JPEG压缩并发送JPEG图像并将其重新膨胀到接收端的Numpy阵列吗?这可能是该尺寸的十分之一,或更小。或者你能用一半大小的YUV吗?非常感谢!我真的被这个问题困住了。您的解决方案非常有效。很酷-很高兴它对您有效。祝你的项目好运!如果你再次陷入困境,请回来。问题和答案是免费的:-)