Commit b44aeb9e authored by liuhy's avatar liuhy
Browse files

上传LPR相关代码

parent 9ce4dc82
import onnxruntime as ort
import cv2
import numpy as np
print('Runing Based On:', ort.get_device())
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', 'I', 'O', '-'
]
def LPRNetPreprocess(image):
img = cv2.imread(image)
img = cv2.resize(img, (94, 24)).astype('float32')
img -= 127.5
img *= 0.0078125
img = np.expand_dims(img.transpose(2, 0, 1), 0)
return img
def LPRNetPostprocess(infer_res):
preb_label = []
for j in range(infer_res.shape[1]):
preb_label.append(np.argmax(infer_res[:, j], axis=0))
no_repeat_blank_label = []
pre_c = preb_label[0]
if pre_c != len(CHARS) - 1:
no_repeat_blank_label.append(pre_c)
for c in preb_label: # dropout repeate label and blank label
if (pre_c == c) or (c == len(CHARS) - 1):
if c == len(CHARS) - 1:
pre_c = c
continue
no_repeat_blank_label.append(c)
pre_c = c
result = ''.join(list(map(lambda x: CHARS[x], no_repeat_blank_label)))
return result
def LPRNetInference(model, imgs):
img = LPRNetPreprocess(imgs)
if ort.get_device() == "GPU":
# sess = ort.InferenceSession(model, providers=['CUDAExecutionProvider'],) #GPU版本
sess = ort.InferenceSession(model, providers=['ROCMExecutionProvider'],) #DCU版本
else:
sess = ort.InferenceSession(model, providers=['CPUExecutionProvider']) # CPU版本
print(sess.get_providers())
intput = sess.get_inputs()[0].shape
preb = sess.run(None, input_feed={sess.get_inputs()[0].name: img})[0]
result = LPRNetPostprocess(preb)
return result
if __name__ == '__main__':
model_name = 'model/LPRNet.onnx'
# model_name = 'LPRNet.onnx'
image = 'imgs/川JK0707.jpg'
InferRes = LPRNetInference(model_name, image)
print(image, 'Inference Result:', InferRes)
# -*- coding: utf-8 -*-
"""
MIGraphX示例程序
"""
import cv2
import numpy as np
import migraphx
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', 'I', 'O', '-'
]
def LPRNetPreprocess(image):
img = cv2.imread(image)
img = cv2.resize(img, (94, 24)).astype('float32')
img -= 127.5
img *= 0.0078125
img = np.expand_dims(img.transpose(2, 0, 1), 0)
return img
def LPRNetPostprocess(infer_res):
preb_label = []
for j in range(infer_res.shape[1]):
preb_label.append(np.argmax(infer_res[:, j], axis=0))
no_repeat_blank_label = []
pre_c = preb_label[0]
if pre_c != len(CHARS) - 1:
no_repeat_blank_label.append(pre_c)
for c in preb_label: # dropout repeate label and blank label
if (pre_c == c) or (c == len(CHARS) - 1):
if c == len(CHARS) - 1:
pre_c = c
continue
no_repeat_blank_label.append(c)
pre_c = c
result = ''.join(list(map(lambda x: CHARS[x], no_repeat_blank_label)))
return result
def LPRNetInference(model_name, imgs):
img = LPRNetPreprocess(imgs)
# 加载模型
if model_name[-3:] == 'mxr':
model = migraphx.load(model_name)
else:
model = migraphx.parse_onnx(model_name)
# migraphx.quantize_fp16(model)
model.compile(t=migraphx.get_target("gpu"),device_id=0) # device_id: 设置GPU设备,默认为0号设备(>=1.2版本中支持)
# migraphx.save(model, 'LPRNet.mxr')
inputName=model.get_parameter_names()[0]
inputShape=model.get_parameter_shapes()[inputName].lens()
print("inputName:{0} \ninputShape:{1}".format(inputName,inputShape))
results = model.run({inputName: migraphx.argument(img)})
result = LPRNetPostprocess(np.array(results[0]))
return result
if __name__ == '__main__':
# model_name = 'LPRNet.onnx'
model_name = 'model/LPRNet.mxr'
image = 'imgs/川JK0707.jpg'
InferRes = LPRNetInference(model_name, image)
print(image, 'Inference Result:', InferRes)
# license-plate-detect-recoginition-pytorch
深度学习车牌检测与识别,检测结果包含车牌矩形框和4个角点,基于pytorch框架运行,
主程序是detect_rec_img.py,运行程序前需要确保您的机器安装了pytorch
车牌识别模块,可以更换成crnn网络做识别,也可以更换到传统图像处理方法分割字符后逐个字符识别,
在这个车牌检测和识别系统里,我觉得最重要的是前面的车牌检测与矫正模块,因为如果前面没做好,
那么后面输入到车牌识别模块里的图片是一个倾斜的车牌,这时候输出结果就出错了。
对于车牌检测,也可以使用图像分割的思想,例如使用UNet语义分割网络,分割出车牌,
二值化然后查找连通域,计算4个顶点
from torch.utils.data import *
from imutils import paths
import numpy as np
import random
import cv2
import os
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', 'I', 'O', '-'
]
CHARS_DICT = {char:i for i, char in enumerate(CHARS)}
class LPRDataLoader(Dataset):
def __init__(self, img_dir, imgSize, PreprocFun=None):
self.img_dir = img_dir
self.img_paths = []
for i in range(len(img_dir)):
self.img_paths += [el for el in paths.list_images(img_dir[i])]
random.shuffle(self.img_paths)
self.img_size = imgSize
# self.lpr_max_len = lpr_max_len
if PreprocFun is not None:
self.PreprocFun = PreprocFun
else:
self.PreprocFun = self.transform
def __len__(self):
return len(self.img_paths)
def __getitem__(self, index):
filename = self.img_paths[index]
Image = cv2.imread(filename)
height, width, _ = Image.shape
if height != self.img_size[1] or width != self.img_size[0]:
Image = cv2.resize(Image, self.img_size)
Image = self.PreprocFun(Image)
basename = os.path.basename(filename)
imgname, suffix = os.path.splitext(basename)
imgname = imgname.split("-")[0].split("_")[0]
label = list()
for c in imgname:
# one_hot_base = np.zeros(len(CHARS))
# one_hot_base[CHARS_DICT[c]] = 1
label.append(CHARS_DICT[c])
if len(label) == 8:
if self.check(label) == False:
print(imgname)
assert 0, "Error label ^~^!!!"
return Image, label, len(label)
def transform(self, img):
img = img.astype('float32')
img -= 127.5
img *= 0.0078125
img = np.transpose(img, (2, 0, 1))
return img
def check(self, label):
if label[2] != CHARS_DICT['D'] and label[2] != CHARS_DICT['F'] \
and label[-1] != CHARS_DICT['D'] and label[-1] != CHARS_DICT['F']:
print("Error label, Please check!")
return False
else:
return True
import torch
import torch.nn as nn
import torch.nn.functional as F
class small_basic_block(nn.Module):
def __init__(self, ch_in, ch_out):
super(small_basic_block, self).__init__()
self.block = nn.Sequential(
nn.Conv2d(ch_in, ch_out // 4, kernel_size=1),
nn.ReLU(),
nn.Conv2d(ch_out // 4, ch_out // 4, kernel_size=(3, 1), padding=(1, 0)),
nn.ReLU(),
nn.Conv2d(ch_out // 4, ch_out // 4, kernel_size=(1, 3), padding=(0, 1)),
nn.ReLU(),
nn.Conv2d(ch_out // 4, ch_out, kernel_size=1),
)
def forward(self, x):
return self.block(x)
class my_lprnet(nn.Module):
def __init__(self, class_num):
super(my_lprnet, self).__init__()
self.class_num = class_num
self.stage1 = nn.Sequential(
nn.Conv2d(in_channels=3, out_channels=64, kernel_size=3, stride=1), # 0
nn.BatchNorm2d(num_features=64),
nn.ReLU())
self.stage2 = nn.Sequential(small_basic_block(ch_in=64, ch_out=128), # *** 4 ***
nn.BatchNorm2d(num_features=128),
nn.ReLU())
self.stage3 = nn.Sequential(small_basic_block(ch_in=64, ch_out=256), # 8
nn.BatchNorm2d(num_features=256),
nn.ReLU(), # 10
small_basic_block(ch_in=256, ch_out=256), # *** 11 ***
nn.BatchNorm2d(num_features=256), # 12
nn.ReLU())
self.stage4 = nn.Sequential(nn.Conv2d(in_channels=64, out_channels=256, kernel_size=(1, 4), stride=1), # 16
nn.BatchNorm2d(num_features=256),
nn.ReLU(), # 18
nn.Conv2d(in_channels=256, out_channels=class_num, kernel_size=(13, 1), stride=1), # 20
nn.BatchNorm2d(num_features=class_num),
nn.ReLU())
self.container = nn.Conv2d(in_channels=448 + class_num, out_channels=class_num, kernel_size=(1, 1), stride=(1, 1))
def forward(self, x):
out1 = self.stage1(x)
out = F.max_pool2d(out1, 3, stride=(1, 1))
out2 = self.stage2(out)
out = F.max_pool2d(out2, 3, stride=(1, 2)) ###这里可以改成F.max_pool3d,之所以这么写,是为了便于转换生成onnx文件
out = F.max_pool2d(out.permute(0, 2, 3, 1).contiguous(), 1, stride=(1, 2))
out = out.permute(0, 3, 1, 2).contiguous()
out3 = self.stage3(out)
out = F.max_pool2d(out3, 3, stride=(1, 2))
out = F.max_pool2d(out.permute(0, 2, 3, 1).contiguous(), 1, stride=(1, 4))
out = out.permute(0, 3, 1, 2).contiguous()
out4 = self.stage4(out)
out1 = F.avg_pool2d(out1, kernel_size=5, stride=5)
f = torch.pow(out1, 2)
f = torch.mean(f)
out1 = torch.div(out1, f)
out2 = F.avg_pool2d(out2, kernel_size=5, stride=5)
f = torch.pow(out2, 2)
f = torch.mean(f)
out2 = torch.div(out2, f)
out3 = F.avg_pool2d(out3, kernel_size=(4, 10), stride=(4, 2))
f = torch.pow(out3, 2)
f = torch.mean(f)
out3 = torch.div(out3, f)
f = torch.pow(out4, 2)
f = torch.mean(f)
out4 = torch.div(out4, f)
logits = torch.cat((out1, out2, out3, out4), 1)
logits = self.container(logits)
logits = torch.mean(logits, dim=2)
# logits = logits.view(self.class_num, -1)
return logits
def build_lprnet(class_num, phase=False):
Net = my_lprnet(class_num)
if phase:
return Net.train()
else:
return Net.eval()
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment