车牌识别数据收集之自动化筛选工具

news2025/1/12 20:10:17

综述

最近在进行车牌识别的开发,在数据收集阶段除了那些特定的数据集(开源数据集),还需要自己收集一些数据,这些数据主要来自如爬虫、行车记录视频、非特定数据集,而在这些数据集中,只有少量的数据是我们需要的,大多数数据对于开发来说是无用的。所以,如何从这些数据中筛选出对我们有用的数据则是数据收集工作的重点,手动筛选可以作为一种筛选方式,但对于大量数据来说,却是最笨最费时的方式。这时便可以想到如何通过写代码的方式来自动化实现这个筛选过程。
在此做一个记录,下面进入正题。

准备工作

算法准备

要实现依靠代码的筛选,就必须要找到一套现成可用的车牌识别算法,只需编写少量代码便可调用使用。我们这里主要用到的是HyperLPR 高性能开源中文车牌识别框架。

依赖环境

python 3
Keras (>2.0.0)
Theano(>0.9) or Tensorflow(>1.1.x)
Numpy (>1.10)
Scipy (0.19.1)
OpenCV(>3.0)
Scikit-image (0.13.0)
PIL
imageio
shutil

开源框架代码地址

https://github.com/szad670401/HyperLPR

代码准备

自动化筛选流程确定

  • 确定筛选处理数据格式:图片、视频
  • 确定图片和视频的读取调用库:图片——opencv,视频——imageio
  • 确定图片和视频的读取方式:遍历读取
  • 编写遍历读取相关代码:
# 遍历读取图片
for parent, dirnames, filenames in os.walk(input_image_root_path):
        for filename in filenames:
            img_path = os.path.join(parent, filename)
            img_name = os.path.splitext(filename)[0]
            img_format = os.path.splitext(filename)[1]
            if img_format == ".jpg" or img_format == ".png":
                img = cv2.imread(img_path)
                # 进一步识别处理
