pyqtyolov7可视化界面
时间: 2025-07-01 20:07:06 浏览: 4
### 使用 PyQt 创建 YOLOv7 可视化界面
YOLOv7 是一款先进的实时目标检测算法,在性能上超越了许多现有的模型。为了提高用户体验并将其集成到图形用户界面上,可以利用 PyQt 构建直观的应用程序[^1]。
#### 准备工作
首先安装必要的依赖项:
```bash
pip install pyqt5 opencv-python-headless ultralytics
```
接着准备基础的 Python 文件结构来组织项目文件夹中的资源和脚本。
#### 主窗口布局设计
定义主应用类 `MainWindow` 并继承自 `QMainWindow` 类型,设置基本属性以及初始化组件实例变量。通过垂直盒式管理器 (`VBoxLayout`) 和水平盒式管理器 (`HBoxLayout`) 实现控件排列逻辑;同时加入按钮、标签等部件完成初步UI搭建[^2]。
```python
import sys
from PyQt5.QtCore import Qt, QTimer
from PyQt5.QtWidgets import (QApplication, QMainWindow, QLabel,
QVBoxLayout, QWidget, QPushButton,
QHBoxLayout, QMessageBox, QFileDialog)
from PyQt5.QtGui import QImage, QPixmap, QIcon
import cv2
from ultralytics import YOLO
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle('YOLOv7 Object Detection with PyQt')
self.setGeometry(100, 100, 800, 600)
central_widget = QWidget()
layout = QVBoxLayout()
# Add widgets to the layout here...
button_layout = QHBoxLayout() # Horizontal box for buttons
open_button = QPushButton("Open Image", self)
detect_button = QPushButton("Detect Objects", self)
quit_button = QPushButton("Quit", self)
button_layout.addWidget(open_button)
button_layout.addWidget(detect_button)
button_layout.addWidget(quit_button)
layout.addLayout(button_layout)
self.image_label = QLabel(self)
layout.addWidget(self.image_label)
central_widget.setLayout(layout)
self.setCentralWidget(central_widget)
if __name__ == '__main__':
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
```
上述代码片段展示了如何建立一个带有三个操作按键的基础框架——打开图片、执行物体识别任务及退出程序,并预留了一个用于呈现图像数据的空间位置给后续处理流程做铺垫。
#### 加载预训练好的 YOLOv7 模型
加载由 Ultralytics 提供支持的官方版本 YOLOv7 预训练权重文件,以便可以直接调用其预测方法获取检测框坐标信息和其他元数据作为输出结果的一部分。
```python
def load_model():
model_path = 'yolov7.pt' # Replace this path according to your actual file location.
return YOLO(model_path)
```
此函数负责读取本地磁盘上的 `.pt` 扩展名格式保存下来的 PyTorch checkpoint 数据集,从而恢复整个神经网络架构及其参数配置状态至内存之中待命使用。
#### 图像上传与显示功能实现
当点击“Open Image”按钮时触发事件处理器函数 `_open_image()` ,该函数会弹出对话框让用户挑选一张想要分析的照片素材,之后再经过 OpenCV 库转换成适合渲染的形式最终呈现在界面上方预留出来的区域里。
```python
def _open_image(self):
options = QFileDialog.Options()
fileName, _ = QFileDialog.getOpenFileName(
None,
"Select an image",
"",
"Images (*.png *.jpg *.jpeg);;All Files (*)",
options=options
)
if not fileName:
return
try:
img = cv2.imread(fileName)
height, width, channel = img.shape
bytesPerLine = 3 * width
qImg = QImage(img.data, width, height, bytesPerLine, QImage.Format_RGB888).rgbSwapped()
pixmap = QPixmap.fromImage(qImg)
self.image_label.setPixmap(pixmap.scaledToWidth(780))
except Exception as e:
msgBox = QMessageBox()
msgBox.setIcon(QMessageBox.Critical)
msgBox.setText(f"Error opening {fileName}: {str(e)}")
msgBox.exec_()
```
这段代码实现了从硬盘选取特定路径下的静态图档后立即更新 UI 上对应部分的内容刷新动作,确保每次交互都能及时反馈最新的视觉效果变化情况给前端使用者观察确认。
#### 物体检测过程封装
最后一步就是编写核心业务逻辑即启动推理引擎的部分了。每当按下 “Detect Objects” 键位就会激活关联的方法去调用之前已经准备好就绪等待命令下达的对象探测服务接口,进而取得标注好边界矩形坐标的返回值集合列表形式传递回来进一步加工处理成为可被绘制成图形元素的信息表达方式。
```python
model = load_model()
def perform_detection(self):
global model
current_pixmap = self.image_label.pixmap()
if current_pixmap is None or current_pixmap.isNull():
msgBox = QMessageBox()
msgBox.setIcon(QMessageBox.Warning)
msgBox.setText("No image loaded.")
msgBox.exec_()
return
original_img = current_pixmap.toImage().convertToFormat(QImage.Format_RGB888)
processed_img = np.array(original_img.constBits()).reshape(original_img.height(), original_img.width(), 3)
results = model(processed_img)[0].cpu().numpy()
annotated_frame = draw_boxes_on_image(results, processed_img.copy())
h, w, ch = annotated_frame.shape
bytes_per_line = ch * w
convert_to_Qt_format = QImage(annotated_frame.tobytes(), w, h, bytes_per_line, QImage.Format_RGB888)
p = convert_to_Qt_format.rgbSwapped()
self.image_label.setPixmap(QPixmap.fromImage(p))
def draw_boxes_on_image(result_dict, frame_copy):
"""Draw bounding boxes on a copy of the input image."""
for detection in result_dict['boxes']:
x_min, y_min, x_max, y_max = map(int, detection[:4])
label = f"{detection[-1]}"
color = tuple(map(int, [np.random.randint(0, 255) for _ in range(3)]))
thickness = 2
font_scale = 0.5
text_thickness = 1
offset_x, offset_y = 5, 5
cv2.rectangle(frame_copy, (x_min, y_min), (x_max, y_max), color=color, thickness=thickness)
(text_width, text_height), baseline = cv2.getTextSize(label, cv2.FONT_HERSHEY_SIMPLEX
阅读全文
相关推荐
















