您的位置:首页 > 房产 > 家装 > 商标设计logo网站_最新新闻热点事件摘抄及评论_黄页88网推广服务_设计网站大全

商标设计logo网站_最新新闻热点事件摘抄及评论_黄页88网推广服务_设计网站大全

2025/4/21 1:57:00 来源:https://blog.csdn.net/pengxiang1998/article/details/147124346  浏览:    关键词:商标设计logo网站_最新新闻热点事件摘抄及评论_黄页88网推广服务_设计网站大全
商标设计logo网站_最新新闻热点事件摘抄及评论_黄页88网推广服务_设计网站大全

当我们使用YOLO检测器得到检测结果后,我们如何计算检测的物体距离相机的位置呢?
目前,有三种较为主流的距离计算方法,分别是单目测距、双目测距以及基于深度估计的测距方法。

单目测距

工作原理:单目测距使用一个摄像头来估计物体的距离。由于只有一个视角,无法直接计算深度信息,因此单目测距依赖于一些假设或先验知识,如物体的尺寸、颜色、纹理等特征。

优点: 简单且成本低。 易于部署和维护。
缺点: 准确度较低,因为缺乏直接的空间信息。 对环境和目标物体有特定要求,例如需要知道物体的实际大小。

应用场景:常用于简单场景下的距离估算,比如在已知背景环境中跟踪移动对象。

借助YOLO目标检测方法,计算检测到的物体距离:

from ultralytics import YOLO
import cv2# 已知参数:不同类别的真实宽度(单位:米)
KNOWN_WIDTHS = {0: 0.5,  # 均压环1: 0.5,  # 复合绝缘子2: 0.06,   # 挂点金具3: 0.5,   # 玻璃绝缘子4: 0.2,   # 连接金具5: 1,   # '避雷器6: 0.2,   # 防震锤
}# 不同类别的颜色(BGR 格式)
COLORS = {0: (0, 255, 0),  # 绿色1: (255, 0, 0),  # 蓝色2: (0, 0, 255),   # 红色3: (0, 225, 255),   # 红色4: (0, 128, 255),   # 红色5: (128, 0, 255),   # 红色6: (3, 0, 128)   # 红色
}# 相机焦距(单位:像素)
FOCAL_LENGTH = 4032def calculate_distance(known_width, focal_length, pixel_width):"""根据目标的真实宽度、相机焦距和目标在图像中的像素宽度,计算目标与相机的距离。"""return (known_width * focal_length) / pixel_widthdef adjust_exposure(image):"""使用CLAHE技术调整图像的曝光度。"""# 将图像转换为Lab色彩空间,以便单独处理亮度通道lab_image = cv2.cvtColor(image, cv2.COLOR_BGR2LAB)l_channel, a_channel, b_channel = cv2.split(lab_image)# 应用CLAHE到L通道clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))cl = clahe.apply(l_channel)# 合并处理后的L通道和其他两个通道updated_lab_image = cv2.merge((cl, a_channel, b_channel))# 将Lab图像转换回BGR色彩空间adjusted_image = cv2.cvtColor(updated_lab_image, cv2.COLOR_LAB2BGR)return adjusted_imagedef adjust_exposure(image):"""使用CLAHE技术调整图像的曝光度。"""# 将图像转换为Lab色彩空间,以便单独处理亮度通道lab_image = cv2.cvtColor(image, cv2.COLOR_BGR2LAB)l_channel, a_channel, b_channel = cv2.split(lab_image)# 应用CLAHE到L通道clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))cl = clahe.apply(l_channel)# 合并处理后的L通道和其他两个通道updated_lab_image = cv2.merge((cl, a_channel, b_channel))# 将Lab图像转换回BGR色彩空间adjusted_image = cv2.cvtColor(updated_lab_image, cv2.COLOR_LAB2BGR)return adjusted_image# 加载模型
model = YOLO("D:\project_mine\detection/ultralytics/runs\detect/train2\weights/best.pt")  # 预训练的 YOLO11n 模型# 读取原始图像
original_img = cv2.imread("images/test2.JPG")# 创建一个副本用于显示(调整曝光度)
adjusted_img = adjust_exposure(original_img.copy())# 使用调整后的图像进行目标检测
results = model(adjusted_img)  # 使用调整后的图像进行推理# 处理结果
for result in results:# 在原始图像上获取边界框坐标 (x1, y1, x2, y2)boxes = result.boxes  # 获取边界框对象cls_list = result.boxes.cls  # 获取类别 ID 列表for box, cls in zip(boxes, cls_list):cls = int(cls)  # 转换为整数类别 ID# 获取边界框坐标 (x1, y1, x2, y2)x1, y1, x2, y2 = map(int, box.xyxy[0])  # 提取单个边界框的坐标# 计算目标在原始图像中的宽度(像素)pixel_width = x2 - x1# 根据类别获取真实宽度known_width = KNOWN_WIDTHS.get(cls, 0.1)  # 默认宽度为 0.1 米(如果类别未定义)# 计算目标与相机的距离if pixel_width > 0:  # 确保像素宽度有效distance = calculate_distance(known_width, FOCAL_LENGTH, pixel_width)# 根据类别获取颜色color = COLORS.get(cls, (255, 255, 255))  # 默认颜色为白色# 在调整后的图像上绘制检测框cv2.rectangle(adjusted_img, (x1, y1), (x2, y2), color, 2)# 构造标注文本label = f"Class {cls}, Dist: {distance:.2f}m"# 计算文字放置位置(置于框内中心位置偏上一点)text_size, _ = cv2.getTextSize(label, cv2.FONT_HERSHEY_SIMPLEX, 0.9, 2)text_x = x1 + (x2 - x1 - text_size[0]) // 2  # 文字X坐标:框内居中text_y = y1 + (y2 - y1) // 2  # 文字Y坐标:框内垂直居中# 在检测框中央添加标注信息cv2.putText(adjusted_img, label, (text_x, text_y), cv2.FONT_HERSHEY_SIMPLEX, 0.9, color, 2)else:print(f"无法计算距离:类别 {cls} 的目标宽度无效")# 保存带有标注的图片cv2.imwrite("调整曝光测距.jpg", adjusted_img)

双目测距

工作原理:双目测距模仿人类视觉系统,使用两个摄像头同时拍摄同一场景,通过比较两幅图像中的差异(视差)来计算每个点的深度信息。视差越大,物体越近;反之亦然。

优点: 相对准确,能够提供较为精确的深度信息。 不需要预先知道物体的具体信息。
缺点: 需要精确校准两个摄像头的位置关系。在低纹理区域或遮挡情况下性能下降。 成本较高,因为需要两个高质量的摄像头。

应用场景:适用于自动驾驶汽车、机器人导航等领域,其中精确的距离测量至关重要。

import cv2
import numpy as np
from ultralytics import YOLO# 辅助函数:计算距离
def calculate_distance(disparity, focal_length, baseline):"""根据视差计算目标距离"""return (focal_length * baseline) / disparity# 辅助函数:查找视差(简化实现)
def find_disparity(center_x, center_y, left_img, right_img):"""通过左右图像匹配点计算视差"""# 提取左图像和右图像的特征区域(简化实现:直接比较灰度值)gray_left = cv2.cvtColor(left_img, cv2.COLOR_BGR2GRAY)gray_right = cv2.cvtColor(right_img, cv2.COLOR_BGR2GRAY)# 固定搜索范围(假设目标不会偏离太多)search_range = 50  # 搜索范围为 50 像素min_error = float('inf')best_match_x = center_xfor offset in range(-search_range, search_range + 1):match_x = center_x + offsetif 0 <= match_x < gray_right.shape[1]:error = np.sum(np.abs(gray_left[center_y, center_x] - gray_right[center_y, match_x]))if error < min_error:min_error = errorbest_match_x = match_x# 视差为水平位移disparity = abs(center_x - best_match_x)return disparity# 假设已知的参数
FOCAL_LENGTH =448 # 焦距(单位为像素)
BASELINE = 0.03    # 基线长度(单位为米)
model = YOLO("yolo11n.pt")  # 预训练的 YOLO11n 模型
#model = YOLO("D:\project_mine\detection/ultralytics/runs\detect/train2\weights/best.pt")
# 读取左右图像
left_img = cv2.imread("images/right.jpg")
right_img = cv2.imread("images/left.jpg")# 使用调整后的左图像进行目标检测
results = model(left_img)  # 使用 YOLO 模型进行推理# 处理结果
for result in results:boxes = result.boxes  # 获取边界框对象for box in boxes:# 获取边界框坐标 (x1, y1, x2, y2)x1, y1, x2, y2 = map(int, box.xyxy[0])  # 提取单个边界框的坐标# 计算目标在左图像中的中心点center_x = (x1 + x2) // 2center_y = (y1 + y2) // 2# 在右图像中寻找对应的匹配点(简化实现:假设同一行)disparity = find_disparity(center_x, center_y, left_img, right_img)if disparity > 0:  # 确保视差有效# 计算目标与相机的距离distance = calculate_distance(disparity, FOCAL_LENGTH, BASELINE)# 在调整后的左图像上绘制检测框color = (0, 255, 0)  # 固定颜色为绿色cv2.rectangle(left_img, (x1, y1), (x2, y2), color, 2)# 构造标注文本label = f"Dist: {distance:.2f}m"# 计算文字放置位置(置于框内中心位置偏上一点)text_size, _ = cv2.getTextSize(label, cv2.FONT_HERSHEY_SIMPLEX, 0.9, 2)text_x = x1 + (x2 - x1 - text_size[0]) // 2  # 文字X坐标:框内居中text_y = y1 + (y2 - y1) // 2  # 文字Y坐标:框内垂直居中# 在检测框中央添加标注信息cv2.putText(left_img, label, (text_x, text_y), cv2.FONT_HERSHEY_SIMPLEX, 0.9, color, 2)else:print("无法计算距离:视差无效")# 保存带有标注的图片
cv2.imwrite("left_with_annotations.jpg", left_img)

