一、项目概述

本次项目目标是实现对自动生成的带有各种噪声的车牌识别。在噪声干扰情况下,车牌字符分割较困难,此次车牌识别是将车牌7个字符同时训练,字符包括31个省份简称、10个阿拉伯数字、24个英文字母('O'和'I'除外),共有65个类别,7个字符使用单独的loss函数进行训练。

(运行环境:tensorflow1.14.0-GPU版)

二、生成车牌数据集

import os

import cv2 as cv

import numpy as np

from math import *

from PIL import ImageFont

from PIL import Image

from PIL import ImageDraw

index = {"京": 0, "沪": 1, "津": 2, "渝": 3, "冀": 4, "晋": 5, "蒙": 6, "辽": 7, "吉": 8, "黑": 9,

"苏": 10, "浙": 11, "皖": 12, "闽": 13, "赣": 14, "鲁": 15, "豫": 16, "鄂": 17, "湘": 18, "粤": 19,

"桂": 20, "琼": 21, "川": 22, "贵": 23, "云": 24, "藏": 25, "陕": 26, "甘": 27, "青": 28, "宁": 29,

"新": 30, "0": 31, "1": 32, "2": 33, "3": 34, "4": 35, "5": 36, "6": 37, "7": 38, "8": 39,

"9": 40, "A": 41, "B": 42, "C": 43, "D": 44, "E": 45, "F": 46, "G": 47, "H": 48, "J": 49,

"K": 50, "L": 51, "M": 52, "N": 53, "P": 54, "Q": 55, "R": 56, "S": 57, "T": 58, "U": 59,

"V": 60, "W": 61, "X": 62, "Y": 63, "Z": 64}

chars = ["京", "沪", "津", "渝", "冀", "晋", "蒙", "辽", "吉", "黑",

"苏", "浙", "皖", "闽", "赣", "鲁", "豫", "鄂", "湘", "粤",

"桂", "琼", "川", "贵", "云", "藏", "陕", "甘", "青", "宁",

"新", "0", "1", "2", "3", "4", "5", "6", "7", "8",

"9", "A", "B", "C", "D", "E", "F", "G", "H", "J",

"K", "L", "M", "N", "P", "Q", "R", "S", "T", "U",

"V", "W", "X", "Y", "Z"]

def AddSmudginess(img, Smu):

"""

模糊处理

:param img: 输入图像

:param Smu: 模糊图像

:return: 添加模糊后的图像

"""

rows = r(Smu.shape[0] - 50)

cols = r(Smu.shape[1] - 50)

adder = Smu[rows:rows + 50, cols:cols + 50]

adder = cv.resize(adder, (50, 50))

img = cv.resize(img,(50,50))

img = cv.bitwise_not(img)

img = cv.bitwise_and(adder, img)

img = cv.bitwise_not(img)

return img

def rot(img, angel, shape, max_angel):

"""

添加透视畸变

"""

size_o = [shape[1], shape[0]]

size = (shape[1]+ int(shape[0] * cos((float(max_angel ) / 180) * 3.14)), shape[0])

interval = abs(int(sin((float(angel) / 180) * 3.14) * shape[0]))

pts1 = np.float32([[0, 0], [0, size_o[1]], [size_o[0], 0], [size_o[0], size_o[1]]])

if angel > 0:

pts2 = np.float32([[interval, 0], [0, size[1]], [size[0], 0], [size[0] - interval, size_o[1]]])

else:

pts2 = np.float32([[0, 0], [interval, size[1]], [size[0] - interval, 0], [size[0], size_o[1]]])

M = cv.getPerspectiveTransform(pts1, pts2)

dst = cv.warpPerspective(img, M, size)

return dst

def rotRandrom(img, factor, size):

"""

添加放射畸变

:param img: 输入图像

:param factor: 畸变的参数

:param size: 图片目标尺寸

:return: 放射畸变后的图像

"""

shape = size

pts1 = np.float32([[0, 0], [0, shape[0]], [shape[1], 0], [shape[1], shape[0]]])

pts2 = np.float32([[r(factor), r(factor)], [r(factor), shape[0] - r(factor)], [shape[1] - r(factor), r(factor)],

[shape[1] - r(factor), shape[0] - r(factor)]])

M = cv.getPerspectiveTransform(pts1, pts2)

dst = cv.warpPerspective(img, M, size)

return dst

def tfactor(img):

"""

添加饱和度光照的噪声

"""

hsv = cv.cvtColor(img,cv.COLOR_BGR2HSV)

hsv[:, :, 0] = hsv[:, :, 0] * (0.8 + np.random.random() * 0.2)

hsv[:, :, 1] = hsv[:, :, 1] * (0.3 + np.random.random() * 0.7)

hsv[:, :, 2] = hsv[:, :, 2] * (0.2 + np.random.random() * 0.8)

img = cv.cvtColor(hsv, cv.COLOR_HSV2BGR)

return img

def random_envirment(img, noplate_bg):

"""

添加自然环境的噪声, noplate_bg为不含车牌的背景图

"""

