首先,下载相关的权重文件、配置文件和待检测图像。
链接:https://pan.baidu.com/s/1iX_g4PoeKNP9mNmITniCJg 提取码:0djr

1.关于YOLO

YOLO是一个深度学习算法,因此它本身不需要任何安装,而需要的是在其中运行算法的深度学习框架。
介绍下与YOLO兼容的3种最常用和已知的框架:
*Darknet:这是由YOLO开发人员构建的框架,专门为yolo制作。
特点:速度快,可以与GPU或CPU一起使用
*Darkflow:这是Darknet对Tensorflow(另一个深层leanring框架)的改编。
特点:速度快,可以与GPU或CPU一起使用,并且还与Linux,Windows和Mac兼容。但安装比较复杂,尤其是在Windows上
*Opencv: opencv还有一个可与YOLO一起使用的深度学习框架。只要确保至少具有opencv 3.4.2版本及以上。
特点:安装简单,但它仅与CPU一起使用,因此无法以很高的速度实时处理视频。

2.代码:在Opencv中使用YOLO

要求:需要提前准备训练好的权重文件(yolov3.weights)、网络结构配置文件(yolov3.cfg)与标签名称文件(coco.names)。

import cv2
import numpy as np

"""1"""
# 加载yolo的相关文件
net = cv2.dnn.readNet("yolov3.weights", "yolov3.cfg") #导入权重文件weights与配置文件cfg
classes = []

#coco.names文件是包含算法可以检测到的对象名称
with open("coco.names", "r") as f:
    classes = [line.strip() for line in f.readlines()]
layer_names = net.getLayerNames() #layer_names表示的是opencv集成的darknet每层网络结构名称
output_layers = [layer_names[i[0] - 1] for i in net.getUnconnectedOutLayers()]
#net.getUnconnectedOutLayers():[[200] [227] [254]]
#output_layers(yolo所在的网络层):['yolo_82', 'yolo_94', 'yolo_106']
colors = np.random.uniform(0, 255, size=(len(classes), 3))
#size: 输出样本数目,为int或元组(tuple)类型,例如,size=(m,n,k), 则输出m*n*k个样本,缺省时输出1个值。
#colors.shape:(80, 3)

"""2"""
# 输入图像,将图像加载到要执行对象检测的位置,并获得其宽度和高度
img = cv2.imread("room_ser.jpg") #traffic.jpg fx=1, fy=1 ;
img = cv2.resize(img, None, fx=0.3, fy=0.3) #fx:width方向的缩放比例,fy:height方向的缩放比例
#缩放比例自己调节,有些图片太大电脑分辨率显示不了全部所以需要缩小
height, width, channels = img.shape

#上面已经准备好了yolo算法和要检测的图像,现在该将图像传递到网络中并进行检测了
#PS:我们不能立即使用待检测的完整图像传递到神经网络中,首先需要将其转换为blob。Blob用于从图像中提取特征并调整其大小。
#YOLO接受三种尺寸:
#320×320:很小,所以精度较低,但速度更好
#416×416:在中间,两者兼而有之
#609×609:更大,因此精度高且速度慢
blob = cv2.dnn.blobFromImage(img, 0.00392, (416, 416), (0, 0, 0), True, crop=False)
#blob.shape:(1, 3, 416, 416) N,C,H,W

net.setInput(blob) #将待检测的图像传递到网络中并进行检测
outs = net.forward(output_layers)
#Outs是一个数组,包含有关所检测对象的所有信息,包括它们的位置以及对检测的置信度的信息
#至此,检测完成

"""3"""
#前面已经检测完毕,下面只需要在屏幕上显示结果
class_ids = []
confidences = []
boxes = []
for out in outs:
    for detection in out:
        scores = detection[5:]
        class_id = np.argmax(scores)
        confidence = scores[class_id]
        if confidence > 0.5: #这里将阈值置信度设置为0.5
        #阈值置信度如果更大,则认为已正确检测到对象,否则将其跳过。
        # 阈值从0到1。越接近1,则检测的精度越高;而越接近0,则精度越低,但是检测到的对象数量也越大。
            # 目标检测
            center_x = int(detection[0] * width)
            center_y = int(detection[1] * height)
            w = int(detection[2] * width)
            h = int(detection[3] * height)

            # Rectangle coordinates
            x = int(center_x - w / 2)
            y = int(center_y - h / 2)

            boxes.append([x, y, w, h])
            confidences.append(float(confidence))
            class_ids.append(class_id)

#当我们使用yolo进行目标检测时,对于同一个目标,可能在目标上会标出许多的方框(即Anchor),
# 这里,需要使用NMS(非极大值抑制算法)来消除多余的方框。
indexes = cv2.dnn.NMSBoxes(boxes, confidences, 0.5, 0.4)
#cv2.dnn.NMSBoxes()函数:可以在目标检测中筛选置信度低于阈值的,同时还进行Nms筛选。
#参考博客:
print(indexes) #打印待检测图像在coco.names类别中检测种类的序号

font = cv2.FONT_HERSHEY_PLAIN #字体类型
for i in range(len(boxes)):
    if i in indexes:
        x, y, w, h = boxes[i]
        label = str(classes[class_ids[i]])
        color = colors[i]
        cv2.rectangle(img, (x, y), (x + w, y + h), color, 2)
        cv2.putText(img, label, (x, y + 30), font, 3, color, 3)
        #cv2.putText(img, xy, (x1, y1), cv2.FONT_HERSHEY_PLAIN, 2, (0, 0, 255), thickness=2)
        #img:要作用的图片
        #xy:显示的文本内容(字符串)
        #(x1, y1): 文本显示在图片上的位置坐标
        #cv2.FONT_HERSHEY_PLAIN: 字体类型
        #2: 字体大小
        #(0,0,255):显示的文本颜色(红色)
        #thickness = 2:字体粗细,数值表示占几个像素


cv2.imshow("Image", img)
cv2.waitKey(0)
cv2.destroyAllWindows()

效果:

yolo算法实现 python yolo算法python代码_python


yolo算法实现 python yolo算法python代码_opencv_02


yolo算法实现 python yolo算法python代码_opencv_03