如何创建网站的第一步,中国制造网外贸平台,网站开发宣传,中文域名.网站目标
利用yolo模型进行目标检测的方法完成目标检测功能的实现 整个流程如下#xff1a;
基于OPenCV中的DNN模块
加载已训练好的yolov3模型及其权重参数将要处理的图像转换成输入到模型中的blobs利用模型对目标进行检测遍历检测结果应用非极大值抑制绘制最终检测结果#x…目标
利用yolo模型进行目标检测的方法完成目标检测功能的实现 整个流程如下
基于OPenCV中的DNN模块
加载已训练好的yolov3模型及其权重参数将要处理的图像转换成输入到模型中的blobs利用模型对目标进行检测遍历检测结果应用非极大值抑制绘制最终检测结果并存入到ndarray中供目标追踪使用。
代码如下
1.加载yolov3模型及其权重参数 # 1.加载可以识别物体的名称将其存放在LABELS中一共有80种在这我们只使用car
labelsPath ./yolo-coco/coco.names
LABELS open(labelsPath).read().strip().split(\n)# 设置随机数种子生成多种不同的颜色当一个画面中有多个目标时使用不同颜色的框将其框起来
np.random.seed(42)
COLORS np.random.randint(0, 255, size(200, 3),dtypeuint8)# 加载已训练好的yolov3网络的权重和相应的配置数据
weightsPath ./yolo-coco/yolov3.weights
configPath ./yolo-coco/yolov3.cfg# 加载好数据之后开始利用上述数据恢复yolo神经网络
net cv2.dnn.readNetFromDarknet(configPath, weightsPath)
# 获取YOLO中每一网络层的名称[conv_0, bn_0, relu_0, conv_1, bn_1, relu_1, conv_2, bn_2, relu_2...]
ln net.getLayerNames()
# 获取输出层在网络中的索引位置并以列表的形式[yolo_82, yolo_94, yolo_106]
ln [ln[i[0] - 1] for i in net.getUnconnectedOutLayers()] 2.要处理的图像转换成输入到模型中的blobs # 2. 读取图像
frame cv2.imread(./images/car1.jpg)
# 视频的宽度和高度即帧尺寸
(W, H) (None, None)
if W is None or H is None:(H, W) frame.shape[:2]# 根据输入图像构造blob,利用OPenCV进行深度网路的计算时一般将图像转换为blob形式对图片进行预处理包括缩放减均值通道交换等
# 还可以设置尺寸一般设置为在进行网络训练时的图像的大小
blob cv2.dnn.blobFromImage(frame, 1 / 255.0, (416, 416), swapRBTrue, cropFalse) 3.利用模型对目标进行检测 # 3.将blob输入到前向网络中并进行预测
net.setInput(blob)
start time.time()
# yolo前馈计算获取边界和相应的概率
# 输出layerOutsputs介绍
# 是YOLO算法在图片中检测到的bbx的信息
# 由于YOLO v3有三个输出也就是上面提到的[yolo_82, yolo_94, yolo_106]
# 因此layerOutsputs是一个长度为3的列表
# 其中列表中每一个元素的维度是(num_detection, 85)
# num_detections表示该层输出检测到bbx的个数
# 85因为该模型在COCO数据集上训练[5:]表示类别概率[0:4]表示bbx的位置信息[5]表示置信度
layerOutputs net.forward(ln) 4.遍历检测结果,获得检测框 # 下面对网络输出的bbx进行检查
# 判定每一个bbx的置信度是否足够的高以及执行NMS算法去除冗余的bbxboxes [] # 用于存放识别物体的框的信息包括框的左上角横坐标x和纵坐标y以及框的高h和宽w
confidences [] # 表示识别目标是某种物体的可信度
classIDs [] # 表示识别的目标归属于哪一类[person, bicycle, car, motorbike....]# 4. 遍历每一个输出层的输出
for output in layerOutputs:# 遍历某个输出层中的每一个目标for detection in output:scores detection[5:] # 当前目标属于某一类别的概率classID np.argmax(scores) # 目标的类别IDconfidence scores[classID] # 得到目标属于该类别的置信度# 只保留置信度大于0.3的边界框若图片质量较差可以将置信度调低一点if confidence 0.3:# 将边界框的坐标还原至与原图片匹配YOLO返回的是边界框的中心坐标以及边界框的宽度和高度box detection[0:4] * np.array([W, H, W, H])(centerX, centerY, width, height) box.astype(int) # 使用 astype(int) 对上述 array 进行强制类型转换centerX框的中心点横坐标 centerY框的中心点纵坐标width框的宽度height框的高度x int(centerX - (width / 2)) # 计算边界框的左上角的横坐标y int(centerY - (height / 2)) # 计算边界框的左上角的纵坐标# 更新检测到的目标框置信度和类别IDboxes.append([x, y, int(width), int(height)]) # 将边框的信息添加到列表boxesconfidences.append(float(confidence)) # 将识别出是某种物体的置信度添加到列表confidencesclassIDs.append(classID) # 将识别物体归属于哪一类的信息添加到列表classIDs 5.非极大值抑制 # 5. 非极大值抑制
idxs cv2.dnn.NMSBoxes(boxes, confidences, 0.5, 0.3) 6.最终检测结果绘制并存入到ndarray中供目标追踪使用 # 6. 获得最终的检测结果
dets [] # 存放检测框的信息包括左上角横坐标纵坐标右下角横坐标纵坐标以及检测到的物体的置信度,用于目标跟踪
if len(idxs) 0: # 存在检测框的话即检测框个数大于0for i in idxs.flatten(): # 循环检测出的每一个box# yolo模型可以识别很多目标因为我们在这里只是识别车所以只有目标是车的我们进行检测其他的忽略if LABELS[classIDs[i]] car:(x, y) (boxes[i][0], boxes[i][1]) # 得到检测框的左上角坐标(w, h) (boxes[i][2], boxes[i][3]) # 得到检测框的宽和高cv2.rectangle(frame, (x, y), (xw, yh), (0,255,0), 2) # 将方框绘制在画面上dets.append([x, y, x w, y h, confidences[i]]) # 将检测框的信息的放入dets中
# 设置数据类型将整型数据转换为浮点数类型且保留小数点后三位
np.set_printoptions(formatter{float: lambda x: {0:0.3f}.format(x)})
# 将检测框数据转换为ndarray,其数据类型为浮点型
dets np.asarray(dets)plt.imshow(frame[:,:,::-1]) 在视频中进行目标检测 labelsPath ./yolo-coco/coco.names
LABELS open(labelsPath).read().strip().split(\n)# 设置随机数种子生成多种不同的颜色当一个画面中有多个目标时使用不同颜色的框将其框起来
np.random.seed(42)
COLORS np.random.randint(0, 255, size(200, 3),dtypeuint8)# 加载已训练好的yolov3网络的权重和相应的配置数据
weightsPath ./yolo-coco/yolov3.weights
configPath ./yolo-coco/yolov3.cfg# 加载好数据之后开始利用上述数据恢复yolo神经网络
net cv2.dnn.readNetFromDarknet(configPath, weightsPath)
# 获取YOLO中每一网络层的名称[conv_0, bn_0, relu_0, conv_1, bn_1, relu_1, conv_2, bn_2, relu_2...]
ln net.getLayerNames()
# 获取输出层在网络中的索引位置并以列表的形式[yolo_82, yolo_94, yolo_106]
ln [ln[i[0] - 1] for i in net.getUnconnectedOutLayers()]
视频处理类
# 初始化vediocapture类参数指定打开的视频文件也可以是摄像头
vs cv2.VideoCapture(./input/test_1.mp4)
# 视频的宽度和高度即帧尺寸
(W, H) (None, None)
# 视频文件写对象
writer Nonetry:# 确定获取视频帧数的方式prop cv2.cv.CV_CAP_PROP_FRAME_COUNT if imutils.is_cv2() \else cv2.CAP_PROP_FRAME_COUNT# 获取视频的总帧数total int(vs.get(prop))# 打印视频的帧数print([INFO] {} total frames in video.format(total))
except:print([INFO] could not determine # of frames in video)print([INFO] no approx. completion time can be provided)total -1# 循环读取视频中的每一帧画面
while True:# 读取帧grabbed是bool,表示是否成功捕获帧frame是捕获的帧(grabbed, frame) vs.read()# 若未捕获帧则退出循环if not grabbed:break# 若W和H为空则将第一帧画面的大小赋值给他if W is None or H is None:(H, W) frame.shape[:2]# 根据输入图像构造blob,利用OPenCV进行深度网路的计算时一般将图像转换为blob形式对图片进行预处理包括缩放减均值通道交换等# 还可以设置尺寸一般设置为在进行网络训练时的图像的大小blob cv2.dnn.blobFromImage(frame, 1 / 255.0, (416, 416), swapRBTrue, cropFalse)# 将blob输入到前向网络中net.setInput(blob)start time.time()# yolo前馈计算获取边界和相应的概率layerOutputs net.forward(ln)输出layerOutsputs介绍是YOLO算法在图片中检测到的bbx的信息由于YOLO v3有三个输出也就是上面提到的[yolo_82, yolo_94, yolo_106]因此layerOutsputs是一个长度为3的列表其中列表中每一个元素的维度是(num_detection, 85)num_detections表示该层输出检测到bbx的个数85因为该模型在COCO数据集上训练[5:]表示类别概率[0:4]表示bbx的位置信息[5]表示置信度end time.time()下面对网络输出的bbx进行检查判定每一个bbx的置信度是否足够的高以及执行NMS算法去除冗余的bbxboxes [] # 用于存放识别物体的框的信息包括框的左上角横坐标x和纵坐标y以及框的高h和宽wconfidences [] # 表示识别目标是某种物体的可信度classIDs [] # 表示识别的目标归属于哪一类[person, bicycle, car, motorbike....]# 遍历每一个输出层的输出for output in layerOutputs:# 遍历某个输出层中的每一个目标for detection in output:scores detection[5:] # 当前目标属于某一类别的概率# scores detection[5:] --- [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.# 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.# 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.# 0. 0. 0. 0. 0. 0. 0. 0.]# scores的大小应该是1*80因为在训练yolo模型时是80类目标classID np.argmax(scores) # 目标的类别IDconfidence scores[classID] # 得到目标属于该类别的置信度# 只保留置信度大于0.3的边界框若图片质量较差可以将置信度调低一点if confidence 0.3:# 将边界框的坐标还原至与原图片匹配YOLO返回的是边界框的中心坐标以及边界框的宽度和高度box detection[0:4] * np.array([W, H, W, H])(centerX, centerY, width, height) box.astype(int) # 使用 astype(int) 对上述 array 进行强制类型转换centerX框的中心点横坐标 centerY框的中心点纵坐标width框的宽度height框的高度x int(centerX - (width / 2)) # 计算边界框的左上角的横坐标y int(centerY - (height / 2)) # 计算边界框的左上角的纵坐标# 更新检测到的目标框置信度和类别IDboxes.append([x, y, int(width), int(height)]) # 将边框的信息添加到列表boxesconfidences.append(float(confidence)) # 将识别出是某种物体的置信度添加到列表confidencesclassIDs.append(classID) # 将识别物体归属于哪一类的信息添加到列表classIDs# 上一步中已经得到yolo的检测框但其中会存在冗余的bbox,即一个目标对应多个检测框所以使用NMS去除重复的检测框# 利用OpenCV内置的NMS DNN模块实现即可实现非最大值抑制 所需要的参数是边界 框、 置信度、以及置信度阈值和NMS阈值# 第一个参数是存放边界框的列表第二个参数是存放置信度的列表第三个参数是自己设置的置信度第四个参数是关于threshold阈值# 返回的idxs是一个一维数组数组中的元素是保留下来的检测框boxes的索引位置idxs cv2.dnn.NMSBoxes(boxes, confidences, 0.5, 0.3)dets [] # 存放检测框的信息包括左上角横坐标纵坐标右下角横坐标纵坐标以及检测到的物体的置信度,用于目标跟踪if len(idxs) 0: # 存在检测框的话即检测框个数大于0for i in idxs.flatten(): # 循环检测出的每一个box# yolo模型可以识别很多目标因为我们在这里只是识别车所以只有目标是车的我们进行检测其他的忽略if LABELS[classIDs[i]] car:(x, y) (boxes[i][0], boxes[i][1]) # 得到检测框的左上角坐标(w, h) (boxes[i][2], boxes[i][3]) # 得到检测框的宽和高dets.append([x, y, x w, y h, confidences[i]]) # 将检测框的信息的放入dets中# 设置数据类型将整型数据转换为浮点数类型且保留小数点后三位np.set_printoptions(formatter{float: lambda x: {0:0.3f}.format(x)})# 将检测框数据转换为ndarray,其数据类型为浮点型dets np.asarray(dets)