有时候需要在一个长视频中找到某台车辆出现的位置,在几分钟的视频还可以人工操作,过长的视频中去寻找则十分枯燥,这里介绍一种方法,通过Python&HyperLPR自动寻找车辆在视频中出现的时间点,再根据时间点去翻看视频,这样能减轻大量的枯燥工作。
一、准备工作
开发环境:Win10、Python3.7
1、简述
这里主要使用HyperLPR进行车牌识别。
HyperLPR是一个基于深度学习的高性能中文车牌识别开源项目,github地址是:https://github.com/zeusees/HyperLPR,由python语言编写,同时还支持Linux、Android、iOS、Windows等各主流平台。
目前已经支持的车牌类型包括:
- 单行蓝牌
- 单行黄牌
- 新能源车牌
- 白色警用车牌
- 使馆/港澳车牌
- 教练车牌
- 双层黄牌
HyperLPR的检测流程:
1、使用opencv的HAAR Cascade检测车牌大致位置
2、Extend检测到的大致位置的矩形区域
3、使用类似于MSER的方式的多级二值化和RANSAC拟合车牌的上下边界
4、使用CNN Regression回归车牌左右边界
5、使用基于纹理场的算法进行车牌校正倾斜
6、使用CNN滑动窗切割字符
7、使用CNN识别字符
2、安装HyperLPR库
pip install hyperlpr
二、寻找车辆在视频中出现的时间点
1、测试数据
在网上随便截取了一小段视频,作为测试数据。
2、代码
# -*- coding: utf-8 -*-
from hyperlpr import *
import cv2 as cv
capture = cv.VideoCapture('D:/Products/Python/work/VideoFaceCapture/car.mp4') # 导入视频 车牌京APL428
car_num = "京APL428" #需要查询的车牌号码
video_time = [] #存储出现的时间点
i = 0
s = 0
fps = int(capture.get(cv.CAP_PROP_FPS)) # 获取视频帧率
print("视频帧数为" + str(fps))
all_frames = int(capture.get(cv.CAP_PROP_FRAME_COUNT)) # 获取视频总帧数
print("视频时长为" + str(all_frames / fps) + "秒")
while (True):
ret, frame = capture.read() # 读取成功后 ret 返回为为布尔值True,frame返回读取的一帧图像
# 每秒只比对一帧,提高效率
if (i % fps == 0):
s = i / fps + 1
print("获取第" + str(s) + "秒")
#开始识别
rgb_frame = frame[:, :, ::-1]
result = HyperLPR_plate_recognition(rgb_frame)
if(result):
if(float(result[0][1]) > 0.9):
print("检测到车牌号码:" + result[0][0])
if(result[0][0] == car_num):
video_time.append(s)
i = i + 1
#视频结束,退出
if(i - all_frames == 0):
break;
print("结束")
print("该车辆在视频中出现在以下时间点(秒):")
print(video_time)
capture.release()
cv.destroyAllWindows()
3、测试效果
对每一秒视频进行了分析,可以看到,能够准确的将该车辆出现的时间的标记出来。
三、可能出现的问题
当写完代码,感觉一切正常,运行的时候却报错了。
关键的错误就是这个:
AttributeError: module ‘cv2.cv2’ has no attribute 'estimateRigidTransform’
opencv 4.5之后 cv2.estimateRigidTransform()方法已经停用,可以使用cv2.estimateAffine2D(),cv2.estimateAffinePartial2D()来替代。
将"D:\ProgramData\Anaconda3\envs\python37\Lib\site-packages\hyperlpr\hyperlpr.py"中
mat_ = cv2.estimateRigidTransform(org_pts, target_pts, True)
更换为
mat_, _ = cv2.estimateAffinePartial2D(org_pts, target_pts, True)