基于YOLO算法与intel深度相机三维测量(工件尺寸和物体尺寸)

目录

1.简介

 1.1 intel D4系列深度相机 (D455)

1.2 yolo算法

2.功能实现 

2.1构思:

2.2 主代码


这篇文章还是接着前面的几篇文章的项目延申,这个是最初的方案,因为太贵被否了。

1.简介

 1.1 intel D4系列深度相机 (D455)

Intel RealSense D435、D455等D4系列:

Intel D4系列深度相机是由英特尔(Intel)公司推出的一款深度感知摄像头,专为实现计算机视觉和深度学习应用而设计。这款相机使用了英特尔的深度感知技术,结合了摄像头和红外(IR)传感器,可以提供高质量的深度图像和 RGB 彩色图像,为开发者提供了丰富的数据源,用于各种应用,包括虚拟现实(VR)、增强现实(AR)、手势识别、人脸识别、姿势识别、3D 扫描等。

以下是Intel D4系列深度相机的一些主要特点和优势:
1. 深度感知技术:
D4系列相机具备高质量的深度感知功能,能够获取场景中各个物体的精确距离信息,而不仅仅是RGB图像。
2. 多模式操作:
相机支持多种操作模式,包括手势识别、人脸识别、物体追踪等。这使得它非常适合于需要人机交互的应用领域。
3. 低光环境适应:
D4系列深度相机在低光环境下也能够提供准确的深度信息,这使得它在各种不同的环境中都能够稳定工作。
4. 易于集成:
相机提供了丰富的软件开发工具,开发者可以方便地将其集成到自己的应用中,快速开发深度感知应用。
5. 多平台支持:
D4系列深度相机支持多种操作系统,包括Windows、Linux等,也提供了各种开发语言的API,方便开发者在不同平台上使用。
6. 精准度和稳定性:
相机具有高精度和稳定性,能够在不同距离范围内提供准确的深度信息,这对于需要精确度的应用非常重要。

1.2 yolo算法

YOLO(You Only Look Once)是一种实时目标检测算法,它的主要思想是将目标检测问题转化为一个回归问题。相较于传统的目标检测算法,YOLO具有更快的处理速度和较高的准确性。

YOLO算法的基本原理如下:

将输入图像划分为一个固定大小的网格。每个网格负责预测该网格中是否包含目标以及目标的边界框。

每个网格预测多个边界框(一般为5个)以适应不同形状的目标。

每个边界框预测目标类别的概率。

对每个边界框的位置和类别进行综合预测。

使用非极大值抑制(NMS)处理重叠的边界框,以获取最终的目标检测结果。

YOLO算法相较于其他目标检测算法的优势在于其端到端的设计,能够实现实时目标检测,并且减少了检测过程中的多次重复计算。然而,由于YOLO将图像划分为网格,对于小尺寸目标和密集目标的检测效果可能会稍差。

此外,YOLO还有不同版本的改进,如YOLOv2、YOLOv3和YOLOv4等,这些改进版本在准确性和速度方面有所提升,同时也引入了一些新的技术和网络结构,如多尺度预测、锚框、Darknet-19等。

2.功能实现 

这是实验室的一个项目,用于未来试智能立体停车场的视觉部分,需要检测车俩位置信息和尺寸信息,摄像头在库的顶上,俯拍视角,图如下:

2.1构思:

因为是俯拍,所以这里就考虑了用2D框实现的可行性,通过yolo拿到粗定位框,将框手动扩大一点,确保物体完全包裹,对框内区域提取轮廓在进行多边形拟合,使用拟合后数据重新画框,拿到角点坐标,进行坐标变换,将像素坐标转为真实坐标,求出距离。(仅限俯拍情况,如果是其他场景,框的坐标和现实坐标不在一个面上,这样就需要用三维目标检测算法画框)

2.2 主代码

这里就不完全开源了,因为这个项目还在做,不过有底子的道友,可以参考我前面有一篇opencv里dnn推理yolov5的代码,结合一下下面这个代码就可以用了。

