0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

把YOLOv11和Python Qt做个用户界面程序

安费诺传感器学堂 来源:安费诺传感器学堂 2024-11-28 10:18 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

早些时间,小编想把PID控制器优化部分通过Py Qt来实现用户界面化,不过看着窗口一堆参数,有点发怵:这玩意谁用啊?

9e185014-a936-11ef-93f3-92fbcf53809c.png

参考《PID控制器参数自动优化示例和比较》

后来就搁置了。 在通过Python以及YOLO来检测图中或者视频中的各种物体以及人物的时候,就会考虑:全部用代码来输出的?怎么通过一个简单直观的窗口界面来测试相应的功能?我觉得要再试一下,哪怕是最简单的方式呈现。这便是这篇文章的目的所在。 我们通过YOLO现成的各种检测模块,实现:

图中物体的识别检测

检出物体的区域分割

人体姿态的检测

还有其他的检测功能,感觉功能有重叠,就选了上面的三个功能简单地集成到一个windows的因为分类的功能只是软件界面中。 以下图片均有AI生成,但是人体姿态检测的结果可能看不清楚输出。

按照我们之前的惯例,先提供结果,后提供代码。

9e83512a-a936-11ef-93f3-92fbcf53809c.png

[1]物体检测

9eb9e1f4-a936-11ef-93f3-92fbcf53809c.png

[2]物体分割

9efb1868-a936-11ef-93f3-92fbcf53809c.png

[3]姿态检测

我们可以自己尝试运行一下。

# This program is part of a project developed by Amphenol Sensors.
#Copyright(C)2024,Leo Lu
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .


import sys
from PyQt5.QtWidgets import (QApplication, QLabel, QPushButton, QVBoxLayout, QWidget, 
                             QFileDialog, QComboBox, QHBoxLayout)
from PyQt5.QtGui import QPixmap, QImage
from PyQt5.QtCore import Qt
import cv2
import numpy as np
import random


from ultralytics import YOLO
from ultralytics.models.yolo.pose.predict import PosePredictor


