ADD file via upload

main
phfr8ja45 5 months ago
parent c41f70202e
commit 2d5682e27c

@ -0,0 +1,182 @@
# yolov4-tiny目标检测
import cv2
import numpy as np
from myFunction import drawButton
#1导入yolov4-tiny网络模型结构
# 传入模型结构.cfg文件模型权重参数.weight文件
net = cv2.dnn.readNet('dnn_model\yolov4-tiny.cfg', 'dnn_model\yolov4-tiny.weights')
# 定义一个目标检测模型,将模型传进去
model = cv2.dnn_DetectionModel(net)
'''
设置模型的输入
size将输入的图像缩放至指定大小size越大检测效果越好但是检测速度越慢
scale像素值的缩放大小在opencv中每个像素值的范围在0-255之间而在神经网络中每个像素值在0-1之间
'''
model.setInputParams(size=(416, 416), scale=1/255)
#2获取分类文本的信息
classes = [] # 存放每个分类的名称
with open('dnn_model\classes.txt') as file_obj:
# 获取文本中的每一行
for class_name in file_obj.readlines():
# 删除文本中的换行符、空格等
class_name = class_name.strip()
# 将每个分类名保存到列表中
classes.append(class_name)
#3视频捕获
filepath = 'F:\\yolov4-tiny\\1.mp4'
cap = cv2.VideoCapture(filepath)
#4创建鼠事件
# 创建按钮,默认停用
button_class = False
button_index = None # 存放哪个按键被点亮了
# 定义鼠标回调函数
def click_button(event, x, y, flags, params):
# 调用外部变量
global button_class
global button_index
# 设置事鼠标件event为点击鼠标左键
if event == cv2.EVENT_LBUTTONDOWN:
# 检查鼠标的坐标是否在矩形框按键内部index代表第几个按钮
# 遍历每个矩形框,每个框包含四个角的坐标
for index, pt in enumerate(np.array(buttonList)): # 要转换成numpy类型
# 如果设为True计算鼠标左键距离矩形框的距离
is_inside = cv2.pointPolygonTest(pt, (x,y), False)
if is_inside > 0: # 鼠标在矩形框内部
print(f'click in the No.{index+1}', (x,y))
# 如果鼠标点击位置在矩形框内部,并且上一次没点击
if button_class == False:
# 激活按钮
button_class = True
# 激活哪个分类的检测框
button_index = index
# 如果鼠标点击位置不在矩形框内部
else:
button_class = False
#5创建窗口
cv2.namedWindow('Image') # 窗口名和显示图像的窗口名相同
# 设置鼠标回调,窗口名和上面相同,自定义回调函数
cv2.setMouseCallback('Image', click_button)
# 创建按钮
usenames = ['all', 'person', 'car', 'bus', 'truck']
button = drawButton(usenames)
#6定义检测框绘制函数
colorline = (0,255,0) # 角点线段颜色
angerline = 13 # 角点线段长度
def drawbbx(img, x, y, w, h, predName, score):
# 检测框
cv2.rectangle(img, (x, y), (x+w, y+h), (255,255,0), 1)
# 角点美化
cv2.line(img, (x,y), (x+angerline,y), colorline, 2)
cv2.line(img, (x,y), (x,y+angerline), colorline, 2)
cv2.line(img, (x+w,y), (x+w,y+angerline), colorline, 2)
cv2.line(img, (x+w,y), (x+w-angerline,y), colorline, 2)
cv2.line(img, (x,y+h), (x,y+h-angerline), colorline, 2)
cv2.line(img, (x,y+h), (x+angerline,y+h), colorline, 2)
cv2.line(img, (x+w,y+h), (x+w,y+h-angerline), colorline, 2)
cv2.line(img, (x+w,y+h), (x+w-angerline,y+h), colorline, 2)
# 显示预测的类别
cv2.putText(img, predName, (x,y+h+20), cv2.FONT_HERSHEY_COMPLEX, 1, (0,255,0), 2)
# 显示预测概率
cv2.putText(img, str(int(score*100))+'%', (x,y-5), cv2.FONT_HERSHEY_COMPLEX, 1, (0,255,255), 2)
#6对每一帧视频图像处理
while True:
# 返回是否读取成功ret和读取的帧图像frame
ret, frame = cap.read()
# 图像比较大把它缩小一点
frame = cv2.resize(frame, (1280,720))
# 视频比较短,循环播放
if cap.get(cv2.CAP_PROP_POS_FRAMES) == cap.get(cv2.CAP_PROP_FRAME_COUNT):
# 如果当前帧==总帧数那就重置当前帧为0
cap.set(cv2.CAP_PROP_POS_FRAMES, 0)
# 目标检测
'''
返回值
classids检测得到的类别
score检测得到的目标的概率
bbox检测框的85项信息
参数
confThreshold目标检测最小置信度
nmsThreshold非极大值抑制的自定义参数
'''
classids, scores, bboxes = model.detect(frame, 0.5, 0.3)
# 在画面上创建按钮
button.drawRec_many(frame)
# 获取所有矩形框的四个角的坐标
buttonList = button.recList
#7显示检测结果
# 遍历所有的检测框信息,把它们绘制出来
for class_id, score, bbox in zip(classids, scores, bboxes):
# 获取检测框的左上角坐标和宽高
x, y, w, h = bbox
# 获取检测框对应的分类名
class_name = classes[class_id]
# 遍历四个按键的名称
for index, name in enumerate(usenames):
# 设置检测条件只有检测到的类别是person并且鼠标点击位置在矩形框内
if class_name == name and index == button_index:
# 绘制class_name类别的检测框
drawbbx(frame, x, y, w, h, class_name, score)
elif name == 'all' and index == button_index:
# 绘制所有类别的检测框
drawbbx(frame, x, y, w, h, class_name, score)
# 显示图像
cv2.imshow('Image', frame) #窗口名,图像变量
if cv2.waitKey(30) & 0xFF==27: #每帧滞留1毫秒后消失
break
# 释放视频资源
cap.release()
cv2.destroyAllWindows()
Loading…
Cancel
Save