文章目录

0 项目说明1 主要实现2 环境配置3 界面效果4 算法实现5 项目源码6 最后

0 项目说明

基于opencv与SVM的车牌识别系统

提示:适合用于课程设计或毕业设计,工作量达标,源码开放

1 主要实现

用python3+opencv3做的中国车牌识别,包括算法和客户端界面,只有2个文件,surface.py是界面代码,predict.py是算法代码,界面不是重点所以用tkinter写得很简单。

2 环境配置

python3.7.3 opencv4.0.0.21 numpy1.16.2 Tkinter PIL5.4.1

3 界面效果

4 算法实现

算法思想来自于网上资源,先使用图像边缘和车牌颜色定位车牌,再识别字符。

车牌定位在predict方法中,为说明清楚,完成代码和测试后,加了很多注释,请参看源码。车牌字符识别也在predict方法中,请参看源码中的注释,需要说明的是,车牌字符识别使用的算法是opencv的SVM, opencv的SVM使用代码来自于opencv附带的sample,StatModel类和SVM类都是sample中的代码。SVM训练使用的训练样本来自于github上的EasyPR的c++版本。

由于训练样本有限,测试时会发现,车牌字符识别,可能存在误差,尤其是第一个中文字符出现的误差概率较大。源码中,上传了EasyPR中的训练样本,在train\目录下,如果要重新训练请解压在当前目录下,并删除原始训练数据文件svm.dat和svmchinese.dat。

5 项目源码

import tkinter as tk

from tkinter.filedialog import *

from tkinter import ttk

import predict

import cv2

from PIL import Image, ImageTk

import threading

import time

class Surface(ttk.Frame):

pic_path = ""

viewhigh = 600

viewwide = 600

update_time = 0

thread = None

thread_run = False

camera = None

color_transform = {"green":("绿牌","#55FF55"), "yello":("黄牌","#FFFF00"), "blue":("蓝牌","#6666FF")}

def __init__(self, win):

ttk.Frame.__init__(self, win)

frame_left = ttk.Frame(self)

frame_right1 = ttk.Frame(self)

frame_right2 = ttk.Frame(self)

win.title("车牌识别")

win.state("zoomed")

self.pack(fill=tk.BOTH, expand=tk.YES, padx="5", pady="5")

frame_left.pack(side=LEFT,expand=1,fill=BOTH)

frame_right1.pack(side=TOP,expand=1,fill=tk.Y)

frame_right2.pack(side=RIGHT,expand=0)

ttk.Label(frame_left, text='原图:').pack(anchor="nw")

ttk.Label(frame_right1, text='车牌位置:').grid(column=0, row=0, sticky=tk.W)

from_pic_ctl = ttk.Button(frame_right2, text="来自图片", width=20, command=self.from_pic)

from_vedio_ctl = ttk.Button(frame_right2, text="来自摄像头", width=20, command=self.from_vedio)

self.image_ctl = ttk.Label(frame_left)

self.image_ctl.pack(anchor="nw")

self.roi_ctl = ttk.Label(frame_right1)

self.roi_ctl.grid(column=0, row=1, sticky=tk.W)

ttk.Label(frame_right1, text='识别结果:').grid(column=0, row=2, sticky=tk.W)

self.r_ctl = ttk.Label(frame_right1, text="")

self.r_ctl.grid(column=0, row=3, sticky=tk.W)

self.color_ctl = ttk.Label(frame_right1, text="", width="20")

self.color_ctl.grid(column=0, row=4, sticky=tk.W)

from_vedio_ctl.pack(anchor="se", pady="5")

from_pic_ctl.pack(anchor="se", pady="5")

self.predictor = predict.CardPredictor()

self.predictor.train_svm()

def get_imgtk(self, img_bgr):

img = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2RGB)

im = Image.fromarray(img)

imgtk = ImageTk.PhotoImage(image=im)

wide = imgtk.width()

high = imgtk.height()

if wide > self.viewwide or high > self.viewhigh:

wide_factor = self.viewwide / wide

high_factor = self.viewhigh / high

factor = min(wide_factor, high_factor)

wide = int(wide * factor)

if wide <= 0 : wide = 1

high = int(high * factor)

if high <= 0 : high = 1

im=im.resize((wide, high), Image.ANTIALIAS)

imgtk = ImageTk.PhotoImage(image=im)

return imgtk

def show_roi(self, r, roi, color):

if r :

roi = cv2.cvtColor(roi, cv2.COLOR_BGR2RGB)

roi = Image.fromarray(roi)

self.imgtk_roi = ImageTk.PhotoImage(image=roi)

self.roi_ctl.configure(image=self.imgtk_roi, state='enable')

self.r_ctl.configure(text=str(r))

self.update_time = time.time()

try:

c = self.color_transform[color]

self.color_ctl.configure(text=c[0], background=c[1], state='enable')

except:

self.color_ctl.configure(state='disabled')

elif self.update_time + 8 < time.time():

self.roi_ctl.configure(state='disabled')

self.r_ctl.configure(text="")

self.color_ctl.configure(state='disabled')

def from_vedio(self):

if self.thread_run:

return

if self.camera is None:

self.camera = cv2.VideoCapture(0)

if not self.camera.isOpened():

mBox.showwarning('警告', '摄像头打开失败!')

self.camera = None

return

self.thread = threading.Thread(target=self.vedio_thread, args=(self,))

self.thread.setDaemon(True)

self.thread.start()

self.thread_run = True

def from_pic(self):

self.thread_run = False

self.pic_path = askopenfilename(title="选择识别图片", filetypes=[("jpg图片", "*.jpg")])

if self.pic_path:

img_bgr = predict.imreadex(self.pic_path)

self.imgtk = self.get_imgtk(img_bgr)

self.image_ctl.configure(image=self.imgtk)

resize_rates = (1, 0.9, 0.8, 0.7, 0.6, 0.5, 0.4)

for resize_rate in resize_rates:

print("resize_rate:", resize_rate)

r, roi, color = self.predictor.predict(img_bgr, resize_rate)

if r:

break

#r, roi, color = self.predictor.predict(img_bgr, 1)

self.show_roi(r, roi, color)

@staticmethod

def vedio_thread(self):

self.thread_run = True

predict_time = time.time()

while self.thread_run:

_, img_bgr = self.camera.read()

self.imgtk = self.get_imgtk(img_bgr)

self.image_ctl.configure(image=self.imgtk)

if time.time() - predict_time > 2:

r, roi, color = self.predictor.predict(img_bgr)

self.show_roi(r, roi, color)

predict_time = time.time()

print("run end")

def close_window():

print("destroy")

if surface.thread_run :

surface.thread_run = False

surface.thread.join(2.0)

win.destroy()

if __name__ == '__main__':

win=tk.Tk()

surface = Surface(win)

win.protocol('WM_DELETE_WINDOW', close_window)

win.mainloop()

6 最后

项目分享:https://gitee.com/asoonis/feed-neo

好文链接

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: