基于深度学习的车牌识别

如果你认为车牌只是车子的‘名字’,那么是时候让你见识一下,当科技赋予它‘超能力’时会发生什么?

上效果图;

这就是车牌识别的力量,下面是主函数代码:

# -*- coding: UTF-8 -*-
import argparse
import time
from pathlib import Path
import os
import cv2
import torch
import torch.backends.cudnn as cudnn
from numpy import random
import copy
import numpy as np
from models.experimental import attempt_load
from utils.datasets import letterbox
from utils.general import check_img_size, non_max_suppression_face, apply_classifier, scale_coords, xyxy2xywh, \strip_optimizer, set_logging, increment_path
from utils.plots import plot_one_box
from utils.torch_utils import select_device, load_classifier, time_synchronized
from utils.cv_puttext import cv2ImgAddText
from plate_recognition.plate_rec import get_plate_result, allFilePath, init_model, cv_imread
# from plate_recognition.plate_cls import cv_imread
from plate_recognition.double_plate_split_merge import get_split_mergeclors = [(255, 0, 0), (0, 255, 0), (0, 0, 255), (255, 255, 0), (0, 255, 255)]
danger = ['危', '险']def order_points(pts):  # 四个点按照左上 右上 右下 左下排列rect = np.zeros((4, 2), dtype="float32")s = pts.sum(axis=1)rect[0] = pts[np.argmin(s)]rect[2] = pts[np.argmax(s)]diff = np.diff(pts, axis=1)rect[1] = pts[np.argmin(diff)]rect[3] = pts[np.argmax(diff)]return rectdef four_point_transform(image, pts):  # 透视变换得到车牌小图# rect = order_points(pts)rect = pts.astype('float32')(tl, tr, br, bl) = rectwidthA = np.sqrt(((br[0] - bl[0]) ** 2) + ((br[1] - bl[1]) ** 2))widthB = np.sqrt(((tr[0] - tl[0]) ** 2) + ((tr[1] - tl[1]) ** 2))maxWidth = max(int(widthA), int(widthB))heightA = np.sqrt(((tr[0] - br[0]) ** 2) + ((tr[1] - br[1]) ** 2))heightB = np.sqrt(((tl[0] - bl[0]) ** 2) + ((tl[1] - bl[1]) ** 2))maxHeight = max(int(heightA), int(heightB))dst = np.array([[0, 0],[maxWidth - 1, 0],[maxWidth - 1, maxHeight - 1],[0, maxHeight - 1]], dtype="float32")M = cv2.getPerspectiveTransform(rect, dst)warped = cv2.warpPerspective(image, M, (maxWidth, maxHeight))return warpeddef load_model(weights, device):  # 加载检测模型model = attempt_load(weights, map_location=device)  # load FP32 modelreturn modeldef scale_coords_landmarks(img1_shape, coords, img0_shape, ratio_pad=None):  # 返回到原图坐标# Rescale coords (xyxy) from img1_shape to img0_shapeif ratio_pad is None:  # calculate from img0_shapegain = min(img1_shape[0] / img0_shape[0], img1_shape[1] / img0_shape[1])  # gain  = old / newpad = (img1_shape[1] - img0_shape[1] * gain) / 2, (img1_shape[0] - img0_shape[0] * gain) / 2  # wh paddingelse:gain = ratio_pad[0][0]pad = ratio_pad[1]coords[:, [0, 2, 4, 6]] -= pad[0]  # x paddingcoords[:, [1, 3, 5, 7]] -= pad[1]  # y paddingcoords[:, :8] /= gain# clip_coords(coords, img0_shape)coords[:, 0].clamp_(0, img0_shape[1])  # x1coords[:, 1].clamp_(0, img0_shape[0])  # y1coords[:, 2].clamp_(0, img0_shape[1])  # x2coords[:, 3].clamp_(0, img0_shape[0])  # y2coords[:, 4].clamp_(0, img0_shape[1])  # x3coords[:, 5].clamp_(0, img0_shape[0])  # y3coords[:, 6].clamp_(0, img0_shape[1])  # x4coords[:, 7].clamp_(0, img0_shape[0])  # y4# coords[:, 8].clamp_(0, img0_shape[1])  # x5# coords[:, 9].clamp_(0, img0_shape[0])  # y5return coordsdef get_plate_rec_landmark(img, xyxy, conf, landmarks, class_num, device, plate_rec_model,is_color=False):  # 获取车牌坐标以及四个角点坐标并获取车牌号h, w, c = img.shaperesult_dict = {}tl = 1 or round(0.002 * (h + w) / 2) + 1  # line/font thicknessx1 = int(xyxy[0])y1 = int(xyxy[1])x2 = int(xyxy[2])y2 = int(xyxy[3])height = y2 - y1landmarks_np = np.zeros((4, 2))rect = [x1, y1, x2, y2]for i in range(4):point_x = int(landmarks[2 * i])point_y = int(landmarks[2 * i + 1])landmarks_np[i] = np.array([point_x, point_y])class_label = int(class_num)  # 车牌的的类型0代表单牌,1代表双层车牌roi_img = four_point_transform(img, landmarks_np)  # 透视变换得到车牌小图if class_label:  # 判断是否是双层车牌,是双牌的话进行分割后然后拼接roi_img = get_split_merge(roi_img)if not is_color:plate_number, rec_prob = get_plate_result(roi_img, device, plate_rec_model, is_color=is_color)  # 对车牌小图进行识别else:plate_number, rec_prob, plate_color, color_conf = get_plate_result(roi_img, device, plate_rec_model,is_color=is_color)# cv2.imwrite("roi.jpg",roi_img)result_dict['rect'] = rect  # 车牌roi区域result_dict['detect_conf'] = conf  # 检测区域得分result_dict['landmarks'] = landmarks_np.tolist()  # 车牌角点坐标result_dict['plate_no'] = plate_number  # 车牌号result_dict['rec_conf'] = rec_prob  # 每个字符的概率result_dict['roi_height'] = roi_img.shape[0]  # 车牌高度result_dict['plate_color'] = ""if is_color:result_dict['plate_color'] = plate_color  # 车牌颜色result_dict['color_conf'] = color_conf  # 颜色得分result_dict['plate_type'] = class_label  # 单双层 0单层 1双层return result_dictdef detect_Recognition_plate(model, orgimg, device, plate_rec_model, img_size, is_color=False):  # 获取车牌信息# Load model# img_size = opt_img_sizeconf_thres = 0.3  # 得分阈值iou_thres = 0.5  # nms的iou值dict_list = []# orgimg = cv2.imread(image_path)  # BGRimg0 = copy.deepcopy(orgimg)assert orgimg is not None, 'Image Not Found 'h0, w0 = orgimg.shape[:2]  # orig hwr = img_size / max(h0, w0)  # resize image to img_sizeif r != 1:  # always resize down, only resize up if training with augmentationinterp = cv2.INTER_AREA if r < 1 else cv2.INTER_LINEARimg0 = cv2.resize(img0, (int(w0 * r), int(h0 * r)), interpolation=interp)imgsz = check_img_size(img_size, s=model.stride.max())  # check img_sizeimg = letterbox(img0, new_shape=imgsz)[0]  # 检测前处理,图片长宽变为32倍数,比如变为640X640# img =process_data(img0)# Convertimg = img[:, :, ::-1].transpose(2, 0, 1).copy()  # BGR to RGB, to 3x416x416  图片的BGR排列转为RGB,然后将图片的H,W,C排列变为C,H,W排列# Run inferencet0 = time.time()img = torch.from_numpy(img).to(device)img = img.float()  # uint8 to fp16/32img /= 255.0  # 0 - 255 to 0.0 - 1.0if img.ndimension() == 3:img = img.unsqueeze(0)# Inference# t1 = time_synchronized()/pred = model(img)[0]# t2=time_synchronized()# print(f"infer time is {(t2-t1)*1000} ms")# Apply NMSpred = non_max_suppression_face(pred, conf_thres, iou_thres)# print('img.shape: ', img.shape)# print('orgimg.shape: ', orgimg.shape)# Process detectionsfor i, det in enumerate(pred):  # detections per imageif len(det):# Rescale boxes from img_size to im0 sizedet[:, :4] = scale_coords(img.shape[2:], det[:, :4], orgimg.shape).round()# Print resultsfor c in det[:, -1].unique():n = (det[:, -1] == c).sum()  # detections per classdet[:, 5:13] = scale_coords_landmarks(img.shape[2:], det[:, 5:13], orgimg.shape).round()for j in range(det.size()[0]):xyxy = det[j, :4].view(-1).tolist()conf = det[j, 4].cpu().numpy()landmarks = det[j, 5:13].view(-1).tolist()class_num = det[j, 13].cpu().numpy()result_dict = get_plate_rec_landmark(orgimg, xyxy, conf, landmarks, class_num, device, plate_rec_model,is_color=is_color)dict_list.append(result_dict)return dict_list# cv2.imwrite('result.jpg', orgimg)def draw_result(orgimg, dict_list, is_color=False):  # 车牌结果画出来result_str = ""for result in dict_list:rect_area = result['rect']x, y, w, h = rect_area[0], rect_area[1], rect_area[2] - rect_area[0], rect_area[3] - rect_area[1]padding_w = 0.05 * wpadding_h = 0.11 * hrect_area[0] = max(0, int(x - padding_w))rect_area[1] = max(0, int(y - padding_h))rect_area[2] = min(orgimg.shape[1], int(rect_area[2] + padding_w))rect_area[3] = min(orgimg.shape[0], int(rect_area[3] + padding_h))height_area = result['roi_height']landmarks = result['landmarks']result_p = result['plate_no']if result['plate_type'] == 0:  # 单层result_p += " " + result['plate_color']else:  # 双层result_p += " " + result['plate_color'] + "双层"result_str += result_p + " "for i in range(4):  # 关键点cv2.circle(orgimg, (int(landmarks[i][0]), int(landmarks[i][1])), 5, clors[i], -1)cv2.rectangle(orgimg, (rect_area[0], rect_area[1]), (rect_area[2], rect_area[3]), (0, 0, 255), 2)  # 画框labelSize = cv2.getTextSize(result_p, cv2.FONT_HERSHEY_SIMPLEX, 0.5, 1)  # 获得字体的大小if rect_area[0] + labelSize[0][0] > orgimg.shape[1]:  # 防止显示的文字越界rect_area[0] = int(orgimg.shape[1] - labelSize[0][0])orgimg = cv2.rectangle(orgimg, (rect_area[0], int(rect_area[1] - round(1.6 * labelSize[0][1]))),(int(rect_area[0] + round(1.2 * labelSize[0][0])), rect_area[1] + labelSize[1]),(255, 255, 255), cv2.FILLED)  # 画文字框,背景白色if len(result) >= 1:orgimg = cv2ImgAddText(orgimg, result_p, rect_area[0], int(rect_area[1] - round(1.6 * labelSize[0][1])),(0, 0, 0), 21)# orgimg=cv2ImgAddText(orgimg,result_p,rect_area[0]-height_area,rect_area[1]-height_area-10,(0,255,0),height_area)print(result_str)return orgimgdef get_second(capture):if capture.isOpened():rate = capture.get(5)  # 帧速率FrameNumber = capture.get(7)  # 视频文件的帧数duration = FrameNumber / rate  # 帧速率/视频总帧数 是时间,除以60之后单位是分钟return int(rate), int(FrameNumber), int(duration)if __name__ == '__main__':parser = argparse.ArgumentParser()parser.add_argument('--detect_model', nargs='+', type=str, default='weights/plate_detect.pt',help='model.pt path(s)')  # 检测模型parser.add_argument('--rec_model', type=str, default='weights/plate_rec_color.pth',help='model.pt path(s)')  # 车牌识别+颜色识别模型parser.add_argument('--is_color', type=bool, default=True, help='plate color')  # 是否识别颜色parser.add_argument('--image_path', type=str, default='imgs', help='source')  # 图片路径parser.add_argument('--img_size', type=int, default=640, help='inference size (pixels)')  # 网络输入图片大小parser.add_argument('--output', type=str, default='result', help='source')  # 图片结果保存的位置parser.add_argument('--video', type=str, default='video/1.mp4', help='source')  # 视频的路径device = torch.device("cuda" if torch.cuda.is_available() else "cpu")  # 使用gpu还是cpu进行识别# device =torch.device("cpu")opt = parser.parse_args()print(opt)save_path = opt.outputcount = 0if not os.path.exists(save_path):os.mkdir(save_path)detect_model = load_model(opt.detect_model, device)  # 初始化检测模型plate_rec_model = init_model(device, opt.rec_model, is_color=opt.is_color)  # 初始化识别模型# 算参数量total = sum(p.numel() for p in detect_model.parameters())total_1 = sum(p.numel() for p in plate_rec_model.parameters())print("detect params: %.2fM,rec params: %.2fM" % (total / 1e6, total_1 / 1e6))# plate_color_model =init_color_model(opt.color_model,device)time_all = 0time_begin = time.time()video_name = opt.videocapture = cv2.VideoCapture(video_name)print(video_name)# print(count, opt.image_path, end=" ")# img = cv_imread(opt.image_path)# if img.shape[-1] == 4:#     img = cv2.cvtColor(img, cv2.COLOR_BGRA2BGR)# # detect_one(model,img_path,device)# dict_list = detect_Recognition_plate(detect_model, img, device, plate_rec_model, opt.img_size,#                                      is_color=opt.is_color)# ori_img = draw_result(img, dict_list)# img_name = os.path.basename(opt.image_path)# save_img_path = os.path.join(save_path, img_name)# cv2.imwrite(save_img_path, ori_img)

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

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

