ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

基于深度摄像头的yolov4算法应用 (Realsense D435i)python

2021-10-04 16:02:15  阅读:530  来源: 互联网

标签:D435i yolov4 python image cv2 boxes color depth np


硬件使用的是教授提供的RealSense D435i摄像头
深度值用来当作测距传感器
识别工作在RBG图像上做文章

融合了一些大佬们的code,ps:深度摄像头有专门的库(pyrealsense2),需要变通

全部代码

# coding=utf-8
import pyrealsense2 as rs
import numpy as np
import cv2
import time


LABELS = open("coco.names").read().strip().split("\n")
np.random.seed(666)
COLORS = np.random.randint(0, 255, size=(len(LABELS), 3), dtype="uint8")



# 导入 YOLO 配置和权重文件并加载网络:
net = cv2.dnn_DetectionModel('yolov4.cfg', 'yolov4.weights')
# 获取 YOLO 未连接的输出图层
layer = net.getUnconnectedOutLayersNames()



# Configure depth and color streams
pipeline = rs.pipeline()
config = rs.config()
config.enable_stream(rs.stream.depth, 640, 480, rs.format.z16, 30)
config.enable_stream(rs.stream.color, 640, 480, rs.format.bgr8, 30)

# Start streaming
profile = pipeline.start(config)
try:
    while True:
        # Wait for a coherent pair of frames: depth and color
        frames = pipeline.wait_for_frames()
        depth_frame = frames.get_depth_frame()
        color_frame = frames.get_color_frame()
        if not depth_frame or not color_frame:
            continue

        # Convert images to numpy arrays
        depth_image = np.asanyarray(depth_frame.get_data())
        color_image = np.asanyarray(color_frame.get_data())

        (H, W) = color_image.shape[:2]

        # 从输入图像构造一个 blob,然后执行 YOLO 对象检测器的前向传递,给我们边界盒和相关概率
        blob = cv2.dnn.blobFromImage(color_image, 1 / 255.0, (416, 416),
                                     swapRB=True, crop=False)
        net.setInput(blob)
        start = time.time()
        # 前向传递,获得信息
        layerOutputs = net.forward(layer)
        # 用于得出检测时间
        end = time.time()
        print("[INFO] YOLO took {:.6f} seconds".format(end - start))

        boxes = []
        confidences = []
        classIDs = []

        # 循环提取每个输出层
        for output in layerOutputs:
            # 循环提取每个框
            for detection in output:
                # 提取当前目标的类 ID 和置信度
                scores = detection[5:]
                classID = np.argmax(scores)
                confidence = scores[classID]
                # 通过确保检测概率大于最小概率来过滤弱预测
                if confidence > 0.5:
                    # 将边界框坐标相对于图像的大小进行缩放,YOLO 返回的是边界框的中心(x, y)坐标,
                    # 后面是边界框的宽度和高度
                    box = detection[0:4] * np.array([W, H, W, H])
                    (centerX, centerY, width, height) = box.astype("int")
                    # 转换出边框左上角坐标
                    x = int(centerX - (width / 2))
                    y = int(centerY - (height / 2))
                    # 更新边界框坐标、置信度和类 id 的列表
                    boxes.append([x, y, int(width), int(height)])
                    confidences.append(float(confidence))
                    classIDs.append(classID)

        # 非最大值抑制,确定唯一边框
        idxs = cv2.dnn.NMSBoxes(boxes, confidences, 0.5, 0.3)
        # 确定每个对象至少有一个框存在
        if len(idxs) > 0:
            # 循环画出保存的边框
            for i in idxs.flatten():
                # 提取坐标和宽度
                (x, y) = (boxes[i][0], boxes[i][1])
                (w, h) = (boxes[i][2], boxes[i][3])
                # 画出边框和标签
                color = [int(c) for c in COLORS[classIDs[i]]]
                cv2.rectangle(color_image, (x, y), (x + w, y + h), color, 1, lineType=cv2.LINE_AA)
                text = "{}: {:.4f}".format(LABELS[classIDs[i]], confidences[i])
                cv2.putText(color_image, text, (x, y - 5), cv2.FONT_HERSHEY_SIMPLEX,
                            0.5, color, 1, lineType=cv2.LINE_AA)
        # cv2.imshow("Tag", image)
        # cv2.waitKey(0)

        # 将深度图转换成彩色图
        depth_colormap = cv2.applyColorMap(cv2.convertScaleAbs(depth_image, alpha=0.03), cv2.COLORMAP_JET)

        # 将彩色图和深度图叠加在一起
        # images = np.hstack((color_image, depth_colormap))
        # print(color_image)
        # print(depth_colormap)
        depth_image_3d = np.dstack((depth_image, depth_image, depth_image))

        # 原图
        cv2.namedWindow('color_image', cv2.WINDOW_AUTOSIZE)
        cv2.imshow('color_image', color_image)
        # 深度图
        cv2.namedWindow('depth_colormap', cv2.WINDOW_AUTOSIZE)
        cv2.imshow('depth_colormap', depth_image_3d)

        key = cv2.waitKey(1)

        # Press esc or 'q' to close the image window
        if key & 0xFF == ord('q') or key == 27:
            cv2.destroyAllWindows()
            break