class YOLOInterface(QWidget):
    def __init__(self):
        super().__init__()


        self.initUI()
        self.model_detec = YOLO('./yolo_models/yolo11s.pt')
        self.model_seg = YOLO('./yolo_models/yolo11s-seg.pt')
        self.model_bd = './yolo_models/yolo11s-pose.pt'
        self.connections = ((2, 4), (1, 3), (10, 8), (8, 6), (6, 5), (5, 7), (7, 9), 
                            (6, 12), (12, 14), (14, 16), (5, 11), (11, 13), (13, 15))


    def initUI(self):
        self.setWindowTitle('YOLO 图像检测')
        self.setGeometry(100, 100, 1200, 600)
        self.setFixedSize(1200, 600)
        # 主布局
        main_layout = QVBoxLayout()


        # 图像显示布局
        image_layout = QHBoxLayout()


        self.image_label = QLabel(self)
        self.image_label.setFixedSize(600, 400)
        self.image_label.setAlignment(Qt.AlignCenter)
        image_layout.addWidget(self.image_label)


        self.result_label = QLabel(self)
        self.result_label.setFixedSize(600, 400)
        self.result_label.setAlignment(Qt.AlignCenter)
        image_layout.addWidget(self.result_label)


        main_layout.addLayout(image_layout)


        # 控制布局
        control_layout = QHBoxLayout()


        self.detect_button = QPushButton('选择图片', self)
        self.detect_button.clicked.connect(self.load_image)
        control_layout.addWidget(self.detect_button)


        self.yolo_combo = QComboBox(self)
        self.yolo_combo.addItems(['物体检测', '物体分割', '人体姿态识别'])  # 假设在此处添加不同的YOLO任务
        control_layout.addWidget(self.yolo_combo)


        self.run_button = QPushButton('开始检测', self)
        self.run_button.clicked.connect(self.run_yolo)
        control_layout.addWidget(self.run_button)


        self.quit_button = QPushButton('退出', self)
        self.quit_button.clicked.connect(self.close_application)
        control_layout.addWidget(self.quit_button)


        main_layout.addLayout(control_layout)
        self.setLayout(main_layout)


    def load_image(self):
        options = QFileDialog.Options()
        file_name, _ = QFileDialog.getOpenFileName(self, "选择图片文件", "", "Images (*.png *.jpg *.bmp)", options=options)
        if file_name:
            self.current_image = file_name
            pixmap = QPixmap(file_name)
            scaled_pixmap = pixmap.scaled(self.image_label.size(), Qt.KeepAspectRatio)
            self.image_label.setPixmap(scaled_pixmap)


    def plot_keypoints(self, image, keypoints, line_color=(60, 179, 113), point_color=(255, 0, 0),
                   offset=(0, 0), show_idx=False):
        if keypoints is None:
            return image
        
        for data in keypoints.xy:
            if len(data) == 0:
                continue
            # Draw connections between keypoints
            for start_index, end_index in self.connections:
                start_point, end_point = data[start_index], data[end_index]
                if all(start_point[:2] > 0) and all(end_point[:2] > 0):  # Ignore invalid points
                    cv2.line(image, 
                             tuple(map(lambda v, o: int(v + o), start_point[:2], offset)), 
                             tuple(map(lambda v, o: int(v + o), end_point[:2], offset)), 
                             line_color, 2)
            # Draw keypoints
            for index, (x, y) in enumerate(data[:, :2]):
                if x > 0 or y > 0:  # Ignore invalid points
                    cv2.circle(image, 
                               (int(x + offset[0]), int(y + offset[1])), 
                               5, point_color, -1)
                    if show_idx:
                        cv2.putText(image, 
                                    str(index), 
                                    (int(x + offset[0]), int(y + offset[1])), 
                                    cv2.FONT_HERSHEY_SIMPLEX, 0.5, point_color, 1, cv2.LINE_AA)
    
        return image


    def run_yolo(self):
        if hasattr(self, 'current_image'):
            img = cv2.imread(self.current_image)
            
            # YOLO推理示例:
            task = self.yolo_combo.currentText()
            if task =='物体检测':
                #model = self.model_detec #YOLO('yolo11s.pt')
                results = self.model_detec(img)
                
                for result in results:
                    boxes = result.boxes                # Pseudo-code; adjust based on actual library


                    for box in boxes:
                        x1, y1, x2, y2 = box.xyxy[0]    # Extracting the bounding box coordinates
                        class_name = self.model_detec.names[int(box.cls[0])]  # Using class_id to get class_name from model
                        confidence = box.conf.item()
                        cv2.rectangle(img, (int(x1), int(y1)), (int(x2), int(y2)), (0, 255, 0), 2)
                        txt_y_pos = int(y1) - 10
                        if txt_y_pos <= 10:
                            txt_y_pos = int(y2) - 10
                        
                        class_name = class_name + " "+ "{:.2g}".format(confidence)
                        cv2.putText(img, class_name, (int(x1), txt_y_pos), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 255, 0), 2)


            elif task =='物体分割':
                #model = YOLO('yolo11s-seg.pt')
                results = self.model_seg(img)
                
                # Prepare an overlay image with the same dimensions
                overlay = img.copy()
                
                for result in results:
                    boxes = result.boxes  # Pseudo-code; adjust based on actual library
                    masks = result.masks
                    names = result.names
                    for box, mask in zip(boxes, masks):
                        for cls, contour in zip(box.cls, mask.xy):
                            class_id = cls.item()  # Get scalar from tensor
                            class_name = names[class_id]
                            #print(class_name)
                            #print(cv2.contourArea(contour))  # Calculate contour area
                            
                            # Generate a random color
                            color = [random.randint(0, 255) for _ in range(3)]
                            
                            # Fill the contour on the overlay with the random color
                            cv2.drawContours(overlay, [contour.astype(np.int32)], -1, color, thickness=cv2.FILLED)
                # Define the alpha (transparency factor)
                alpha = 0.4  # Value between 0 (transparent) and 1 (opaque)
                
                # Blend the overlay with the original image
                """
                Parameters
                overlay (src1):


                This is the first input array (image).
                In your context, this represents the overlay image, which typically contains modifications like semi-transparent masks drawn over contours.
                
                alpha:
                This is the weight of the first array (image).
                It controls the opacity of the overlay. A value closer to 1 makes the overlay more prominent, while a value closer to 0 makes it less prominent.
                
                img (src2):
                This is the second input array (image).
                It represents the original image onto which the overlay is being applied.
                
                1 - alpha (beta):
                This is the weight of the second array (image).
                Complementary to alpha, it controls the visibility of the original image. A value closer to 1 makes the original image more visible, while closer to 0 makes it less visible.
                
                0 (gamma):
                A scalar added to each sum.
                Typically set to 0 when blending for direct overlay purposes without additional brightness adjustment.
                
                img (dst):
                The destination array where the output is stored.
                It uses the same variable as the original image, implying that the blended result will overwrite this variable.
                """
                cv2.addWeighted(overlay, alpha, img, 1 - alpha, 0, img)


            elif task == '人体姿态识别':
                #model = YOLO('yolo11s-pose.pt')
                #results = model(img)
                
                overrides_Body_pose = {
                    "task": "pose",
                    "mode": "predict",
                    "model": self.model_bd,        #'yolo11s-pose.pt'
                    "verbose": False,
                    "classes": [0],
                    "iou": 0.5,
                    "conf": 0.3
                    }


                predictor_ren_pose = PosePredictor(overrides=overrides_Body_pose)
                pose_ren = predictor_ren_pose(img)[0]
                
                img = self.plot_keypoints(img, pose_ren.keypoints)
                
            # Convert the image to a format suitable for PyQt
            height, width, channel = img.shape
            bytes_per_line = 3 * width
            q_image = QImage(img.data, width, height, bytes_per_line, QImage.Format_RGB888).rgbSwapped()
            pixmap = QPixmap.fromImage(q_image)
            self.display_results(pixmap)


    def display_results(self, pixmap):
        scaled_pixmap = pixmap.scaled(self.result_label.size(), Qt.KeepAspectRatio)
        self.result_label.setPixmap(scaled_pixmap)


    def close_application(self):
        self.close()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = YOLOInterface()
    ex.show()
    sys.exit(app.exec_())