相关文章

服务器硬件:裸金属安装 VMware ESXi

写在前面 工作中遇到&#xff0c;简单整理博文内容涉及 裸金属安装VMware ESXi 基本步骤理解不足小伙伴帮忙指正 不必太纠结于当下&#xff0c;也不必太忧虑未来&#xff0c;当你经历过一些事情的时候&#xff0c;眼前的风景已经和从前不一样了。——村上春树 一、准备工作 确…

1. 房屋租赁管理系统(Java项目 springboot/vue)

1.此系统的受众 1.1 在校学习的学生&#xff0c;可用于日常学习使用或是毕业设计使用 1.2 毕业一到两年的开发人员&#xff0c;用于锻炼自己的独立功能模块设计能力&#xff0c;增强代码编写能力。 1.3 亦可以部署为商化项目使用。 2. 技术栈 jdk8springbootvue2mysq5.7&8…

基于SpringBoot + Vue实现的家政服务管理系统设计与实现+毕业论文+答辩PPT+指导搭建视频(包运行成功)

目录 项目介绍 论文展示 资源获取 项目介绍 家政服务管理平台是一个管理信息系统&#xff0c;为了宣传的需要&#xff0c;为了给用户提供方便快捷的服务&#xff0c;从而设计了家政服务管理平台。管理员可以通过这个系统把家政服务信息发布出去&#xff0c;可以方便用户快…