# 遍历读取视频帧
vid = imageio.get_reader(input_video_path, 'ffmpeg')
        for num, frame in enumerate(vid):
        	# 根据帧采样间隔进行选取(对于非高速运动的视频,一般相隔太近的帧数据差异很小,没必要对每一帧进行识别)
            if num % frame_interval == 0:
                # 保存帧数据为图片
                image_path = output_image_root_path + "/" + str(num // frame_interval) + '.jpg'
                imageio.imwrite(image_path, frame)
                img = cv2.imread(image_path)
                # 进一步识别处理
  • 编写车牌识别相关代码:
# 预加载识别模型
model = pr.LPR("model/cascade.xml", "model/model12.h5", "model/ocr_plate_all_gru.h5")
# 获取识别结果
result = model.SimpleRecognizePlateByE2E(img)
  • 确定识别结果判断规则

非空(数量)判断:判断是否有识别到车牌或识别到的车牌数量,该判断主要确定待筛选图片中是否含有车牌对象,如果含有则保留,如果不含则剔除
尺寸判断:判断识别到的车牌尺寸是否符合要求,由于拍摄距离和照片分辨率的限制,经常会存在一些尺寸较小的图片,有时甚至看不清具体的车牌号信息,这样的数据对于模型训练来说,意义不大,所以也是需要过滤的

识别示例

完整代码

首先需要clone开源项目https://github.com/szad670401/HyperLPR,并在该项目目录下创建python文件

import cv2
import os
import imageio
import shutil
import HyperLPRLite as pr
import time

model = pr.LPR("model/cascade.xml", "model/model12.h5", "model/ocr_plate_all_gru.h5")

# 视频筛选
def getAndSaveVideoFrame(input_video_path, output_image_root_path, frame_interval):

    if (os.path.exists(output_image_root_path)) is False:
        os.makedirs(output_image_root_path)
    try:
        j = 0
        vid = imageio.get_reader(input_video_path, 'ffmpeg')
        for num, frame in enumerate(vid):
            if num % frame_interval == 0:
                image_path = output_image_root_path + "/" + str(num // frame_interval) + '.jpg'
                imageio.imwrite(image_path, frame)
                img = cv2.imread(image_path)
                results = model.SimpleRecognizePlateByE2E(img)
                if len(results)>0:
                    j += 1
                    match_num = 0
		            for result in results:
		            	# 识别框像素高不能小于64
		                if result[2][3] >= 64:
		                    match_num = match_num + 1
		            if match_num > 0:
		                print(image_path + "中存在车牌且尺寸符合要求:" + str(match_results))
		            else:
		                os.remove(image_path)
                else:
                    os.remove(image_path)    

        print("视频 " + input_video_path + " 抓帧成功,数量:" + str(j))

    except Exception as e:
        print("视频 " + input_video_path + " 文件损坏或非视频文件:" + str(e))

# 图片筛选
def getAndSaveImage(input_video_path, output_image_root_path):

    if (os.path.exists(output_image_root_path)) is False:
        os.makedirs(output_image_root_path)
	for parent, dirnames, filenames in os.walk(input_image_root_path):
        for filename in filenames:
            img_path = os.path.join(parent, filename)
            img_name = os.path.splitext(filename)[0]
            img_format = os.path.splitext(filename)[1]
            if img_format == ".jpg" or img_format == ".png":
                time_ = time.time()
                img = cv2.imread(img_path)
                results = model.SimpleRecognizePlateByE2E(img)
                if len(results)>0:
                    match_num = 0
                    for result in results:
                    	# 识别框像素高不能小于64
                        if result[2][3] >= 64:
                            match_num = match_num + 1
                    if match_num > 0:
                        new_file_name_path = os.path.join(output_image_root_path, str(time_) + "_" + img_name + img_format)
                        shutil.copyfile(img_path, new_file_name_path)
                        print(img_path + "存在符合要求的车牌识别结果:" + str(results))

至此,中文车牌识别的自动化筛选工具便开发完成了,最后,只需将需要将需要筛选的图片集或视频放入指定路径的文件夹下,设定好相关输出路径和规则,运行自动化筛选代码,只需等待一段时间便可以查看到筛选出的数据了,当然该模型识别未必百分百精确,也有可能出现误识别的情况,这时仍需要我们来手动筛选一遍,不过比起整个手动筛选的工作量,可以说是九牛一毛了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/145815.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

PCB结构和谐振(二)

PCB结构和谐振(一)实验研究在此章节中,我们通过不同的测试研究了旋转角度/复杂层叠/走线pitch和layout设计等,所有的测试都是基于Intel Delta L 4.0规范。旋转角度单层结构是一个简单的层叠,所以首先通过测试单层结构研…

成都远石无人机航测服务内容

成都远石无人机航测服务致力于为客户提供DEM、DSM、DOM、三维实景模型和机载激光雷达等数据成果,获得的数据成果在各个行业得到了应用和认可。相信大家对于DEM、DSM和DOM这些名词并不陌生,但对其内涵和差别却又比较模糊,接下来就讲一下这些数…

Android:OKhttp拦截器整理笔记

目录 正文 拦截器的自我实现 RetryAndFollowUpInterceptor BridgeInterceptor CacheInterceptor ConnectInterceptor CallServerInterceptor 运行一下 题外话 OkHttp是一个高效的HTTP库: 支持HTTP/2, HTTP/2通过使用多路复用技术在一个单独的TCP连接上支持并发, 通过…

Referer与XMLHttpRequest整理

Apache日志分割 1.原因 1.随着网络的访问量的增加,默认情况下Apache的单个日志文件也会越来越大。 2.日志文件占用磁盘空间很大 3.查看相关信息不方便2.对日志文件进行分割 1.Apache自带rotatelogs分割工具实现 2.第三方工具cronolog 分割3.配置日志分割(我用的p…

基于springboot+mybatis-plus+mysql+python+tensorflow2.0波导识别管理系统

基于springbootmybatis-plusmysqlpythontensorflow2.0波导识别管理系统一、系统介绍二、功能展示1.图片上传2.波导识别三、代码展示四、其它系统五、获取源码一、系统介绍 技术框架: 前端:vue 后端:springboot 算法:pythontensor…

用八叉树优化RayCasting

在之前的文章中,我们不得不等待 8 分钟来渲染一盏精灵灯和一个球体。 总而言之,我们询问每个像素是否有多个三角形之一相交。 这个场景包括: 4 个物体:1 个灯、2 个球体和 1 个平面34,378 个三角形:1 个球体没有三角形…

某音漂亮小姐姐视频合集一键下载,想看就看!

大家好,我是派森酱! 最近工作压力大,每天晚上回来基本洗洗就要睡了。但是总觉得一天就这么过去,有点遗憾,所以每天睡前躺床上刷刷抖音,看看美丽小姐姐,心情就会舒畅许多! 有些小姐姐…

架构师成长日记 - 01 4+1视图模型

文章目录 什么是软件架构什么是架构师?架构师的主要能力4+1视图模型逻辑视图(Logical View)开发视图(Development View)物理视图(Physical View)过程视图(Process View)场景视图(scenarios)软件建模语言什么是软件架构 软件架构是有关软件整体结构与组件的抽象描述,用于指导大…

StarkWare的Recursive STARKs

1. 引言 StarkWare的Recursive STARKs 为首个在以太坊主网上线的,针对通用计算的recursive stark proof方案: 递归证明目前已在以太坊主网上线: 扩容StarkEx app扩容StarkNet用于StarkWare的SaaS scaling engine用于permissionless rollup …

javaScript浅谈----asyncawait

什么是 async ? async/await 是 ES7 的标准,Promise 是 ES6 标准,async/await 这套 API 也是用来帮助我们写异步代码的,它是构建在 Promise 之上的。 async的特点: async 一般不单独使用,而是和 await 一…

3. 无重复字符的最长子串(滑动窗口)

文章目录题目描述暴力破解滑动窗口优化知识积累待解决题目描述 给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。 示例 1: 输入: s “abcabcbb” 输出: 3 解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。 示例 2: 输…

python 操作符介绍

python操作符分类:算数操作符;比较操作符;逻辑操作符;成员操作符;身份操作符; 1 算数操作符: 常用的算数操作符:; python如何执行除法: 许多编程语言中整数除法执行的…

另一半人马座,孟庭苇

我写过生于12月25日的半人马座桂纶镁《半人马座,桂纶镁》。射手座是11月23日-12月21日。而摩羯座的开始恰恰是:12月22日。而孟庭苇,恰恰就生于12月22日。她更是半人马座啊。1989年,20岁的孟庭苇出演铃木机车广告出道(没…

分享一套响应式自适应公司网站官网源码,带文字搭建教程

分享一套响应式自适应公司网站官网源码,带文字搭建教程。需要源码学习可私信我。 技术架构 PHP7.2 nginx mysql5.7 JS CSS HTML cnetos7以上 宝塔面板 系统介绍 1、四网合一企业网站管理系统支持在线升级(支持跨版本)、插件在线安装、系…

跳表SkipList介绍与实现

目录 一.跳表介绍 二.实现思路 (一).结点结构 (二).检索 (三).插入 (四).删除 三.实现代码 一.跳表介绍 跳表是一种随机化数据结构,主要用于快速检索数据。实质上…

JavaScript 函数

文章目录JavaScript 函数JavaScript 函数语法调用带参数的函数带有返回值的函数局部 JavaScript 变量全局 JavaScript 变量JavaScript 变量的生存期向未声明的 JavaScript 变量分配值笔记列表JavaScript 函数 函数是由事件驱动的或者当它被调用时执行的可重复使用的代码块。 实…

Go语言之容器总结

目录 1.值类型 1.1. 数组Array 数组遍历 数组初始化 值拷贝 内置函数len、cap 2. 引用数据类型 2.1. 切片slice 切片初始化 切片的内存布局 通过slice修改struct array值 用append内置函数操作切片(切片追加) slice自动扩容 slice中cap重新…

基于yolov5算法的安全帽头盔检测源码+模型,Pytorch开发,智能工地安全领域中头盔目标检测的应用

基于yolov5算法的安全帽头盔检测|Pytorch开发源码模型 本期给大家打开的是YOLOv5在智能工地安全领域中头盔目标检测的应用。 完整代码下载地址:基于yolov5算法的安全帽头盔检测源码模型 可视化界面演示: 💥💥💥新增…

opencv c++ Mat CUDA的编译与使用

Mat 构造函数 cv::Mat img ; //默认 定义了一个Mat img cv::imread("image.jpg");//除了直接读取,还有通过大小构造等cv::Mat img cv::imread("image.png", IMREAD_GRAYSCALE); cv::Mat img_novel img;转换 Mat::convertTo(Mat& m, in…

【自学Java】Java方法

Java方法 Java方法教程 在 Java 语言 中,方法就是一段可重复调用的代码段。在平时开发直接交流中,也有一些同学喜欢把方法叫做函数,这两个其实是一个概念。 Java语言方法详解 语法 public void fun(Object param1,...){//do something }…