import pyrealsense2 as rs
# import numpy as np
# import cv2
import random
# import torch
from ours import *
import time# model = torch.hub.load('ultralytics/yolov5', 'yolov5s')
#
# model = torch.hub.load('ultralytics/yolov5', 'yolov5l6')
# model.conf = 0.5
def get_mid_pos(frame,box,depth_data,randnum):distance_list = []mid_pos = [(box[0] + box[2])//2, (box[1] + box[3])//2] #确定索引深度的中心像素位置min_val = min(abs(box[2] - box[0]), abs(box[3] - box[1])) #确定深度搜索范围#print(box,)for i in range(randnum):bias = random.randint(-min_val//4, min_val//4)dist = depth_data[int(mid_pos[1] + bias), int(mid_pos[0] + bias)]cv2.circle(frame, (int(mid_pos[0] + bias), int(mid_pos[1] + bias)), 4, (255,0,0), -1)#print(int(mid_pos[1] + bias), int(mid_pos[0] + bias))if dist:distance_list.append(dist)distance_list = np.array(distance_list)distance_list = np.sort(distance_list)[randnum//2-randnum//4:randnum//2+randnum//4] #冒泡排序+中值滤波cv2.imshow('1', frame)return np.mean(distance_list)
def dectshow(org_img, boxs,depth_data):img = org_img.copy()for box in boxs:cv2.rectangle(img, (int(box[0]), int(box[1])), (int(box[2]), int(box[3])), (0, 255, 0), 2)intrinsics = depth_frame.profile.as_video_stream_profile().intrinsics## x1, y1 = (box[0] ,box[1])# print((x1,y1))# x1, y2 = (box[1] ,box[1])# x2, y1 = (box[0] ,box[1])# x2, y2 = (box[0] ,box[1])x1 = box[0]y1 = box[1]x2 = box[2]y2 = box[3]cv2.circle(img, (x1, y1), 5, (0, 0, 255), -1)  # 红色圆点cv2.circle(img, (x2, y1), 5, (0, 255, 0), -1)  # 绿色圆点cv2.circle(img, (x2, y2), 5, (255, 0, 0), -1)  # 蓝色圆点depth1 = depth_frame.get_distance(x1, y1)  # 获取第一个点的深度值depth2 = depth_frame.get_distance(x2, y1)  # 获取第二个点的深度值depth3 = depth_frame.get_distance(x2, y2)  # 获取第三个点的深度值point1 = rs.rs2_deproject_pixel_to_point(intrinsics, [x1, y1], depth1)point2 = rs.rs2_deproject_pixel_to_point(intrinsics, [x2, y1], depth2)point3 = rs.rs2_deproject_pixel_to_point(intrinsics, [x2, y2], depth3)cv2.imshow('1', img)# 计算两点之间的距离width = np.linalg.norm(np.array(point2) - np.array(point1))height = np.linalg.norm(np.array(point3) - np.array(point2))print("宽 is:", width, "m")print("长 is:", height, "m")cv2.putText(img, f'W: {str(width)[:4] }m H: {str(height)[:4]}m', (int(box[0]), int(box[1]) - 40), cv2.FONT_HERSHEY_SIMPLEX, 0.5,(0, 255, 0), 2)# if not depth_frame.is_depth_frame():#     continue## # 确定坐标值是否在depth_image的范围之内# if x1 >= 0 and x1 < depth_image.shape[1] and y1 >= 0 and y1 < depth_image.shape[0]:#     depth1 = depth_frame.get_distance(x1, y1)  # 获取第一个点的深度值#     continue# else:#     depth1 = None### # 确定坐标值是否在depth_image的范围之内# if x2 >= 0 and x2 < depth_image.shape[1] and y1 >= 0 and y1 < depth_image.shape[0]:#     depth2 = depth_frame.get_distance(x2, y1)  # 获取第二个点的深度值#     continue# else:#     depth2 = None## # 确定坐标值是否在depth_image的范围之内# if x2 >= 0 and x2 < depth_image.shape[1] and y2 >= 0 and y2 < depth_image.shape[0]:#     depth3 = depth_frame.get_distance(x2, y2)  # 获取第三个点的深度值#     continue# else:#     depth3 = None# if x1 < 0 or x1 >= depth_image.shape[1] or y1 < 0 or y1 >= depth_image.shape[0]:#     # 处理超出范围的情况#     continue  # 跳过该点的处理# if x2 < 0 or x2 >= depth_image.shape[1] or y2 < 0 or y2 >= depth_image.shape[0]:#     # 处理超出范围的情况#     continue  # 跳过该点的处理dist = get_mid_pos(org_img, box, depth_data, 24)cv2.putText(img, box[4] + ' ' + str(dist / 1000)[:4] + 'm' ,(int(box[0]), int(box[1])), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2)# if not depth_frame.is_depth_frame():#     continue## # 确定坐标值是否在depth_image的范围之内# if x1 >= 0 and x1 < depth_image.shape[1] and y1 >= 0 and y1 < depth_image.shape[0]:#     depth1 = depth_frame.get_distance(x1, y1)  # 获取第一个点的深度值#     continue# else:#     depth1 = None### # 确定坐标值是否在depth_image的范围之内# if x2 >= 0 and x2 < depth_image.shape[1] and y1 >= 0 and y1 < depth_image.shape[0]:#     depth2 = depth_frame.get_distance(x2, y1)  # 获取第二个点的深度值#     continue# else:#     depth2 = None## # 确定坐标值是否在depth_image的范围之内# if x2 >= 0 and x2 < depth_image.shape[1] and y2 >= 0 and y2 < depth_image.shape[0]:#     depth3 = depth_frame.get_distance(x2, y2)  # 获取第三个点的深度值#     continue# else:#     depth3 = Noneif x1 < 0 or x1 >= depth_image.shape[1] or y1 < 0 or y1 >= depth_image.shape[0]:# 处理超出范围的情况continue  # 跳过该点的处理if x2 < 0 or x2 >= depth_image.shape[1] or y2 < 0 or y2 >= depth_image.shape[0]:# 处理超出范围的情况continue  # 跳过该点的处理cv2.imshow('dec_img', img)if __name__ == "__main__":# Configure depth and color streamsonnx_path = 'yolov5s.onnx'model = Yolov5ONNX(onnx_path)pipeline = rs.pipeline()config = rs.config()config.enable_stream(rs.stream.depth, 640, 480, rs.format.z16, 60)config.enable_stream(rs.stream.color, 640, 480, rs.format.bgr8, 60)# Start streamingpipeline.start(config)pTime = 0try:while True:# Wait for a coherent pair of frames: depth and colorframes = pipeline.wait_for_frames()depth_frame = frames.get_depth_frame()color_frame = frames.get_color_frame()depth_intrinsics = depth_frame.profile.as_video_stream_profile().intrinsicsif not depth_frame or not color_frame:continue# Convert images to numpy arraysdepth_image = np.asanyarray(depth_frame.get_data())color_image = np.asanyarray(color_frame.get_data())im = color_image.copy()    # 备份原图cTime = time.time()fps = 1 / (cTime - pTime)pTime = cTimecv2.putText(color_image, str(int(fps)), (10, 70), cv2.FONT_HERSHEY_PLAIN, 3,(255, 0, 255), 3)results , boxs = model.detect(color_image)dectshow(im, boxs, depth_image)# Apply colormap on depth image (image must be converted to 8-bit per pixel first)depth_colormap = cv2.applyColorMap(cv2.convertScaleAbs(depth_image, alpha=0.03), cv2.COLORMAP_JET)# Stack both images horizontallyimages = np.hstack((color_image, depth_colormap))# Show imagescv2.namedWindow('RealSense', cv2.WINDOW_AUTOSIZE)cv2.imshow('RealSense', images)key = cv2.waitKey(1)# Press esc or 'q' to close the image windowif key & 0xFF == ord('q') or key == 27:cv2.destroyAllWindows()breakfinally:# Stop streamingpipeline.stop()

请忽略yolo这个笨蛋把他识别错了,但是效果还是可以的,精度也没问题,关键是很省事,就是相机费钱。这个方案被否了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/132453.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

文心一言 VS 讯飞星火 VS chatgpt (111)-- 算法导论10.2 2题

二、用go语言&#xff0c;用一个单链表 L实现一个栈。要求操作 PUSH和 POP 的运行时间仍为 O(1)。 文心一言&#xff1a; 在 Go 语言中&#xff0c;我们可以用结构体来实现一个单链表&#xff0c;然后再用栈的相关操作。 以下是一个可能的实现方式&#xff1a; package mai…

进来了解实现官网搜索引擎的三种方法

做网站的目的是对自己的品牌进行推广&#xff0c;让越来越多的人知道自己的产品&#xff0c;但是如果只是做了一个网站放着&#xff0c;然后等着生意找上门来那是不可能的。在当今数字时代&#xff0c;实现官网搜索引擎对于提升用户体验和推动整体性能至关重要。搜索引擎可以帮…

4+1视图与UML

目录 逻辑视图过程视图开发视图物理视图&#xff08;部署视图&#xff09;用例视图 41视图&#xff0c;即逻辑视图&#xff0c;过程视图&#xff0c;实现视图&#xff0c;部署视图&#xff0c;用例视图。 为什么不用一个视图&#xff1f; 针对多个用户&#xff0c;即终端用户&a…

python - excel 设置样式

文章目录 前言python - excel 设置样式1. 准备2. 示例2.1. 给单元格设置样式"等线"、大小为24磅、斜体、红色颜色和粗体2.2. 给第二行设置样式"宋体"、大小为16磅、斜体、红色颜色和粗体2.3. 给第三行数据设置垂直居中和水平居中2.4. 给第四行设置行高为30…

协同办公解决方案:你需要了解的5个关键点

随着互联网技术的不断发展和应用&#xff0c;协同办公已成为现代企业不可或缺的一部分。协同办公解决方案不仅提高了企业的工作效率&#xff0c;还加强了团队的协作和沟通。本文将介绍协同办公解决方案的5个关键点&#xff0c;帮助你更好地了解这一领域的发展。 一、协同办公解…

基于Cucumber的行为驱动开发(BDD)实例

本篇介绍 Cucumber 的基本使用&#xff0c; 因为Cucumber是BDD的工具&#xff0c; 所以首先需要弄清楚什么是BDD&#xff0c;而在介绍BDD之前&#xff0c;先看看常见的软件开发方法。 常见的软件开发方法 面向过程开发&#xff08;Procedural Development&#xff09;&#x…

【算法笔记】LCR 086. 分割回文串

基本思想是使用回溯法&#xff0c;回溯法都可以将问题划分为一个解空间树&#xff1a;假设字符串s为"aab"&#xff0c;那么我们可以使用深度优先搜索去构建解空间树&#xff1a; dfs遍历出来的第一个序列是[a, a, b]&#xff0c;显然该序列都是回文子串&#xff0c;…

如何有效改进erp管理系统?erp管理系统改进建议方向

前言&#xff1a; 说到erp&#xff0c;全称是企业资源计划&#xff0c;这可是企业管理的大杀器&#xff0c;也是现在企业管理的必备神器。它的出身可以追溯到上世纪90年代&#xff0c;那时候的企业管理可是个大难题&#xff0c;各种资源调配不灵光&#xff0c;企业主们急需一种…

[ROS2系列] ubuntu 20.04测试rtabmap 3D建图(二)

接上文我们继续 如果我们要在仿真环境中进行测试&#xff0c;需要将摄像头配置成功。 一、配置位置 sudo vim /opt/ros/foxy/share/turtlebot3_gazebo/models/turtlebot3_waffle/model.sdf 二、修改 <joint name"camera_rgb_optical_joint" type"fixed&…

3、TCP状态

TCP状态 1、TCP通信时序 三次握手成功后&#xff0c;服务器和客户端进入了状态ESTABLISHED 当处于Time_WAIT状态后&#xff0c;不会马上变成CLOSE状态&#xff0c;会经历2MSL&#xff08;约40秒&#xff09;&#xff0c;之后才会进入CLOSE状态。 总结&#xff1a; 主动发起…

Java架构师缓存通用设计方案

目录 1 采用多级缓存2 缓存数据尽量前移3 静态化4 数据平衡策略5 jvm缓存的问题6 redis存放数据解决7 redis垂直拆分8 总结1 采用多级缓存 在实际应用中需要考虑的实际问题。首先,前端页面可以做缓存,虽然图上没有显示,但在现实应用中这是提高性能的一个重要方面。前端页面缓…

前端axios发送请求,在请求头添加参数

1.在封装接口传参时&#xff0c;定义形参&#xff0c;params是正常传参&#xff0c;name则是我想要在请求头传参 export function getCurlList (params, name) {return request({url: ********,method: get,params,name}) } 2.接口调用 const res await getCurlList(params,…