终端安全管理软件哪个好?

终端安全管理软件是保障企业信息安全的重要工具。 它们能够有效地防范恶意软件、黑客攻击和其他安全威胁&#xff0c;并提供多方面的终端设备安全保护措施。 终端安全软件的功能和保护机制各不相同&#xff0c;这就需要企业根据自身的需求和情况来进行评估和选择。 下面总结了…

spring的常用注解

目录 1.前言 2.web url映射 2.1RequestMapping 2.2PostMapping 2.3GetMapping 3.参数接受和接口响应 3.1RequestParam 3.2RequstBoby 3.3ResponseBoby 3.4RestController 4.bean的存储 4.1Controller 4.2Service 4.3Repository 4.4Compontent 4.5Configuration …

短视频生成背景文字工具(前端工具)

过年这两天有些无聊就刷刷抖音&#xff0c;刷着刷着自己也蠢蠢欲动&#xff0c;想发上几个&#xff0c;可是却找不到合适自己的模板。由于个人喜欢一些古诗文之类的&#xff0c;所以自己简单的编写了一个小工具&#xff0c;如下图&#xff1a; 当设置好了之后&#xff0c;将浏…

关于Spring Aop的通知类型

一、概述 1.1 通知类型 为了符合各种流程处理&#xff0c;通知类型提供了5种&#xff0c;可以对目标方法进行全方位处理&#xff0c;如下所示&#xff1a; 通知类型说明前置通知&#xff08;Before advice&#xff09;在某连接点之前执行的通知&#xff0c;但这个通知不能阻止…

