• 通过 MQTT 检测对象和传输图像


    ef3f073dc0d3de1bea887bb8e6f681be.png

    在本文中,我们将学习如何使用 open-cv 和 YOLO 对象检测器每五秒捕获/保存和检测图像中的对象。然后我们将图像转换为字节数组并通过 MQTT 发布,这将在另一个远程设备上接收并保存为 JPG。

    我们将使用 YoloV3 算法和一个免费的 MQTT 代理

    YoloV3 算法:https://viso.ai/deep-learning/yolov3-overview/#:~:text=What's%20Next%3F-,What%20is%20YOLOv3%3F,Joseph%20Redmon%20and%20Ali%20Farhadi.

    MQTT 代理:https://www.emqx.com/

    在我们继续之前,我假设你具备以下基本知识:

    · OpenCV:https://opencv.org/about/#:~:text=OpenCV%20(Open%20Source%20Computer%20Vision,perception%20in%20the%20commercial%20products.

    · NumPy:https://numpy.org/doc/stable/user/whatisnumpy.html

    · MQTT:https://mqtt.org/getting-started/

    第 1 节 — 发布

    让我们首先在我们的第一台设备上编写 Python 脚本,该设备将充当监控系统。

    安装:

    · pip install opencv-python

    · pip install numpy

    · pip install paho-mqtt

    如果你在安装 opencv 时仍然遇到问题,请遵循以下文章

    · 在 Windows上安装:https://docs.opencv.org/3.4/d5/de5/tutorial_py_setup_in_windows.html

    · 在 Ubuntu上安装:https://docs.opencv.org/3.4/d2/de6/tutorial_py_setup_in_ubuntu.html

    我们还需要下载一些文件(YoloV3 的预训练权重、配置文件和名称文件)。

    从以下链接下载它们

    • Yolov3.weights:https://pjreddie.com/media/files/yolov3.weights

    • Yolov3.cfg:https://github.com/pjreddie/darknet/blob/master/cfg/yolov3.cfg

    • coco.names:https://github.com/pjreddie/darknet/blob/master/data/coco.names

    (确保以上 3 个下载的文件与 sendImage.py 保存在同一目录下)

    在 IDE 中创建一个新文件并将文件保存为 sendImage.py

    从导入所需的模块开始

    1. import paho.mqtt.client as mqtt
    2. import paho.mqtt.publish as publish
    3. import cv2
    4. import numpy as np
    5. import time

    我们现在将为代理和图像初始化变量

    1. broker = "broker.emqx.io"
    2. port = 1883
    3. timelive=60
    4. image_name="capture.jpg"

    我们的第一个函数将捕获/保存图像,并调用 process_image() 函数

    1. def save_image():
    2.     #cv2.VideoCapture(0) this can be 012 depending on your device id
    3.     videoCaptureObject = cv2.VideoCapture(0)
    4.     ret, frame = videoCaptureObject.read()
    5.     cv2.imwrite(image_name, frame)
    6.     videoCaptureObject.release()
    7.     process_image()

    process_image() 函数是所有魔法发生的地方。

    1. def process_image():
    2.     boxes = []
    3.     confs = []
    4.     class_ids = []
    5.     #loading the YoloV3 weights and configuration file using the open-cv dnn module
    6.     net = cv2.dnn.readNet("yolov3.weights""yolov3.cfg")
    7.     #storing all the trained object names from the coco.names file in the list names[]
    8.     names = []
    9.     with open("coco.names""r") as n:
    10.         names = [line.strip() for line in n.readlines()]
    11.     #running a foward pass by passing the names of layers of the output to be computed by net.getUnconnectedOutLayersNames()
    12.     output_layers = [layer_name for layer_name in net.getUnconnectedOutLayersNames()]
    13.     colors = np.random.uniform(0255, size=(len(names), 3))
    14.     #reading  the image from the image_name variable (Same image which was saved by the save_image function)
    15.     image = cv2.imread(image_name)
    16.     height, width, channels = image.shape
    17.     #using blobFromImage function to preprocess the data
    18.     blob = cv2.dnn.blobFromImage(image, scalefactor=0.00392, size=(160160), mean=(000))
    19.     net.setInput(blob)
    20.     #getting X/Y cordinates of the object detected, scores for all the classes of objects in coco.names where the predicted object is class with the highest score, height/width of bounding box
    21.     outputs = net.forward(output_layers)
    22.     for output in outputs:
    23.         for check in output:
    24.             #this list scores stores confidence for each corresponding object
    25.             scores = check[5:]
    26.             #np.argmax() gets the class index with highest score which will help us get the name of the class for the index from the names list
    27.             class_id = np.argmax(scores)
    28.             conf = scores[class_id]
    29.             #predicting with a confidence value of more than 40%
    30.             if conf > 0.4:
    31.                 center_x = int(check[0] * width)
    32.                 center_y = int(check[1] * height)
    33.                 w = int(check[2] * width)
    34.                 h = int(check[3] * height)
    35.                 x = int(center_x - w / 2)
    36.                 y = int(center_y - h / 2)
    37.                 boxes.append([x, y, w, h])
    38.                 confs.append(float(conf))
    39.                 class_ids.append(class_id)
    40.     #drawing bounding boxes and adding labels while removing duplicate detection for same object using non-maxima suppression
    41.     indexes = cv2.dnn.NMSBoxes(boxes, confs, 0.50.5)
    42.     font = cv2.FONT_HERSHEY_PLAIN
    43.     for i in range(len(boxes)):
    44.         if i in indexes:
    45.             x, y, w, h = boxes[i]
    46.             label = str(names[class_ids[i]])
    47.             color = colors[i]
    48.             cv2.rectangle(image, (x, y), (x + w, y + h), color, 2)
    49.             cv2.putText(image, label, (x, y - 5), font, 1, color, 1)
    50.     #resizing and saving the the image
    51.     width = int(image.shape[1] * 220 / 100)
    52.     height = int(image.shape[0] * 220 / 100)
    53.     dim = (width, height)
    54.     resized = cv2.resize(image, dim, interpolation=cv2.INTER_AREA)
    55.     cv2.imwrite('processed.jpg', resized)
    56.     
    57.     #reading the image and converting it to bytearray
    58.     f = open("processed.jpg""rb")
    59.     fileContent = f.read()
    60.     byteArr = bytes(fileContent)
    61.     #topic to publish for our MQTT
    62.     TOPIC = "IMAGE"
    63.     client = mqtt.Client()
    64.     #connecting to the MQTT broker
    65.     client.connect(broker, port, timelive)
    66.     #publishing the message with bytearr as the payload and IMAGE as topic
    67.     publish.single(TOPIC, byteArr, hostname=broker)
    68.     print("Published")

    启动 save_image 函数并每 5 秒调用一次的最后几行代码

    1. while True:
    2.     save_image()
    3.     time.sleep(5)

    第 2 节 — 订阅

    现在让我们在第二个设备上编写第二个脚本,该脚本将用于下载和查看通过 MQTT 接收的检测到的对象文件

    安装:

    · pip install paho-mqtt

    在 IDE 中创建一个新文件并将文件保存为 receiveImage.py

    从导入所需的模块开始

    import paho.mqtt.client as mqtt

    为代理初始化变量

    1. broker = "broker.emqx.io"
    2. port = 1883
    3. timelive = 60

    使用 on_connect() 函数连接代理并订阅主题 IMAGE

    1. def on_connect(client, userdata, flags, rc):
    2.     print("Connected with result code " + str(rc))
    3.     #subscribe to the topic IMAGE, this is the same topic which was used to published the image on the previous device
    4.     client.subscribe("IMAGE")

    编写 on_message() 函数以在收到有效负载后立即保存文件

    1. def on_message(client, userdata, msg):
    2.     #create/open jpg file [detected_objects.jpg] to write the received payload
    3.     f = open('detected_objects.jpg'"wb")
    4.     f.write(msg.payload)
    5.     f.close()

    连接到代理并通过无限循环开始监听传入消息的根函数

    1. def mqtt_sub():
    2.     client = mqtt.Client()
    3.     client.connect(broker, port, timelive)
    4.     client.on_connect = on_connect
    5.     client.on_message = on_message
    6.     client.loop_forever()

    启动脚本的最后一行代码

    mqtt_sub()

    每隔5秒,你就会在脚本文件所在的目录中刷新名称为' detected_objects.jpg '的JPG图像。

    就是这样。我们创建了一个监控系统,每 5 秒捕获一次图像,检测其中的物体,并使用 MQTT 通过互联网发送图像。

    ☆ END ☆

    如果看到这里,说明你喜欢这篇文章,请转发、点赞。微信搜索「uncle_pn」,欢迎添加小编微信「 woshicver」,每日朋友圈更新一篇高质量博文。

    扫描二维码添加小编↓

    490b2d2abf7357f72fe22470addf12aa.png

  • 相关阅读:
    设计模式(一):面向对象基础、单一职责原则、开放封闭原则和依赖反转原则
    JAVA设计模式 —— 工厂模式
    [valgrind] 安装与使用
    AMEYA360:永铭固液混合铝电解电容帮助企业级固态硬盘稳定运行
    Python和RPA之间的区别和联系
    springboot基于微信小程序的在线办公系统+java+uinapp+Mysql+计算机毕业设计
    【题解】同济线代习题一.7
    【BM2 链表内指定区间反转】
    MFC中LISTCONTROL控件的相关操作
    【数据结构】单链表
  • 原文地址:https://blog.csdn.net/woshicver/article/details/125476703