YOLO-V3实时检测实现(opencv+python实现)

63 篇文章 24 订阅

1.前置知识点(浅层了解)

(1)深度学习的网络模型

https://mydreamambitious.blog.csdn.net/article/details/125459959

(2)yolo-v3网络结构

对于了解目前这篇文章(YOLO-V3实时检测实现),读者只要了解下面给出的知识点,即可,不需要太关心论文中的细节。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

表的来源:https://blog.csdn.net/qq_37541097/article/details/81214953

图片来源:图片地址


2.YOLO-V3权重文件(.weights),类别文件(.names)和网络文件(.cfg)下载

(1)YOLOV3权重文件下载

https://pjreddie.com/darknet/yolo/

(2)YOLOV3类别文件下载

https://github.com/pjreddie/darknet/blob/master/data/coco.names

(3)YOLO.cfg配置文件下载

https://github.com/pjreddie/darknet
在这里插入图片描述
下载之后如下:
在这里插入图片描述


3.代码实战

YOLO-V3输出的结果形式;知道了输出结果的形式,对于后面获取预测结果的预测框的坐标(x,y),高宽(w,h),置信度(confidence)以及预测类别的概率很有帮助(这些值是最后的输出结果,所以需要映射回原来的图像)。
在这里插入图片描述

(1)读取权重文件和网络配置文件

#读取网络配置文件和权重文件
net=cv2.dnn.readNet(model='dnn_model/yolov3.weights',
                    config='dnn_model/yolov3.cfg')

(2)获取最后三个输出层的名称

#由yolo-v3的结构可知,最终有三个尺度的输出
layerName=net.getLayerNames()
#存储输出的三个尺度名称,用于后面进行前向推断的
ThreeOutput_layers_name=[]
for i in net.getUnconnectedOutLayers():
    ThreeOutput_layers_name.append(layerName[i-1])

(3)读取包含80个类别coco.names的文件

#因为yolo-v3中检测包含80个类别,所以首先获取类别
with open('dnn_model/coco.names','r') as fp:
    classes=fp.read().splitlines()

(4)置信度阈值和非极大值抑制阈值的设定

#指定过滤的置信度阈值:confidence
Confidence_thresh=0.2
#指定非极大值抑制的值:对候选框进行筛选
Nms_thresh=0.35

(5)前向推断以及预测过程

(1)图像的预处理,设置网络输入和前向推断
 # 参数情况:图像 ,归一化,缩放的大小,是否对RGB减去一个常数,R和B交换(因为R和B是反着的,所以需要交换),是否裁剪
    blob = cv2.dnn.blobFromImage(frame, 1 / 255, (416, 416), (0, 0, 0), swapRB=True, crop=False)
    #获取图像的高宽
    height,width,channel=frame.shape
    #设置网络输入
    net.setInput(blob)
    #进行前向推断:采用的最后三个尺度输出层作为前向推断
    predict=net.forward(ThreeOutput_layers_name)
(2)设置存储后续值的列表
 # 存放预测框的坐标
    boxes = []
    #存在预测物体的置信度
    confid_object=[]
    #存放预测的类别
    class_prob=[]
    #存放预测物体的id
    class_id=[]
    #存放预测类别的名称
    class_names=[]
(3)获取坐标,置信度,概率值以及预测类别
 #根据输出的是三个尺度,所以分别遍历三个尺度
    for scale in predict:
        for box in scale:
            #获取坐标值和高宽
            #首先获取矩形中心坐标值(这里需要映射回原图)
            center_x=int(box[0]*width)
            center_y=int(box[1]*height)
            #计算框的高宽
            w=int(box[2]*width)
            h=int(box[3]*height)
            #获取矩形框的左上角坐标
            left_x=int(center_x-w/2)
            left_y=int(center_y-h/2)
            boxes.append([left_x,left_y,w,h])

            #获取检测物体的置信度
            confid_object.append(float(box[4]))
            #获取概率最大值
            #首先获取最高值概率的下标
            index=np.argmax(box[5:])
            class_id.append(index)
            class_names.append(classes[index])
            class_prob.append(box[index])
    confidences=np.array(class_prob)*np.array(confid_object)
(4)求解非极大值抑制结果
 #计算非极大值抑制
    all_index=cv2.dnn.NMSBoxes(boxes,confidences,Confidence_thresh,Nms_thresh)

