【问题标题】:How to send OpenCV frame over RabbitMQ to process by OpenCV on a server如何通过 RabbitMQ 发送 OpenCV 帧以由服务器上的 OpenCV 处理
【发布时间】:2020-07-15 09:57:31
【问题描述】:

我在客户端 PC 上有一个 Python 应用程序,它使用 OpenCV 测试移动。我想将通过 RabbitMQ 捕获的 OpenCV 帧发送到服务器,以便服务器可以测试帧中是否存在人员。

我让它工作,通过将帧转换为 jpg,对 jpg 进行 base64 编码,通过队列发送,并在另一端进行 base64 解码,然后保存文件。然后可以在服务器上查看 jpg。然后我可以使用 cv2.imread('captured.jpg') 将 jpg 加载到服务器上的 OpenCV 并测试是否存在一个人。

我现在想避免将 jpg 保存到磁盘并将其重新加载到服务器上的 Python 中。但我似乎无法将消息队列正文内容加载到 OpenCV 中。下面是发送内容的客户端代码,然后是处理内容的服务器代码(减去分析帧的检测器API函数)。

retval, image = camera.read()
retval, buffer = cv2.imencode('.jpg', image)
jpgb64 = base64.b64encode(buffer)
properties = pika.BasicProperties(app_id='motion', content_type='image/jpg', reply_to=self.ENVIRON["clientName"])
connection = pika.BlockingConnection(self.parameters )
channel = connection.channel()
channel.basic_publish(exchange='', routing_key='Central', body=jpgb64, properties=properties)
connection.close()



def callback(ch, method, properties, body):
    imgbin = base64.b64decode(body)
    with open('captured.jpg', 'wb') as f_output:
        f_output.write(imgbin)
    frame = cv2.imread('captured.jpg')
    dt = detector.detectorAPI()
    result = dt.objectCount(frame)
    print(result)

我尝试不在客户端转换为 jpg,而只是发送转换为 base64 的 OpenCV 帧。但是在服务器上对其进行解码后,我无法让 OpenCV 将其识别为“框架”。我假设 OpenCV 帧是一种特殊的数据类型,而我只是得到一个二进制对象,这不一样。但这只是一个猜测,我不知道如何解决这个问题。

如何从客户端发送捕获的 OpenCV 帧,以便服务器上的 OpenCV 能够像处理服务器本身捕获的帧一样处理它?

【问题讨论】:

    标签: python opencv rabbitmq


    【解决方案1】:

    我不使用RabbitMQ,但我相信你可以发送二进制数据,所以我不知道你为什么对你的数据进行base64编码以发送它并在接收端解码。您应该可以发送从cv2.imencode() 返回的buffer,它会更快更简单。

    在接收端,你可以将接收到的消息转换成一个Numpy数组,然后解码回原来的帧,这样不用去磁盘:

    # Convert received message into Numpy array
    jpg = np.frombuffer(RECEIVEDMESSAGE, dtype=np.uint8)
    
    # JPEG-decode back into original frame - which is actually a Numpy array
    im = cv2.imdecode(jpg, cv2.IMREAD_UNCHANGED)
    

    【讨论】:

    • 谢谢。但是当我取出 base64 转换时,发布到 MQ 失败。不知道为什么,因为二进制是正文可接受的格式。除此之外,在对另一端的主体进行base64解码之后,我应该有同样的东西。然后当我应用上面的两个建议时,我的服务器组件失败了。上面的两行是否可能顺序错误?
    • 我认为可能是base64解码后我没有缓冲区对象......
    • 是的,解码后的结果对象是字节。但这似乎无关紧要,因为以下代码行有效: frame = cv2.imdecode(np.frombuffer(img_binary, np.uint8), -1) 与您的建议非常相似。 cv2.IMREAD_UNCHANGED = -1 吗?如果是这样,也许我最初遇到了代码错误。将接受您的解决方案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-03-19
    • 2011-04-23
    • 2018-11-27
    • 2017-05-23
    • 1970-01-01
    • 1970-01-01
    • 2018-01-22
    相关资源
    最近更新 更多