bg_index = r(len(noplate_bg))

env = cv.imread(noplate_bg[bg_index])

env = cv.resize(env, (img.shape[1], img.shape[0]))

bak = (img == 0)

bak = bak.astype(np.uint8) * 255

inv = cv.bitwise_and(bak, env)

img = cv.bitwise_or(inv, img)

return img

def GenCh(f, val):

"""

生成中文字符

"""

img = Image.new("RGB", (45, 70), (255, 255, 255))

draw = ImageDraw.Draw(img)

draw.text((0, 3), val, (0, 0, 0), font=f)

img = img.resize((23, 70))

A = np.array(img)

return A

def GenCh1(f, val):

"""

生成英文字符

"""

img =Image.new("RGB", (23, 70), (255, 255, 255))

draw = ImageDraw.Draw(img)

draw.text((0, 2), val, (0, 0, 0), font=f) # val.decode('utf-8')

A = np.array(img)

return A

def AddGauss(img, level):

"""

添加高斯模糊

"""

return cv.blur(img, (level * 2 + 1, level * 2 + 1))

def r(val):

return int(np.random.random() * val)

def AddNoiseSingleChannel(single):

"""

添加高斯噪声

"""

diff = 255 - single.max()

noise = np.random.normal(0, 1 + r(6), single.shape)

noise = (noise - noise.min()) / (noise.max() - noise.min())

noise *= diff

# noise= noise.astype(np.uint8)

dst = single + noise

return dst

def addNoise(img): # sdev = 0.5,avg=10

img[:, :, 0] = AddNoiseSingleChannel(img[:, :, 0])

img[:, :, 1] = AddNoiseSingleChannel(img[:, :, 1])

img[:, :, 2] = AddNoiseSingleChannel(img[:, :, 2])

return img

class GenPlate:

def __init__(self, fontCh, fontEng, NoPlates):

self.fontC = ImageFont.truetype(fontCh, 43, 0)

self.fontE = ImageFont.truetype(fontEng, 60, 0)

self.img = np.array(Image.new("RGB", (226, 70),(255, 255, 255)))

self.bg = cv.resize(cv.imread("data\\images\\template.bmp"), (226, 70)) # template.bmp:车牌背景图

self.smu = cv.imread("data\\images\\smu2.jpg") # smu2.jpg:模糊图像

self.noplates_path = []

for parent, parent_folder, filenames in os.walk(NoPlates):

for filename in filenames:

path = parent + "\\" + filename

self.noplates_path.append(path)

def draw(self, val):

offset = 2

self.img[0:70, offset+8:offset+8+23] = GenCh(self.fontC, val[0])

self.img[0:70, offset+8+23+6:offset+8+23+6+23] = GenCh1(self.fontE, val[1])

for i in range(5):

base = offset + 8 + 23 + 6 + 23 + 17 + i * 23 + i * 6

self.img[0:70, base:base+23] = GenCh1(self.fontE, val[i+2])

return self.img

def generate(self, text):

if len(text) == 7:

fg = self.draw(text) # decode(encoding="utf-8")

fg = cv.bitwise_not(fg)

com = cv.bitwise_or(fg, self.bg)

com = rot(com, r(60)-30, com.shape,30)

com = rotRandrom(com, 10, (com.shape[1], com.shape[0]))

com = tfactor(com)

com = random_envirment(com, self.noplates_path)

com = AddGauss(com, 1+r(4))

com = addNoise(com)

return com

@staticmethod

def genPlateString(pos, val):

"""

生成车牌string,存为图片

生成车牌list,存为label

"""

plateStr = ""

plateList=[]

box = [0, 0, 0, 0, 0, 0, 0]

if pos != -1:

box[pos] = 1

for unit, cpos in zip(box, range(len(box))):

if unit == 1:

plateStr += val

plateList.append(val)

else:

if cpos == 0:

plateStr += chars[r(31)]

plateList.append(plateStr)

elif cpos == 1:

plateStr += chars[41 + r(24)]

plateList.append(plateStr)

else:

plateStr += chars[31 + r(34)]

plateList.append(plateStr)

plate = [plateList[0]]

b = [plateList[i][-1] for i in range(len(plateList))]

plate.extend(b[1:7])

return plateStr, plate

@staticmethod

def genBatch(batchsize, outputPath, size):

"""

将生成的车牌图片写入文件夹,对应的label写入label.txt

:param batchsize: 批次大小

:param outputPath: 输出图像的保存路径

:param size: 输出图像的尺寸

:return: None

"""

if not os.path.exists(outputPath):

os.mkdir(outputPath)

outfile = open('data\\plate\\label.txt', 'w', encoding='utf-8')

for i in range(batchsize):

plateStr, plate = G.genPlateString(-1, -1)

# print(plateStr, plate)

img = G.generate(plateStr)

img = cv.resize(img, size)

cv.imwrite(outputPath + "\\" + str(i).zfill(2) + ".jpg", img)

outfile.write(str(plate) + "\n")

