yolov5 車牌識(shí)別算法,支持12種中文車牌類型 基于yolov5的車牌檢測 車牌矯正以及 基于CRNN的車牌識(shí)別
1.單行藍(lán)牌 2.單行黃牌 3.新能源車牌 4.白色警用車牌 5 教練車牌 6 武警車牌 7 雙層黃牌 8 雙層武警 9 使館車牌 10 港澳牌車 11 雙層農(nóng)用車牌 12 民航車牌
效果如下:
基于yolov5車牌檢測
車牌檢測+關(guān)鍵點(diǎn)定位
1.第一步是目標(biāo)檢測,目標(biāo)檢測大家都很熟悉,常見的yolo系列,這里的話我用的是我修改后的yolov5系列),用yolov5訓(xùn)練的車牌檢測效果如下:
如果對(duì)上面這樣圖片進(jìn)行識(shí)別的話,那么干擾信息很多,會(huì)造成誤識(shí)別,這里就是為什么要進(jìn)行關(guān)鍵點(diǎn)識(shí)別,假設(shè)我們得到車牌的四個(gè)角點(diǎn)坐標(biāo):
通過透視變換,透視變換即可得到下圖:
這樣的圖片進(jìn)行識(shí)別的話就會(huì)非常容易了
所以在檢測的同時(shí),我們需要進(jìn)行關(guān)鍵點(diǎn)定位
透視變換代碼:
def four_point_transform(image, pts):
# obtain a consistent order of the points and unpack them
# individually
rect = order_points(pts)
(tl, tr, br, bl) = rect
# compute the width of the new image, which will be the
# maximum distance between bottom-right and bottom-left
# x-coordiates or the top-right and top-left x-coordinates
widthA = 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))
# compute the height of the new image, which will be the
# maximum distance between the top-right and bottom-right
# y-coordinates or the top-left and bottom-left y-coordinates
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))
# now that we have the dimensions of the new image, construct
# the set of destination points to obtain a "birds eye view",
# (i.e. top-down view) of the image, again specifying points
# in the top-left, top-right, bottom-right, and bottom-left
# order
dst = np.array([
[0, 0],
[maxWidth - 1, 0],
[maxWidth - 1, maxHeight - 1],
[0, maxHeight - 1]], dtype = "float32")
# compute the perspective transform matrix and then apply it
M = cv2.getPerspectiveTransform(rect, dst)
warped = cv2.warpPerspective(image, M, (maxWidth, maxHeight))
# return the warped image
return warped
2.這里關(guān)鍵點(diǎn)定位我們利用和人臉識(shí)別類似的方法進(jìn)行,人臉是5個(gè)點(diǎn),而車牌我們僅僅需要四個(gè)點(diǎn)就可以了。
車牌檢測訓(xùn)練數(shù)據(jù)集可以主要利用了CRPD 和CCPD數(shù)據(jù)集
車牌識(shí)別
拿到車牌區(qū)域的圖片后就可以利用crnn進(jìn)行車牌識(shí)別了
整理了一些數(shù)據(jù),包括12種車牌的訓(xùn)練數(shù)據(jù)集,以及訓(xùn)練步驟
車牌識(shí)別代碼:my_demo_new.py
from plateNet import myNet_ocr
import torch
import torch.nn as nn
import cv2
import numpy as np
import os
import time
import argparse
def cv_imread(path): #讀取中文路徑的圖片
img=cv2.imdecode(np.fromfile(path,dtype=np.uint8),-1)
return img
def allFilePath(rootPath,allFIleList):
fileList = os.listdir(rootPath)
for temp in fileList:
if os.path.isfile(os.path.join(rootPath,temp)):
allFIleList.append(os.path.join(rootPath,temp))
else:
allFilePath(os.path.join(rootPath,temp),allFIleList)
# plateName="#京滬津渝冀晉蒙遼吉黑蘇浙皖閩贛魯豫鄂湘粵桂瓊川貴云藏陜甘青寧新學(xué)警港澳掛使領(lǐng)民深危險(xiǎn)品0123456789ABCDEFGHJKLMNPQRSTUVWXYZ"
plateName=r"#京滬津渝冀晉蒙遼吉黑蘇浙皖閩贛魯豫鄂湘粵桂瓊川貴云藏陜甘青寧新學(xué)警港澳掛使領(lǐng)民航深0123456789ABCDEFGHJKLMNPQRSTUVWXYZ"
mean_value,std_value=(0.588,0.193)
def decodePlate(preds):
pre=0
newPreds=[]
for i in range(len(preds)):
if preds[i]!=0 and preds[i]!=pre:
newPreds.append(preds[i])
pre=preds[i]
return newPreds
def image_processing(img,device):
img = cv2.resize(img, (168,48))
img = np.reshape(img, (48, 168, 3))
# normalize
img = img.astype(np.float32)
img = (img / 255. - mean_value) / std_value
img = img.transpose([2, 0, 1])
img = torch.from_numpy(img)
img = img.to(device)
img = img.view(1, *img.size())
return img
def get_plate_result(img,device,model):
# img = cv2.imread(image_path)
input = image_processing(img,device)
preds = model(input)
# print(preds)
preds=preds.view(-1).detach().cpu().numpy()
newPreds=decodePlate(preds)
plate=""
for i in newPreds:
plate+=plateName[i]
return plate
def init_model(device,model_path):
check_point = torch.load(model_path,map_location=device)
model_state=check_point['state_dict']
cfg = check_point['cfg']
model = myNet_ocr(num_classes=78,export=True,cfg=cfg) #export True 用來推理
model.load_state_dict(model_state)
model.to(device)
model.eval()
return model
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('--model_path', type=str, default='output/360CC/crnn/2022-09-26-21-30/checkpoints/checkpoint_11_acc_0.9657.pth', help='model.pt path(s)')
parser.add_argument('--image_path', type=str, default='images', help='source')
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
# device =torch.device("cpu")
opt = parser.parse_args()
model = init_model(device,opt.model_path)
if os.path.isfile(opt.image_path):
right=0
begin = time.time()
img = cv_imread(opt.image_path)
if img.shape[-1]!=3:
img = cv2.cvtColor(img,cv2.COLOR_BGRA2BGR)
plate=get_plate_result(img, device,model)
print(plate)
else:
file_list=[]
allFilePath(opt.image_path,file_list)
for pic_ in file_list:
try:
pic_name = os.path.basename(pic_)
img = cv_imread(pic_)
if img.shape[-1]!=3:
img = cv2.cvtColor(img,cv2.COLOR_BGRA2BGR)
plate=get_plate_result(img,device,model)
print(plate,pic_name)
except:
print("error")
源碼在這:文章來源:http://www.zghlxwxcb.cn/news/detail-444740.html
github車牌識(shí)別文章來源地址http://www.zghlxwxcb.cn/news/detail-444740.html
到了這里,關(guān)于車牌識(shí)別算法 基于yolov5的車牌檢測+crnn中文車牌識(shí)別 支持12種中文車牌識(shí)別的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!