(5)绘制矩形框
#遍历,绘制矩形框
    for i in all_index.flatten():
        x,y,w,h=boxes[i]
        #四舍五入,保留2位小数
        confidence=str(round(confidences[i],2))
        #绘制矩形框
        cv2.rectangle(img=frame,pt1=(x,y),pt2=(x+w,y+h),
                      color=(0,255,0),thickness=2)
        text=class_names[i]+' '+confidence
        cv2.putText(img=frame,text=text,org=(x,y-10),
                    fontFace=cv2.FONT_HERSHEY_SIMPLEX,
                    fontScale=1.0,color=(0,0,255),thickness=2)

(6)预测单张图片

#单张图片的检测
def signa_Picture(image_path='images/smile.jpg'):
    img=cv2.imread(image_path)
    img=cv2.resize(src=img,dsize=(416,416))
    dst=Forward_Predict(img)
    cv2.imshow('detect',dst)
    key=cv2.waitKey(0)
    if key==27:
        exit()

(7)实时检测

#实时的检测
def detect_time():
    cap=cv2.VideoCapture(0)
    while cap.isOpened():
        OK,frame=cap.read()
        if not OK:
            break
        #将图片进行一下翻转,因为Opencv读取的图片和我们正常是反着的
        frame=cv2.flip(src=frame,flipCode=2)
        frame=cv2.resize(src=frame,dsize=(416,416))
        dst=Forward_Predict(frame)

        cv2.imshow('detect',dst)
        key=cv2.waitKey(1)
        if key==27:
            break
    cap.release()

(8)整体代码

import os
import cv2
import numpy as np
import matplotlib.pyplot as plt

#读取网络配置文件和权重文件
net=cv2.dnn.readNet(model='dnn_model/yolov3.weights',
                    config='dnn_model/yolov3.cfg')
#由yolo-v3的结构可知,最终有三个尺度的输出
layerName=net.getLayerNames()
#存储输出的三个尺度名称,用于后面进行前向推断的
ThreeOutput_layers_name=[]
for i in net.getUnconnectedOutLayers():
    ThreeOutput_layers_name.append(layerName[i-1])

#因为yolo-v3中检测包含80个类别,所以首先获取类别
with open('dnn_model/coco.names','r') as fp:
    classes=fp.read().splitlines()

#指定过滤的置信度阈值:confidence
Confidence_thresh=0.2
#指定非极大值抑制的值:对候选框进行筛选
Nms_thresh=0.35

#检测的过程已经图形的绘制
def Forward_Predict(frame):
    # 参数情况:图像 ,归一化,缩放的大小,是否对RGB减去一个常数,R和B交换(因为R和B是反着的,所以需要交换),是否裁剪
    blob = cv2.dnn.blobFromImage(frame, 1 / 255, (416, 416), (0, 0, 0), swapRB=True, crop=False)
    #获取图像的高宽
    height,width,channel=frame.shape
    #设置网络输入
    net.setInput(blob)
    #进行前向推断:采用的最后三个尺度输出层作为前向推断
    predict=net.forward(ThreeOutput_layers_name)
    # 存放预测框的坐标
    boxes = []
    #存在预测物体的置信度
    confid_object=[]
    #存放预测的类别
    class_prob=[]
    #存放预测物体的id
    class_id=[]
    #存放预测类别的名称
    class_names=[]
    #根据输出的是三个尺度,所以分别遍历三个尺度
    for scale in predict:
        for box in scale:
            #获取坐标值和高宽
            #首先获取矩形中心坐标值(这里需要映射回原图)
            center_x=int(box[0]*width)
            center_y=int(box[1]*height)
            #计算框的高宽
            w=int(box[2]*width)
            h=int(box[3]*height)
            #获取矩形框的左上角坐标
            left_x=int(center_x-w/2)
            left_y=int(center_y-h/2)
            boxes.append([left_x,left_y,w,h])

            #获取检测物体的置信度
            confid_object.append(float(box[4]))
            #获取概率最大值
            #首先获取最高值概率的下标
            index=np.argmax(box[5:])
            class_id.append(index)
            class_names.append(classes[index])
            class_prob.append(box[index])
    confidences=np.array(class_prob)*np.array(confid_object)
    #计算非极大值抑制
    all_index=cv2.dnn.NMSBoxes(boxes,confidences,Confidence_thresh,Nms_thresh)

    #遍历,绘制矩形框
    for i in all_index.flatten():
        x,y,w,h=boxes[i]
        #四舍五入,保留2位小数
        confidence=str(round(confidences[i],2))
        #绘制矩形框
        cv2.rectangle(img=frame,pt1=(x,y),pt2=(x+w,y+h),
                      color=(0,255,0),thickness=2)
        text=class_names[i]+' '+confidence
        cv2.putText(img=frame,text=text,org=(x,y-10),
                    fontFace=cv2.FONT_HERSHEY_SIMPLEX,
                    fontScale=1.0,color=(0,0,255),thickness=2)
    return frame