小编甚至用它来检测一个AI生成的油画风格的图片。看图中哪些抽象的只有形态没有细节的人和物体,居然仍然可以检测出来。大家可以试一下看看检测的结果。

代码中涉及到的python软件包,需要额外安装,模型文件用的是YOLO现成的。小编把这个软件用打包工具生成的exe文件,因为攘括的软件多,简单的这些功能,打包后的文件压缩后的大小竟高达近900MB(分割压缩工具要收费咯),而很多平台不支持这么大的文件上传,所以这里也无法提供打包后的文件下载链接。

9f681a44-a936-11ef-93f3-92fbcf53809c.png

视线收回,我们心旷神怡一下。感谢AI的提供。

是否在怀疑这个世界的真实性?用传感器来检测一下吧,这个世界的冷热、正负压,振动,周围的空气......可以负责任地告诉各位,我们还是碳基生物。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 程序
    +关注

    关注

    117

    文章

    3847

    浏览量

    85454
  • PID控制器
    +关注

    关注

    2

    文章

    173

    浏览量

    19769
  • python
    +关注

    关注

    58

    文章

    4883

    浏览量

    90294

原文标题:把YOLOv11和Python Qt做个用户界面程序

文章出处:【微信号:安费诺传感器学堂,微信公众号:安费诺传感器学堂】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    直播 | 睿擎平台AMP混合部署:你的Qt界面如何“指挥”底层电机?

    )晚8点,我们将通过一场直播,这些问题一次性讲透。直播核心内容本次直播将以睿擎派RC3506J为硬件平台,完整演示从Qt界面开发到底层电机驱动的全流程:1、Qt
    的头像 发表于 03-03 19:33 567次阅读
    直播 | 睿擎平台AMP混合部署:你的<b class='flag-5'>Qt</b><b class='flag-5'>界面</b>如何“指挥”底层电机?

    直播预告 | 睿擎平台AMP混合部署:你的Qt界面如何“指挥”底层电机?

    )晚8点,我们将通过一场直播,这些问题一次性讲透。直播核心内容本次直播将以睿擎派RC3506J为硬件平台,完整演示从Qt界面开发到底层电机驱动的全流程:1、Qt
    的头像 发表于 02-27 18:18 351次阅读
    直播预告 | 睿擎平台AMP混合部署:你的<b class='flag-5'>Qt</b><b class='flag-5'>界面</b>如何“指挥”底层电机?

    RK3562 单板机图形用户界面开发完全手册:Qt Creator 配置与 LVGL 案例详解(二)

    程序自启动与 GPU 加速实现。通过图片显示、LED 控制等案例,明确关键代码与测试步骤。创龙科技以清晰实操指引,帮助开发者高效完成 Qt 图形界面开发,适用于工业控制、智能终端等场景。
    的头像 发表于 02-27 10:42 6284次阅读
    RK3562 单板机图形<b class='flag-5'>用户</b><b class='flag-5'>界面</b>开发完全手册:<b class='flag-5'>Qt</b> Creator 配置与 LVGL 案例详解(二)

    RK3562 单板机图形用户界面开发完全手册:Qt Creator 配置与 LVGL 案例详解(一)

    程序自启动与 GPU 加速实现。通过图片显示、LED 控制等案例,明确关键代码与测试步骤。创龙科技以清晰实操指引,帮助开发者高效完成 Qt 图形界面开发,适用于工业控制、智能终端等场景。
    的头像 发表于 02-26 11:41 1554次阅读
    RK3562 单板机图形<b class='flag-5'>用户</b><b class='flag-5'>界面</b>开发完全手册:<b class='flag-5'>Qt</b> Creator 配置与 LVGL 案例详解(一)

    那些年我用OpenCV+Qt趟过哪些坑?写给视觉应用开发者的避坑指南

    重写半套程序11. 复杂场景:多路视频实时检测的界面与线程架构设计,以及如何用“读写者模式”管理共享数据,避免资源竞争。 第三阶段:实战 - 在真实项目中融会贯通 懂再多道理,不如亲手实现一遍。我
    发表于 12-02 09:43

    yolov11转kmodel,numpy是要降级为1.x吗?

    python3.9,yolo是最新的稳定版,和yolo捆绑pip安装的numpy是2.0.1 错误日志
    发表于 08-11 08:16

    【米尔RK3506国产开发板评测试用】1、硬件介绍、SDK开发环境和QT开发环境搭建

    的mkspec配置的名称。 各个界面的相关配置项如下,Kit界面设置如下 编译器界面的配置如下 调试器界面的配置如下 QT选择
    发表于 08-02 15:02

    YOLOv8转换到kmodel时出现undefined symbol错误怎么解决?

    使用yolo v8训练视觉检测模型,使用yolov8版本为8.3.159,训练完后在windows使用ultralytics中的函数导出.pt文件为.onnx文件,然后在WSL
    发表于 07-28 06:20

    yolov5训练部署全链路教程

    1.Yolov5简介YOLOv5模型是Ultralytics公司于2020年6月9日公开发布的。YOLOv5模型是基于YOLOv3模型基础上改进而来的,有
    的头像 发表于 07-25 15:22 2018次阅读
    <b class='flag-5'>yolov</b>5训练部署全链路教程

    RK3576 Yolov11训练部署教程

    1.Yolo11简介YOLO11系列是YOLO家族中最先进的(SOTA)、最轻量级、最高效的模型,其表现优于其前辈。它由Ultralytics创建,该组织发布了YOLOv8,这是迄今为止最稳定
    的头像 发表于 07-25 15:22 1242次阅读
    RK3576 <b class='flag-5'>Yolov11</b>训练部署教程

    【Milk-V Duo S 开发板免费体验】5 - 使用YOLOv11进行目标检测

    引言 前面已经完成了Milk-V Duo S开发板的基本功能测试,今天来尝试一下使用YOLOv11进行目标检测。 TDL-SDK Cvitek 所提供的 TDL(Turnkey Deep
    发表于 07-24 14:57

    【米尔RK3576开发板免费体验】1、开发环境、镜像烧录、QT开发环境搭建以及应用部署

    指定由Buildroot产生的mkspec配置的名称。 各个界面的相关配置项如下,Kit界面设置如下 编译器界面的配置如下 调试器界面的配置如下
    发表于 07-14 11:26

    【HZ-RK3568开发板免费体验】04 YOLOv11 模型转换为RKNN并在板端部署

    程序自动将其保存为out.png,可以下载到电脑端查看,如下图 至此,YOLOv11的模型转换与部署就结束了,后面再研究视频推理。
    发表于 07-02 14:01

    瑞芯微RK3506(3核A7@1.5GHz+双网口+双CAN-FD)工业开发板—图形用户界面(GUI)开发手册

    本文主要说明Qt的图形用户界面(GUI)开发流程,包括Qt程序自启动配置与案例介绍,旨在帮助开发者完成产品开发与测试。
    的头像 发表于 06-03 14:27 1716次阅读
    瑞芯微RK3506(3核A7@1.5GHz+双网口+双CAN-FD)工业开发板—图形<b class='flag-5'>用户</b><b class='flag-5'>界面</b>(GUI)开发手册

    labview调用yolov8/11目标检测、分割、分类

    labview使用2020版本64位编辑,调用yolov8/11的onnx模型案例。 源码: 通过网盘分享的文件:Labview_cls.zip等4个文件 链接: https
    发表于 04-21 19:37