Python数据分析实验二:Python数据预处理

目录 一、实验目的与要求二、实验任务三、主要程序清单和运行结果&#xff08;一&#xff09;对chipotle.csv文件的销售数据进行分析&#xff08;二&#xff09;对描述泰坦尼克号成员的信息进行可视化和相关分析 四、实验体会 一、实验目的与要求 1、目的&#xff1a;   掌握…

linux kernel内存泄漏检测工具之slub debug

一、背景 slub debug 是一个debug集&#xff0c;聚焦于kmem_cache 分配机制的slub内存&#xff08;比如kmalloc&#xff09;&#xff0c;这部分内存在内核中使用最频繁&#xff0c;slub debug其中有相当部分是用来处理内存踩踏&#xff0c;内存use after free 等异常的&#x…

创建electron,解决包清理的问题,解决镜像源卡住下载时间长

我的电脑用户名是Anyphasy,我的node.js安装在D:\developp\nodejss18.18.0 使用npm config get prefix查看node.js安装路径 npm config get prefix 创建electron 创建package.json文件,它里面记载了你的electron版本,项目描述,以及启动命令等信息 npm init -y 先查看你自己的…

禅道项目管理系统身份认证绕过漏洞

禅道项目管理系统身份认证绕过漏洞 1.漏洞描述 禅道项目管理软件是国产的开源项目管理软件&#xff0c;专注研发项目管理&#xff0c;内置需求管理、任务管理、bug管理、缺陷管理、用例管理、计划发布等功能&#xff0c;完整覆盖了研发项目管理的核心流程。 禅道项目管理系统…