#实时的检测
def detect_time():
    cap=cv2.VideoCapture(0)
    while cap.isOpened():
        OK,frame=cap.read()
        if not OK:
            break
        #将图片进行一下翻转,因为Opencv读取的图片和我们正常是反着的
        frame=cv2.flip(src=frame,flipCode=2)
        frame=cv2.resize(src=frame,dsize=(416,416))
        dst=Forward_Predict(frame)

        cv2.imshow('detect',dst)
        key=cv2.waitKey(1)
        if key==27:
            break
    cap.release()


#单张图片的检测
def signa_Picture(image_path='images/smile.jpg'):
    img=cv2.imread(image_path)
    img=cv2.resize(src=img,dsize=(416,416))
    dst=Forward_Predict(img)
    cv2.imshow('detect',dst)
    key=cv2.waitKey(0)
    if key==27:
        exit()
cv2.destroyAllWindows()

if __name__ == '__main__':
    print('Pycharm')
    # signa_Picture()
    detect_time()

(9)单张图片预测结果

在这里插入图片描述

(10)实时检测结果

yolov3视频演示

  • 12
    点赞
  • 69
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
PythonOpenCV结合使用YOLO(You Only Look Once)可以实现目标检测和物体识别的功能。YOLO是一种基于深度学习的目标检测算法,它可以实时地在图像或视频中检测和定位多个对象。 要在Python中使用YOLO,首先需要安装OpenCVYOLO的相关库。可以使用pip命令来安装它们: ``` pip install opencv-python pip install opencv-contrib-python ``` 接下来,需要下载YOLO的权重文件和配置文件。YOLO有几个不同版本,可以根据需求选择不同的模型。一般来说,比较常用的是YOLOv3YOLOv4。 下载YOLOv3的权重文件和配置文件: ``` wget https://pjreddie.com/media/files/yolov3.weights wget https://github.com/pjreddie/darknet/blob/master/cfg/yolov3.cfg wget https://github.com/pjreddie/darknet/blob/master/data/coco.names ``` 下载YOLOv4的权重文件和配置文件: ``` wget https://github.com/AlexeyAB/darknet/releases/download/darknet_yolo_v3_optimal/yolov4.weights wget https://github.com/AlexeyAB/darknet/blob/master/cfg/yolov4.cfg wget https://github.com/AlexeyAB/darknet/blob/master/data/coco.names ``` 下载完毕后,可以使用下面的代码加载模型并进行目标检测: ```python import cv2 # 加载模型 net = cv2.dnn.readNet("yolov3.weights", "yolov3.cfg") # 加载类别标签 classes = [] with open("coco.names", "r") as f: classes = [line.strip() for line in f.readlines()] # 加载图像 image = cv2.imread("image.jpg") # 进行目标检测 blob = cv2.dnn.blobFromImage(image, 1/255, (416, 416), swapRB=True, crop=False) net.setInput(blob) outs = net.forward(net.getUnconnectedOutLayersNames()) # 解析检测结果 for out in outs: for detection in out: scores = detection[5:] classId = np.argmax(scores) confidence = scores[classId] if confidence > 0.5: centerX = int(detection[0] * width) centerY = int(detection[1] * height) w = int(detection[2] * width) h = int(detection[3] * height) x = int(centerX - w / 2) y = int(centerY - h / 2) cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2) cv2.putText(image, classes[classId], (x, y - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2) # 显示结果 cv2.imshow("Image", image) cv2.waitKey(0) cv2.destroyAllWindows() ``` 这段代码会加载YOLO模型和类别标签,然后读取一张图像,进行目标检测,并在图像中绘制检测结果的边界框和类别标签。最后,显示图像并等待按键退出。 请注意,上述代码只提供了一个基本的示例,实际应用中可能需要根据具体需求进行更多的调整和优化。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值