Вопрос или проблема
Мне удалось извлечь часть данных из JSON-загрузки из mqtt [BCID и Местоположение]. Моя проблема заключается в том, как это визуализировать? Я продолжаю получать ошибки, такие как «недопустимая аппаратная инструкция», «cv2.error: Неизвестное исключение C++ из кода OpenCV» и т. д.
- Мои характеристики: MacOS Big Sur Version 11.7.10
#визуализировать местоположение
#ПРЕВРАЩЕНО В ПИКСЕЛИ!
import cv2
from pathlib import Path
import uuid
import ssl
import json
from dotenv import dotenv_values
from paho.mqtt.client import Client
from paho.mqtt.enums import CallbackAPIVersion
import numpy as np
IMAGE_SIZE = 1080 # Размер изображения (1080x1080)
class Visualizer:
def visualize():
print()
class MQTTClient:
"""MQTTClient"""
def __init__(self, broker_url: str, port: int, topics: dict, **kwargs):
self.broker_url = broker_url
self.port = port
self.topics = topics
self.client = Client(
CallbackAPIVersion.VERSION2, f"visualizer-{str(uuid.uuid4()).split('-')[4]}"
)
self.client.tls_set(
ca_certs=None,
certfile=None,
keyfile=None,
cert_reqs=ssl.CERT_NONE,
tls_version=ssl.PROTOCOL_TLSv1_2,
)
if {"broker_user", "broker_pass"}.issubset(kwargs):
self.client.username_pw_set(kwargs["broker_user"], kwargs["broker_pass"])
self.client.on_connect = self.on_connect
self.client.on_message = self.on_message
def start(self):
"""Подключается к брокеру и создает фоновый поток для ожидания сообщений."""
self.client.connect(self.broker_url, port=self.port, keepalive=60)
self.client.subscribe([(topic, 0) for topic in self.topics])
self.client.loop_start()
def on_connect(self, client, userdata, connect_flags, reason_code, properties):
"""Обратный вызов при подключении к брокеру."""
if reason_code == 0:
print(f"Подключение к брокеру MQTT успешно: {self.broker_url}")
else:
print(f"Ошибка при подключении к брокеру MQTT: {reason_code}")
def on_message(self, client, userdata, msg):
"""Обратный вызов при получении сообщения."""
data = json.loads(msg.payload.decode("utf-8"))
location = data['outputs'][0]['location']
pixel_coordinates = convert_to_pixels(location)
print(f"BCID: {data['outputs'][0]['bcid']} Координаты пикселей: {pixel_coordinates}")
def convert_to_pixels(location):
"""
Преобразовать нормализованные координаты местоположения в пиксельные координаты.
Args:
location (list): Нормализованные координаты [xmin, ymin, xmax, ymax].
Returns:
list: Пиксельные координаты в изображении 1080x1080 [xmin_px, ymin_px, xmax_px, ymax_px].
"""
# Масштабировать и преобразовать нормализованные координаты в пиксельные координаты 1080x1080
# Нормализованный диапазон предполагается как [-1.0, 1.0]
xmin, ymin, xmax, ymax = location
# Отображение нормализованных координат [-1.0, 1.0] на [0, IMAGE_SIZE]
xmin_px = int((xmin + 1) * IMAGE_SIZE / 2)
ymin_px = int((ymin + 1) * IMAGE_SIZE / 2)
xmax_px = int((xmax + 1) * IMAGE_SIZE / 2)
ymax_px = int((ymax + 1) * IMAGE_SIZE / 2)
return [xmin_px, ymin_px, xmax_px, ymax_px]
CONFIG = dotenv_values(Path.cwd() / ".env")
BROKER_URL = CONFIG["MQTT_BROKER"]
BROKER_USER = CONFIG["MQTT_USER"] if "MQTT_USER" in CONFIG else ""
BROKER_PASS = CONFIG["MQTT_PASS"] if "MQTT_PASS" in CONFIG else ""
PORT = 8883
TOPICS = ["/viana/+/ze_all_tracks"]
def main():
client = MQTTClient(BROKER_URL, PORT, TOPICS)
client.start()
input()
if __name__ == "__main__":
main()
Я пробовал множество способов визуализировать данные, многие из них не поддерживают мою ОС. Я пытался использовать XQuartz, но это также оказалось неэффективным и неподдерживаемым согласно моему терминалу. Я также пробовал matplotlib, но это тоже не работает.
Ответ или решение
Для визуализации данных MQTT с использованием OpenCV на Python, приведем полное решение вашей проблемы, включая советы по устранению возможных ошибок. Мы будем использовать OpenCV, чтобы нарисовать прямоугольник на изображении, основываясь на координатах, полученных из MQTT-сообщений.
Шаг 1: Устранение ошибок OpenCV
Похоже, что вы сталкиваетесь с ошибками, связанными с OpenCV. Убедитесь, что у вас установлена последняя стабильная версия OpenCV, совместимая с вашей операционной системой. Вы можете установить его с помощью следующей команды:
pip install opencv-python
Шаг 2: Создание функции для визуализации данных
Добавим функцию визуализации, которая будет рисовать прямоугольник на изображении:
class Visualizer:
def __init__(self):
# Создаем пустое черное изображение 1080x1080
self.image = np.zeros((IMAGE_SIZE, IMAGE_SIZE, 3), dtype=np.uint8)
def visualize(self, pixel_coordinates):
"""Визуализируем данные на изображении"""
xmin_px, ymin_px, xmax_px, ymax_px = pixel_coordinates
# Рисуем прямоугольник на изображении
cv2.rectangle(self.image,
(xmin_px, ymin_px),
(xmax_px, ymax_px),
(0, 255, 0), # Цвет прямоугольника (зеленый)
2) # Толщина прямоугольника
# Отображаем изображение
cv2.imshow("Visualization", self.image)
cv2.waitKey(1) # Обновляем окно
Шаг 3: Обновление класса MQTTClient
Теперь мы обновим класс MQTTClient
, чтобы интегрировать Visualizer
и вызывать его функцию визуализации при получении сообщения:
class MQTTClient:
def __init__(self, broker_url: str, port: int, topics: dict, **kwargs):
# ... [остальной код как прежде] ...
self.visualizer = Visualizer()
def on_message(self, client, userdata, msg):
data = json.loads(msg.payload.decode("utf-8"))
location = data['outputs'][0]['location']
pixel_coordinates = convert_to_pixels(location)
print(f"BCID: {data['outputs'][0]['bcid']} Pixel Coordinates: {pixel_coordinates}")
self.visualizer.visualize(pixel_coordinates) # вызов функции визуализации
Шаг 4: Тестирование
После завершения изменения кода запустите скрипт. При поступлении новых данных вы увидите обновляющееся окно OpenCV с прямоугольниками, визуализирующими границы объектов на изображении.
Замечания и рекомендации
-
Закрытие окна: Не забудьте добавить логику для закрытия окна OpenCV (например, с помощью
cv2.destroyAllWindows()
), когда вы завершаете выполнение программы. -
Проверка данных: Убедитесь, что данные, которые вы получаете через MQTT, правильно форматированы и существуют. Это поможет избежать ошибок на этапе анализа JSON.
-
Использование Matplotlib: Если вы также хотите попробовать Matplotlib, вы можете заменить
cv2.imshow
на Matplotlib, но OpenCV обычно более оптимален для обновления изображений в режиме реального времени.
Заключение
Теперь у вас есть полное решение для визуализации данных MQTT с использованием OpenCV на Python. Простое обновление вашего кода с учетом вышеприведенных шагов должно устранить ошибки и обеспечить визуализацию данных. Если возникнут дополнительные вопросы, не стесняйтесь задавать их!