車牌識(shí)別包括車牌檢測(cè)(通過圖像分割、特征提取獲得車牌位置)+車牌識(shí)別(對(duì)檢測(cè)到的車牌進(jìn)行字符內(nèi)容識(shí)別)。
創(chuàng)新互聯(lián)專注于阜康網(wǎng)站建設(shè)服務(wù)及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗(yàn)。 熱誠為您提供阜康營(yíng)銷型網(wǎng)站建設(shè),阜康網(wǎng)站制作、阜康網(wǎng)頁設(shè)計(jì)、阜康網(wǎng)站官網(wǎng)定制、小程序定制開發(fā)服務(wù),打造阜康網(wǎng)絡(luò)公司原創(chuàng)品牌,更為您提供阜康網(wǎng)站排名全網(wǎng)營(yíng)銷落地服務(wù)。一、基本流程如下:
1.車牌檢測(cè)
1)讀取需要進(jìn)行車牌識(shí)別的圖片;
2)對(duì)圖像進(jìn)行灰度化處理(高斯模糊可選擇是否進(jìn)行)和灰度拉伸;
3)進(jìn)行開運(yùn)算,消除圖像中的噪聲;
4)將灰度拉伸后的圖像和開運(yùn)算后的圖像求差,并輸出其絕對(duì)值;
5)將圖像二值化,并利用Canny邊緣算法提取圖像中邊緣輪廓;
6)進(jìn)行閉運(yùn)算操作,獲得小連通域;
7)進(jìn)行兩次開運(yùn)算操作,獲得大連通域;
8)利用車牌長(zhǎng)寬比篩選可能屬于車牌區(qū)域的框,在原圖中繪制矩形 。
2.車牌字符識(shí)別
1)對(duì)車牌ROI圖像進(jìn)行灰度化處理;
2)利用形態(tài)學(xué)運(yùn)算中的閉運(yùn)算消除灰度圖像噪聲點(diǎn);
3)利用百度飛槳OCR識(shí)別車牌字符與位置;
4)將結(jié)果打印并在圖片上顯示出來。
二、實(shí)際代碼測(cè)試:
1.輸入圖像:
2.輸出圖像:
三、注意事項(xiàng)
1.目前代碼進(jìn)行過單個(gè)車牌檢測(cè),未對(duì)多個(gè)車牌進(jìn)行檢測(cè);
2.paddleOCR下載和配置,且容易出錯(cuò),實(shí)際使用中速度較慢,可考慮使用EASYOCR作為代替。
附上代碼
import cv2
from matplotlib import pyplot as plt
import os
import numpy as np
from paddleocr import PaddleOCR, draw_ocr
from PIL import Image, ImageDraw, ImageFont
#利用paddelOCR進(jìn)行文字掃描,并輸出結(jié)果
def text_scan(img_path):
ocr = PaddleOCR(use_angle_cls=True, use_gpu=False)
#img_path = r'test image/license_plate1.jpg'
result = ocr.ocr(img_path, cls=True)
for line in result:
#print(line)
return result
#在圖片中寫入將車牌信息
def infor_write(img,rect,result):
text=result[1][0]
cv2img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # cv2和PIL中顏色的hex碼的儲(chǔ)存順序不同
pilimg = Image.fromarray(cv2img)
#PIL圖片上打印漢字
draw = ImageDraw.Draw(pilimg) # 圖片上打印
font = ImageFont.truetype("simhei.ttf",20, encoding="utf-8") # 參數(shù)1:字體文件路徑,參數(shù)2:字體大小
draw.text((rect[2], rect[1]), str(text), (0,255,0), font=font) # 參數(shù)1:打印坐標(biāo),參數(shù)2:文本,參數(shù)3:字體顏色,參數(shù)4:字體
#PIL圖片轉(zhuǎn)cv2 圖片
cv2charimg = cv2.cvtColor(np.array(pilimg), cv2.COLOR_RGB2BGR)
return cv2charimg
#圖像去噪灰度處理
def gray_guss(img):
img=cv2.GaussianBlur(img,(1,1),0)
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
return gray
#圖像尺寸變換
def img_resize(img):
a=400*img.shape[0]/img.shape[1]
a=int(a)
img=cv2.resize(img,(400,a))
return img
#Sobel檢測(cè),x方向上的邊緣檢測(cè)(增強(qiáng)邊緣信息)
def Sobel_detec(img):
Sobel_x = cv2.Sobel(img, cv2.CV_16S, 1, 0)
absX = cv2.convertScaleAbs(Sobel_x)
return absX
#尋找某區(qū)域大外接矩形框4點(diǎn)坐標(biāo)
def find_retangle(contour):
y,x=[],[]
for p in contour:
y.append(p[0][0])
x.append(p[0][1])
return [min(y),min(x),max(y),max(x)]
#尋找并定位車牌輪廓位置
def locate_license(img):
blocks=[]
contours,hierarchy=
cv2.findContours(img,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
for c in contours:
x,y,w,h=cv2.boundingRect(c)
r=find_retangle(c)
a=(r[2]-r[0])*(r[3]-r[1])#r=[min(y),min(x),max(y),max(x)]
s=(r[2]-r[0])/(r[3]-r[1])
#根據(jù)輪廓形狀特點(diǎn),確定車牌的輪廓位置并截取圖像
if (w>(h * 3)) and (w< (h * 5)):
# img=oriimg[y:y+h,x:x+w]
# cv2.rectangle(oriimg, (x, y), (x+w, y+h), (0, 255, 0), 2)
blocks.append([r, a, s])
# 選出面積大的3個(gè)區(qū)域
blocks = sorted(blocks, key=lambda b: b[1])[-3:] # 按照blocks第3個(gè)元素大小進(jìn)行排序
# 使用顏色識(shí)別判斷出最像車牌的區(qū)域
maxweight, maxindex = 0, -1
# 劃分ROI區(qū)域
for i in range(len(blocks)):
b = oriimg[blocks[i][0][1]:blocks[i][0][3], blocks[i][0][0]:blocks[i][0][2]]
# RGB轉(zhuǎn)HSV
hsv = cv2.cvtColor(b, cv2.COLOR_BGR2HSV)
# 藍(lán)色車牌范圍
lower = np.array([100, 50, 50])
upper = np.array([140, 255, 255])
# 根據(jù)閾值構(gòu)建掩模
mask = cv2.inRange(hsv, lower, upper)
# 統(tǒng)計(jì)權(quán)值
w1 = 0
for m in mask:
w1 += m / 255
w2 = 0
for w in w1:
w2 += w
# 選出大權(quán)值的區(qū)域
if w2 >maxweight:
maxindex = i
maxweight = w2
# print(blocks[maxindex][0])
return blocks[maxindex][0]#blocks[maxindex][0]即為車牌輪廓位置理想外輪廓
#圖像預(yù)處理+車牌輪廓位置檢測(cè)
def fine_lisecenpts(img):
# 圖像去噪灰度處理
guss = gray_guss(img)
# Sobel檢測(cè),增強(qiáng)邊緣信息
sobel = Sobel_detec(guss)
# 圖像閾值化操作——獲得二值化圖
ret, threshold = cv2.threshold(sobel, 0, 255, cv2.THRESH_OTSU)
# # 對(duì)二值化圖像進(jìn)行邊緣檢測(cè)(可選,通過邊緣檢測(cè)后,最終進(jìn)行形態(tài)學(xué)運(yùn)算得到的輪廓面積更大)
# threshold=cv2.Canny(threshold,threshold.shape[0],threshold.shape[1])
#形態(tài)學(xué)運(yùn)算(從圖像中提取對(duì)表達(dá)和描繪區(qū)域形狀有意義的圖像分量)——閉操作
kernelX = cv2.getStructuringElement(cv2.MORPH_RECT, (30, 10))
closing = cv2.morphologyEx(threshold, cv2.MORPH_CLOSE, kernelX, iterations=1)
# 腐蝕(erode)和膨脹(dilate)
kernelX=cv2.getStructuringElement(cv2.MORPH_RECT,(50,1))
kernelY=cv2.getStructuringElement(cv2.MORPH_RECT,(1,20))
#x方向上進(jìn)行閉操作(抑制暗細(xì)節(jié))
img=cv2.dilate(closing,kernelX)
img=cv2.erode(img,kernelX)
#y方向上進(jìn)行開操作
img=cv2.erode(img,kernelY)
img=cv2.dilate(img,kernelY)
#進(jìn)行中值濾波去噪
Blur=cv2.medianBlur(img,15)
#尋找輪廓
rect=locate_license(Blur)
return rect,Blur
#車牌字符識(shí)別
def seg_char(rect_list,img):
img=oriimg[rect_list[1]:rect_list[3], rect_list[0]:rect_list[2]]
# 圖像去噪灰度處理
gray=gray_guss(img)
# 圖像閾值化操作-獲得二值化圖(可選)
#ret,charimage=cv2.threshold(gray,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)
#圖像進(jìn)行閉運(yùn)算
k1 = np.ones((1, 1), np.uint8)
close = cv2.morphologyEx(gray, cv2.MORPH_CLOSE, k1)
cv2.imshow('close', close)
cv2.imwrite('test image/Char_img.jpg',close)
cv2.waitKey()
res=text_scan(r'test image/Char_img.jpg')
return res
#主函數(shù)區(qū)
if __name__ == '__main__':
img=cv2.imread('test image/license_plate1.jpg')
# 改變圖像尺寸
img=img_resize(img)
oriimg=img.copy()
#尋找到車牌外輪廓矩形坐標(biāo)
rect, img=fine_lisecenpts(img)
#利用車牌輪廓坐標(biāo)劃分ROI區(qū)域用于字符識(shí)別,利用OCR識(shí)別車牌字符并返回字符串內(nèi)容
result=seg_char(rect,oriimg)
#循環(huán)讀取車牌字符串并寫入到圖片中
for list in result:
oriimg=infor_write(oriimg, rect, list)
cv2.rectangle(oriimg, (rect[0], rect[1]), (rect[2], rect[3]), (0, 255, 0), 2)
cv2.imshow('oriimg',oriimg)
cv2.waitKey()
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級(jí)服務(wù)器適合批量采購,新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