手写一个RNN前向传播以及反向传播

前向传播 根据公式 st tanh (Uxt Wst-1 ba) ot softmax(Vst by ) m 3 词的个数 n 5 import numpy as np import tensorflow as tf # 单个cell 的前向传播过程 # 两个输入&#xff0c;x_t&#xff0c;s_prev,parameters def rnn_cell_forward(x_t,s_prev,parameter…

运算符重载(1)

1.加号运算符重载&#xff0c;这里用编译器统一的名称operator代替函数名 #include<iostream> using namespace std; //1.成员函数的加号重载 //2.全局函数的加号重载 class Person { public:Person() {};//1.成员函数的加号重载//Person operator(Person& p)//{// P…

前端HTML5学习2(新增多媒体标签,H5的兼容性处理)

前端HTML5学习2新增多媒体标签&#xff0c;H5的兼容性处理&#xff09; 分清标签和属性新增多媒体标签新增视频标签新增音频标签新增全局属性 H5的兼容性处理 分清标签和属性 标签&#xff08;HTML元素&#xff09;和属性&#xff0c;标签定义了内容的类型或结构&#xff0c;而…

k8s学习(三十七)centos下离线部署kubernetes1.30(高可用)

文章目录 准备工作1、升级操作系统内核1.1、查看操作系统和内核版本1.2、下载内核离线升级包1.3、升级内核1.4、确认内核版本 2、修改主机名/hosts文件2.1、修改主机名2.2、修改hosts文件 3、关闭防火墙4、关闭SELINUX配置5、时间同步5.1、下载NTP5.2、卸载5.3、安装5.4、配置5…

BPE、Wordpiece、Unigram、SpanBERT等Tokenizer细节总结

BPE(Byte Pair Encoding) GPT-2和Roberta用的是这种&#xff0c;不会产生[UNK]这个unknown字符 这部分部分摘录自https://martinlwx.github.io/zh-cn/the-bpe-tokenizer/ 看以下code例子就足够理解了&#xff0c;核心是维护self.merges&#xff08;维护一个pair->str的字…

[蓝桥杯2024]-Reverse:rc4解析(对称密码rc4)

无壳 查看ida 这里应该运行就可以得flag&#xff0c;但是这个程序不能直接点击运行 按照伪代码写exp 完整exp&#xff1a; keylist(gamelab) content[0xB6,0x42,0xB7,0xFC,0xF0,0xA2,0x5E,0xA9,0x3D,0x29,0x36,0x1F,0x54,0x29,0x72,0xA8, 0x63,0x32,0xF2,0x44,0x8B,0x85,0x…

如何在 Visual Studio 中通过 NuGet 添加包

在安装之前要先确定Nuget的包源是否有问题。 Visual Studio中怎样更改Nuget程序包源-CSDN博客 1.图形界面安装 打开您的项目&#xff0c;并在解决方案资源管理器中选择您的项目。单击“项目”菜单&#xff0c;然后选择“管理 NuGet 程序包”选项。在“NuGet 包管理器”窗口中…

详解如何品味品深茶的精髓

在众多的茶品牌中&#xff0c;品深茶以其独特的韵味和深厚的文化底蕴&#xff0c;赢得了众多茶友的喜爱。今天&#xff0c;让我们一同探寻品深茶的精髓&#xff0c;品味其独特的魅力。 品深茶&#xff0c;源自中国传统茶文化的精髓&#xff0c;承载着世代茶人的智慧与匠心。这…

03-MVC执行流程-参数解析与Model

重要组件 准备Model&#xff0c;Controller Configuration public class WebConfig {ControllerAdvicestatic class MyControllerAdvice {ModelAttribute("b")public String bar() {return "bar";}}Controllerstatic class Controller1 {ResponseStatus(H…