finally:
    # Stop streaming
    pipeline.stop()
    pipeline.stop()

结果展示

在这里插入图片描述
结果无法做到视频实时,会有0.4-0.6s延迟,原因yolov4处理还需要0.4-0.6s时间
(猜测市面上流畅的实时人脸识别是采用了多进程处理?boxes和视频流分词输出?)
在这里插入图片描述

debug的点:

  • 只有opencv版本4.4.0适配Yolov4算法,会报错AttributeError: module ‘cv2.dnn’ has no attribute ‘getUnconnectedOutLayersNames’,把新版本cv2删掉,重新下载4.4.0版本就好,我用的4.4.0.42
  • 注意循环和视频流处理
  • cfg,wights,names等文件不可缺,是预处理过的,放同一目录下

预训练准备与函数

coco.names 内包含了很多目标标签,如 person、bicycle、car 等,且按一定顺序排列,里面基本包含了 Yolo 官方模型中可检测的对象。该文件可从以下链接中提取:https://gitee.com/public_sharing/ObjectDetection-YOLO/blob/master/coco.names

每个对象配备了不一样的颜色,以便在图片中标记时便于区分。


yolov4.cfgyolov4.weights 文件就是官方提供的模型,下载链接:https://pan.baidu.com/s/1XrcPHdp2_4c-dKge2Guw4w 提取码:xsxb 。如果失效,可以直接百度搜索 Yolov4模型下载,有很多人都分享出来了。

cv2.dnn_DetectionModel 是 opencv 4.1.2 开始新增的方法,用于加载网络。以前是使用 cv2.dnn.readNetFromDarknet ,此处使用也可以达到同样的效果。

getUnconnectedOutLayersNames() 用于提取输出图层的名称,yolo 含有很多的图层,可以使用 getLayerNames() 将所有图层的名称提取出来。但在这里,我们只需要使用 yolo 的最后输出图层。(高版本opencv也最爱报这个错)


blobFromImage 用于对图像进行预处理

cv2.dnn.blobFromImage(image[, scalefactor[, size[, mean[, swapRB[, crop[, ddepth]]]]]])

image:输入图像
scalefactor:图像各通道数值的缩放比例
size:输出图像的空间尺寸
mean:用于各通道减去的值,以降低光照的影响
swapRB:交换 RB 通道,默认为 False
crop:图像裁剪,默认为 False。当值为 True 时,先按比例缩放,然后从中心裁剪成 size 尺寸
ddepth:输出的图像深度,可选 CV_32F 或者 CV_8U


3 个列表内保存的内容:
boxes:对象的边界框
confidences :YOLO 分配给对象的置信度值,较低的置信度值表示该对象可能不是网络认为的对象。上面的代码中将过滤掉小于 0.5 阈值的对象
classIDs:检测到的对象的类标签
这样每个被提取出的对象,都确定了标签和区域坐标就、位置。接下来就是在图片中标记出来,便于我们观看。


对于每个对象,Yolo 会框出 3 个左右的区域,我们只需要显示出最合适的区域。非最大值抑制,就是搜索出局部最大值,将置信度最大的框保存,其余剔除。

cv2.dnn.NMSBoxes(bboxes, scores, score_threshold, nms_threshold, eta=None, top_k=None)

bboxes:一组边框
scores:一组对应的置信度
score_threshold:置信度的阈值
nms_threshold:非最大抑制的阈值
之后将每个对象的方框和标签都画出来


官方目标结果:
在这里插入图片描述

标签:D435i,yolov4,python,image,cv2,boxes,color,depth,np
来源: https://blog.csdn.net/weixin_51914823/article/details/120604385

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有