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

通过 MQTT 检测对象和传输图像_第1张图片

在本文中,我们将学习如何使用 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

从导入所需的模块开始

import paho.mqtt.client as mqtt
import paho.mqtt.publish as publish
import cv2
import numpy as np
import time

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

broker = "broker.emqx.io"
port = 1883
timelive=60
image_name="capture.jpg"

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

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

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

def process_image():
    boxes = []
    confs = []
    class_ids = []

    #loading the YoloV3 weights and configuration file using the open-cv dnn module
    net = cv2.dnn.readNet("yolov3.weights", "yolov3.cfg")

    #storing all the trained object names from the coco.names file in the list names[]
    names = []
    with open("coco.names", "r") as n:
        names = [line.strip() for line in n.readlines()]

    #running a foward pass by passing the names of layers of the output to be computed by net.getUnconnectedOutLayersNames()
    output_layers = [layer_name for layer_name in net.getUnconnectedOutLayersNames()]
    colors = np.random.uniform(0, 255, size=(len(names), 3))

    #reading  the image from the image_name variable (Same image which was saved by the save_image function)
    image = cv2.imread(image_name)
    height, width, channels = image.shape

    #using blobFromImage function to preprocess the data
    blob = cv2.dnn.blobFromImage(image, scalefactor=0.00392, size=(160, 160), mean=(0, 0, 0))
    net.setInput(blob)

    #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
    outputs = net.forward(output_layers)
    for output in outputs:
        for check in output:
            #this list scores stores confidence for each corresponding object
            scores = check[5:]

            #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
            class_id = np.argmax(scores)
            conf = scores[class_id]
            #predicting with a confidence value of more than 40%
            if conf > 0.4:
                center_x = int(check[0] * width)
                center_y = int(check[1] * height)
                w = int(check[2] * width)
                h = int(check[3] * height)
                x = int(center_x - w / 2)
                y = int(center_y - h / 2)
                boxes.append([x, y, w, h])
                confs.append(float(conf))
                class_ids.append(class_id)

    #drawing bounding boxes and adding labels while removing duplicate detection for same object using non-maxima suppression
    indexes = cv2.dnn.NMSBoxes(boxes, confs, 0.5, 0.5)
    font = cv2.FONT_HERSHEY_PLAIN
    for i in range(len(boxes)):
        if i in indexes:
            x, y, w, h = boxes[i]
            label = str(names[class_ids[i]])
            color = colors[i]
            cv2.rectangle(image, (x, y), (x + w, y + h), color, 2)
            cv2.putText(image, label, (x, y - 5), font, 1, color, 1)

    #resizing and saving the the image
    width = int(image.shape[1] * 220 / 100)
    height = int(image.shape[0] * 220 / 100)
    dim = (width, height)
    resized = cv2.resize(image, dim, interpolation=cv2.INTER_AREA)
    cv2.imwrite('processed.jpg', resized)
    
    #reading the image and converting it to bytearray
    f = open("processed.jpg", "rb")
    fileContent = f.read()
    byteArr = bytes(fileContent)

    #topic to publish for our MQTT
    TOPIC = "IMAGE"
    client = mqtt.Client()

    #connecting to the MQTT broker
    client.connect(broker, port, timelive)

    #publishing the message with bytearr as the payload and IMAGE as topic
    publish.single(TOPIC, byteArr, hostname=broker)
    print("Published")

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

while True:
    save_image()
    time.sleep(5)

第 2 节 — 订阅

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

安装:

· pip install paho-mqtt

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

从导入所需的模块开始

import paho.mqtt.client as mqtt

为代理初始化变量

broker = "broker.emqx.io"
port = 1883
timelive = 60

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

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

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

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

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

def mqtt_sub():
    client = mqtt.Client()
    client.connect(broker, port, timelive)
    client.on_connect = on_connect
    client.on_message = on_message
    client.loop_forever()

启动脚本的最后一行代码

mqtt_sub()

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

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

☆ END ☆

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

扫描二维码添加小编↓

通过 MQTT 检测对象和传输图像_第2张图片

你可能感兴趣的:(python,opencv,vnc,cv,opengl)