【问题标题】:Python MQTT Publish JSONified Numpy ArrayPython MQTT 发布 JSONified Numpy 数组
【发布时间】:2018-11-19 10:05:52
【问题描述】:

我目前正在实现在两个树莓派之间使用的 MQTT 协议。第一个是 Pi 0,将连接一个 pi 相机。它将每个捕获的帧转换为 numpy 数组,然后将其发布到主 Pi,然后使用 PIL 将 numpy 数组转换为图像。我这样做是因为我希望在主 Pi 上执行主要的图像处理操作。

我的问题是主 Pi 没有收到任何消息。我已经进行了调试,并且在服务脚本上一切正常。但是由于某种原因,主 Pi 没有收到任何内容。

这是两个脚本:

servant.py:

import paho.mqtt.client as mqtt
import time
import cv2
import numpy
import json

MQTT_SERVER = "iot.eclipse.org"
MQTT_PATH = "test_channel"

mqttc = mqtt.Client()
mqttc.connect(MQTT_SERVER, 1883, 60)

cap = cv2.VideoCapture(0)

while True:
    ret, frame = cap.read()
    frame_list = frame.tolist()
    MQTT_MESSAGE = json.dumps(frame_list)
    mqttc.publish(MQTT_PATH, MQTT_MESSAGE)
    time.sleep(1)

ma​​ster.py:

import paho.mqtt.client as mqtt
import numpy as np
import json
import PIL

MQTT_SERVER = "iot.eclipse.org"
MQTT_PATH = "test_channel"

def on_connect(client, userdata, flags, rc):
    print("connected with result code " + str(rc))
    client.subscribe(MQTT_PATH)

def on_message(client, userdata, msg):
    data = json.loads(msg.payload)
    array = np.array(data)
    img = PIL.Image.fromarray(array)
    cv2.imshow('image', img)
    cv2.waitKey()

client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
client.connect(MQTT_SERVER, 1883, 60)

client.loop_forever()

【问题讨论】:

  • 你需要解释你的尝试,只是说“我已经进行了调试”并没有帮助
  • 另外,您通过调用cv2.waitKey() 阻止了on_message,这意味着整个订阅者将在处理第一条消息时锁定,直到您按下一个键。您不应阻止消息处理。
  • 不需要在您的客户端中调用mqttc.loop_start()(或在您的for循环中定期调用loop)?
  • @hardillb 抱歉,我没有指定确切的调试技术,但我认为这是多余的,因为仆人脚本运行良好。但是,为了回答你的问题,我在servant.py 上做了一些日志记录,数据正在被正确处理并且是jsonified。我还制作了一个虚拟的 numpy 数组,它实际上已经通过并发布了。但是由于某种原因,当我使用 opencv 时它停止工作。再次,即使在servant.py 上使用opencv 一切正常,发布是问题。
  • @hardillb 至于您的建议,我删除了该行,但仍然没有任何显示。甚至不要认为这是问题所在,因为我使用 print 语句快速调试了它,on_message 方法的第一行,msg.payload 的值没有打印出来。这意味着在发布和 on_message 之间的某个地方出了点问题。

标签: python numpy raspberry-pi mqtt


【解决方案1】:

在您的发布代码中,您实际上并没有给客户端任何时间来处理它尝试发送的消息。这甚至是一个更大的问题,因为消息可能比单个网络数据包(作为图像)大。要解决此问题,您必须调用 MQTT 客户端循环函数(或在 b

import paho.mqtt.client as mqtt
import time
import cv2
import numpy
import json

MQTT_SERVER = "iot.eclipse.org"
MQTT_PATH = "test_channel"

mqttc = mqtt.Client()
mqttc.connect(MQTT_SERVER, 1883, 60)

cap = cv2.VideoCapture(0)

while True:
    ret, frame = cap.read()
    frame_list = frame.tolist()
    MQTT_MESSAGE = json.dumps(frame_list)
    mqttc.publish(MQTT_PATH, MQTT_MESSAGE)
    mqttc.loop()
    time.sleep(1)

或者像这样:

import paho.mqtt.client as mqtt
import time
import cv2
import numpy
import json

MQTT_SERVER = "iot.eclipse.org"
MQTT_PATH = "test_channel"

mqttc = mqtt.Client()
mqttc.connect(MQTT_SERVER, 1883, 60)

cap = cv2.VideoCapture(0)

mqttc.start_loop()

while True:
    ret, frame = cap.read()
    frame_list = frame.tolist()
    MQTT_MESSAGE = json.dumps(frame_list)
    mqttc.publish(MQTT_PATH, MQTT_MESSAGE)
    time.sleep(1)

【讨论】:

  • 非常感谢,再问一个问题,您认为这是一种好的做事方式还是有更轻量级的做事方式?实际上,在我的真实脚本中,我将在servant.py 上安装pi 相机模块,而不是opencv。将图像字节流式传输到主服务器会比我目前的方式更高效、更快吗?
  • 但问题依然存在。我删除了等待键并为客户端添加了循环,但主服务器仍然没有收到任何内容。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-07
  • 1970-01-01
  • 1970-01-01
  • 2022-07-06
相关资源
最近更新 更多