在这里插入图片描述

深度估计测距

工作原理:深度估计通常是基于深度学习的方法,利用神经网络从单一图像或立体图像中预测出每个像素对应的深度值。这种方法可以被视为一种高级形式的单目测距,但它不依赖于具体的物理测量,而是通过学习大量的标记数据来“理解”图像中的深度线索。

优点: 可以从单张图像中推断出深度信息,灵活性高。 随着模型训练数据量的增加和技术进步,准确性不断提高。
缺点:计算资源需求大,尤其是在实时应用中。 模型训练复杂,需要大量的标注数据。

应用场景:广泛应用于增强现实(AR)、虚拟现实(VR)、3D重建等需要高精度深度信息的领域。
下面这个是借助 torch 中自带的 MiDaS深度估计模型进行距离测算。

import cv2
import torch
from ultralytics import YOLO# 加载 YOLO11 模型
yolo_model_path = "yolo11n.pt"  # 替换为您的 YOLO11 模型路径
yolo_model = YOLO(yolo_model_path)# 加载深度估计模型(例如 MiDaS)
midas_model_type = "MiDaS_small"  # 可选模型类型
midas = torch.hub.load("intel-isl/MiDaS", midas_model_type)
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
midas.to(device)
midas.eval()# 预处理变换
transform = torch.hub.load("intel-isl/MiDaS", "transforms")
if midas_model_type == "DPT_Large":transform = transform.dpt_transform
else:transform = transform.small_transform# 标定参数(根据实验调整)
scale_factor = 100  # 根据标定得到的比例因子
offset = 2.0         # 根据标定得到的偏移量# 打开视频流
cap = cv2.VideoCapture(0)  # 使用摄像头,或者替换为视频文件路径
cv2.namedWindow("YOLO11 Depth Estimation")while cap.isOpened():ret, frame = cap.read()if not ret:print("无法读取视频帧!")break# 使用 YOLO11 进行目标检测results = yolo_model(frame)annotated_frame = results[0].plot()  # 绘制检测结果# 使用 MiDaS 进行深度估计input_batch = transform(frame).to(device)with torch.no_grad():prediction = midas(input_batch)prediction = torch.nn.functional.interpolate(prediction.unsqueeze(1),size=frame.shape[:2],mode="bicubic",align_corners=False,).squeeze()depth_map = prediction.cpu().numpy()depth_map = cv2.normalize(depth_map, None, 0, 255, cv2.NORM_MINMAX, dtype=cv2.CV_8U)# 对每个检测到的目标计算距离for box in results[0].boxes:x1, y1, x2, y2 = map(int, box.xyxy[0])  # 获取边界框坐标center_x, center_y = (x1 + x2) // 2, (y1 + y2) // 2  # 计算中心点depth_value = depth_map[center_y, center_x]  # 获取中心点的深度值distance = (scale_factor / (depth_value + offset)) # 计算实际距离# 在图像上绘制距离信息cv2.circle(annotated_frame, (center_x, center_y), 5, (0, 0, 255), -1)  # 标记中心点cv2.putText(annotated_frame, f"{distance:.2f}m", (x1, y1 - 20),cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 255, 0), 1)# 显示结果cv2.imshow("YOLO11 Depth Estimation", annotated_frame)# 按下 'q' 键退出if cv2.waitKey(1) & 0xFF == ord('q'):break# 释放资源
cap.release()
cv2.destroyAllWindows()

总结

相较而言,单目测距依赖与经验值,而深度估计测距则依赖模型性能,综上双目测距的方式无论是在速度方面还是精度方面都能有较好的表现。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com