项目名称
基于YOLO的单目测距系统
项目描述
本项目旨在开发一个基于YOLO(You Only Look Once)深度学习模型的单目测距系统。该系统不仅能够识别目标物体,还能估算出目标与摄像机之间的距离。系统支持对多种目标(如人、车等)的距离测量,适用于多个应用场景,如智能交通系统、机器人导航、安防监控等。
关键功能
-
目标检测:
- 利用YOLO模型对图像中的目标进行检测,并标注出目标的位置。
-
距离估算:
- 通过目标检测的结果,结合已知的目标尺寸和摄像机参数,估算目标与摄像机之间的距离。
-
多目标支持:
- 系统能够支持多种目标类型的测距,包括但不限于行人、车辆等。
-
用户界面:
- 可选的图形用户界面,使用户能够直观地看到检测结果和测距信息。
-
实时检测:
- 支持从摄像头实时捕获图像并进行目标检测与距离估算。
-
离线检测:
- 用户可以从本地文件系统中上传单张或多张图片进行批量检测与测距。
技术栈
- YOLO模型:用于目标检测的核心模型。
- Python:项目的主要编程语言。
- OpenCV:用于图像处理和摄像头流的捕获。
- PyQt5 或 Pyside6:用于构建图形用户界面(可选)。
- 深度学习框架:如PyTorch或TensorFlow,用于模型训练和推理。
这个为原理(单目测距):
以下是一个简化的代码示例,展示如何使用YOLO模型进行目标检测,并基于检测结果进行单目测距。
1. 目标检测与距离估算
关键代码示例
首先,加载YOLO模型,并定义一个函数来进行目标检测和距离估算。
1import torch
2import cv2
3import numpy as np
4
5# 加载YOLO模型
6model = torch.hub.load('ultralytics/yolov5', 'custom', path='path/to/object_detection_model.pt') # 请替换为你的模型路径
7
8def detect_objects_and_estimate_distance(image, known_widths={'person': 1.7, 'car': 4.5}):
9 """
10 Detect objects in the given image and estimate their distance from the camera.
11
12 Args:
13 image (numpy.ndarray): The input image.
14 known_widths (dict): Dictionary mapping object labels to their known widths in meters.
15
16 Returns:
17 list: List of tuples containing (label, bounding box, distance).
18 """
19 results = model(image)
20 detections = results.pandas().xyxy[0]
21
22 # 摄像机焦距
23 focal_length = calculate_focal_length(known_widths['person'], 100) # 假设已知的人的宽度为1.7米,在100米处的像素宽度
24
25 objects_with_distance = []
26 for index, row in detections.iterrows():
27 label = row['name']
28 bbox = [int(row['xmin']), int(row['ymin']), int(row['xmax']), int(row['ymax'])]
29 width_in_pixels = bbox[2] - bbox[0]
30 if label in known_widths:
31 distance = (known_widths[label] * focal_length) / width_in_pixels
32 objects_with_distance.append((label, bbox, distance))
33
34 return objects_with_distance
35
36def calculate_focal_length(known_width, distance):
37 """
38 Calculate the focal length of the camera using a known width at a known distance.
39
40 Args:
41 known_width (float): The known width of an object in meters.
42 distance (float): The known distance of the object from the camera in meters.
43
44 Returns:
45 float: The calculated focal length in pixels.
46 """
47 # 假设在距离distance处,已知宽度为known_width的对象在图像中的宽度为100像素
48 return distance * 100 / known_width
2. 实时检测与测距
接下来,构建一个实时检测与测距的脚本,该脚本从摄像头捕获图像,并展示检测结果和测距信息。
1import time
2
3def main():
4 cap = cv2.VideoCapture(0) # 使用默认摄像头
5
6 while True:
7 ret, frame = cap.read()
8 if not ret:
9 break
10
11 objects_with_distance = detect_objects_and_estimate_distance(frame)
12
13 for obj in objects_with_distance:
14 label, bbox, distance = obj
15 cv2.rectangle(frame, (bbox[0], bbox[1]), (bbox[2], bbox[3]), (0, 255, 0), 2)
16 cv2.putText(frame, f'{label}: {distance:.2f}m', (bbox[0], bbox[1] - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 255, 0), 2)
17
18 cv2.imshow('Object Detection and Distance Estimation', frame)
19
20 if cv2.waitKey(1) & 0xFF == ord('q'):
21 break
22
23 cap.release()
24 cv2.destroyAllWindows()
25
26if __name__ == '__main__':
27 main()
用户界面示例(使用PyQt5)
以下是一个使用PyQt5构建的GUI示例,允许用户选择上传图片或使用摄像头进行目标检测与测距。
python
深色版本
1import sys
2from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QVBoxLayout, QWidget, QFileDialog, QLabel, QSlider, QSpinBox
3from PyQt5.QtGui import QImage, QPixmap
4from PyQt5.QtCore import QTimer
5
6class ObjectDetectionApp(QMainWindow):
7 def __init__(self):
8 super().__init__()
9 self.setWindowTitle('Object Detection and Distance Estimation')
10 self.setGeometry(100, 100, 800, 600)
11
12 self.central_widget = QWidget()
13 self.setCentralWidget(self.central_widget)
14
15 self.layout = QVBoxLayout()
16 self.central_widget.setLayout(self.layout)
17
18 self.image_label = QLabel()
19 self.layout.addWidget(self.image_label)
20
21 self.button_layout = QVBoxLayout()
22
23 self.camera_button = QPushButton('Use Camera')
24 self.camera_button.clicked.connect(self.use_camera)
25 self.button_layout.addWidget(self.camera_button)
26
27 self.file_button = QPushButton('Upload File')
28 self.file_button.clicked.connect(self.upload_file)
29 self.button_layout.addWidget(self.file_button)
30
31 self.layout.addLayout(self.button_layout)
32
33 self.cap = None
34 self.timer = QTimer()
35 self.timer.timeout.connect(self.update_frame)
36
37 def use_camera(self):
38 self.cap = cv2.VideoCapture(0) # 使用默认摄像头
39 self.timer.start(30) # 每30毫秒更新一次图像
40
41 def upload_file(self):
42 file_name, _ = QFileDialog.getOpenFileName(self, 'Open Image File', '', 'Image Files (*.jpg *.jpeg *.png)')
43 if file_name:
44 img = cv2.imread(file_name)
45 self.detect_objects_and_estimate_distance(img)
46
47 def detect_objects_and_estimate_distance(self, image):
48 objects_with_distance = detect_objects_and_estimate_distance(image)
49 for obj in objects_with_distance:
50 label, bbox, distance = obj
51 cv2.rectangle(image, (bbox[0], bbox[1]), (bbox[2], bbox[3]), (0, 255, 0), 2)
52 cv2.putText(image, f'{label}: {distance:.2f}m', (bbox[0], bbox[1] - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 255, 0), 2)
53
54 # 将OpenCV图像转换为QPixmap以便在QLabel中显示
55 height, width, channel = image.shape
56 bytes_per_line = 3 * width
57 q_img = QImage(image.data, width, height, bytes_per_line, QImage.Format_RGB888).rgbSwapped()
58 pixmap = QPixmap.fromImage(q_img)
59 self.image_label.setPixmap(pixmap)
60
61 def update_frame(self):
62 ret, frame = self.cap.read()
63 if ret:
64 self.detect_objects_and_estimate_distance(frame)
65
66 def closeEvent(self, event):
67 if self.cap is not None:
68 self.cap.release()
69 self.timer.stop()
70 event.accept()
71
72if __name__ == '__main__':
73 app = QApplication(sys.argv)
74 window = ObjectDetectionApp()
75 window.show()
76 sys.exit(app.exec_())
说明
- YOLO模型:确保已经加载了预训练的YOLO模型,并且该模型已经被训练用于检测目标对象。
- 单目测距:通过目标检测的结果,结合已知的目标尺寸和摄像机参数,估算目标与摄像机之间的距离。
- PyQt5 GUI:构建了一个简单的用户界面,允许用户选择使用摄像头或上传图片进行检测。界面中包含一个用于显示检测结果的图像区域。
- 视频处理:当用户选择使用摄像头后,程序会读取视频流并通过YOLO模型进行目标检测和距离估算。检测结果会在图像中标注出来,并在界面上展示。
总结
此基于YOLO的单目测距系统通过结合YOLO模型和单目测距算法,实现了对目标物体的检测和距离估算。系统提供了用户友好的界面,使得用户可以方便地选择使用摄像头或上传图片进行检测,并查看检测结果。该系统适用于多种应用场景,如智能交通系统、机器人导航、安防监控等。