if __name__ == '__main__':

G = GenPlate("data\\font\\platech.ttf", 'data\\font\\platechar.ttf', "data\\NoPlates")

G.genBatch(101, 'data\\plate', (272, 72))

python车牌识别系统开源代码_Python+Tensorflow+CNN实现车牌识别的示例代码相关推荐

  1. python简单目标检测代码_Python Opencv实现单目标检测的示例代码

    一 简介 目标检测即为在图像中找到自己感兴趣的部分,将其分割出来进行下一步操作,可避免背景的干扰.以下介绍几种基于opencv的单目标检测算法,算法总体思想先尽量将目标区域的像素值全置为1,背景区域全 ...

  2. python qq自动发消息软件_Python之qq自动发消息的示例代码

    准备:pip install win32gui 可能遇到的麻烦: No module named 'win32gui' 的解决方法(踩坑之旅) 源码: import win32gui import w ...

  3. python修改自己的代码_python修改微信和支付宝步数的示例代码

    项目意义 如果你想在支付宝蚂蚁森林收集很多能量种树,为环境绿化出一份力量,又或者是想每天称霸微信运动排行榜装逼,却不想出门走路,那么该python脚本可以帮你实现. 实现方法 手机安装第三方软件乐心健 ...

  4. python遥感影像分类代码_Python 实现遥感影像波段组合的示例代码

    最近要做个遥感相关的小系统,需要波段组合功能,网上找了可以使用ArcGIS安装时自带的arcpy包,但是Python3.7不能使用现有ArcGIS10.2版本,也不想再装其他版本,所以只能自己想了个办 ...

  5. python随机生成四位验证码的代码_Python random随机生成6位验证码示例代码

    随机生成6位验证码代码 # -*- coding: utf-8 -*- import random def generate_verification_code(): ''' randomly gen ...

  6. python实现图片转字符画_Python实现图片转字符画的示例代码

    初学Python,在网上看到Python图片转字符画的教程,我也来尝试下. 首先我们要用到Python的PIL库的Image模块,PIL(Python Imaging Library)库是Python ...

  7. python数据统计代码_Python 数据的累加与统计的示例代码

    问题 你需要处理一个很大的数据集并需要计算数据总和或其他统计量. 解决方案 对于任何涉及到统计.时间序列以及其他相关技术的数据分析问题,都可以考虑使用 Pandas库 . 为了让你先体验下,下面是一个 ...

  8. python两数相乘代码_Python 实现大整数乘法算法的示例代码

    我们平时接触的长乘法,按位相乘,是一种时间复杂度为 O(n ^ 2) 的算法.今天,我们来介绍一种时间复杂度为 O (n ^ log 3) 的大整数乘法(log 表示以 2 为底的对数). 介绍原理 ...

  9. python中统计数据的总和_Python 数据的累加与统计的示例代码

    问题 你需要处理一个很大的数据集并需要计算数据总和或其他统计量. 解决方案 对于任何涉及到统计.时间序列以及其他相关技术的数据分析问题,都可以考虑使用 Pandas库 . 为了让你先体验下,下面是一个 ...

最新文章

  1. WSL 使用者仍应该使用杀毒软件
  2. N32-马哥Linux第一周学习
  3. JS 时间戳转换成日期
  4. python 使用yield进行数据的流式处理
  5. rxandroid 源码分析
  6. [VN2020 公开赛]CSRe
  7. 专利计算机存储介质是智力活动,涉及计算机程序的发明专利申请的相关问题PPT课件.pptx...
  8. 干货收藏!一文看懂8个常用Python库从安装到应用
  9. 网络编程和反射的基本知识点的总结
  10. HDU 2577 How to Type (DP,经典)
  11. MySQL 学习四 SQL优化
  12. python面向对象实例王者荣耀_python王者荣耀
  13. Modbus-RTU入门篇
  14. 如何以管理员身份进入dos命令窗口
  15. C# 四舍五入 (解决四舍六入五成双的问题)
  16. FPGA资源之LUT
  17. anaconda更改虚拟环境安装位置
  18. Hangfire 基本使用
  19. hdu4745(最长回文子序列)
  20. Opera无法打开网页的解决办法

热门文章

  1. java移动端开发教程视频_Java Web开发-项目部分(中国移动科技综合管理系统)视频教程 - JavaWeb - Java - 私塾在线 - 只做精品视频课程服务...
  2. 跨交换机的VLAN透传
  3. 谷粒学院之阿里云视频点播
  4. 数据库系统概论(第五版)复习资料
  5. 2022年MathorCup数学建模C题自动泊车问题解题全过程文档加程序
  6. 如何成为一名 必学的12个基本步骤
  7. Web自动化测试如何做?Web自动化测试的详细流程和步骤
  8. 命令行远程登录邮件服务器
  9. 玩转华为ENSP模拟器系列 | 两个网关之间利用Tunnel接口实现IPSec VdPdNd隧道多链路备份
  10. postsql和geoserver进行连接,并发布服务