智能停车场车牌识别系统(一)

前段时间练习过的一个小项目,今天再看看,记录一下~

开发工具准备:

  • 开发工具:PyCharm
  • Python内置模块:os、time、datetime
  • 第三方模块:pygame、opencv-python、pandas、matplotlib、baidu-aip

pygame模块:实现项目主窗体
opencv-python模块:调用摄像头进行拍照
pandas模块:数据处理(创建保存数据文件)
baidu-aip模块:进行车牌识别获取车牌号
matplotlib模块:绘制柱状图

项目组织结构:

智能停车场车牌识别系统(一)_第1张图片
说明:

  • datefile文件夹:保存车辆信息表的xlsx文件
  • file文件夹:保存图片文件夹。ic_launcher.jpg是窗体的右上角图标文件;income.png是实现收入统计的柱状图(下一篇文章实现);key.txt是使用百度的图片识别AI接口申请的key;test.jpg保存的是摄像头抓取的图片
  • venv文件夹:项目所需要的各种模块,即项目运行环境
  • btn.py文件:按钮模块
  • main.py文件:程序主文件
  • ocrutil.py文件:车牌识别模块
  • timeutil.py文件:时间处理模块

实现系统主窗体:(pygame模块)

  1. 初始化pygame游戏模块
  2. 设置窗体名称
  3. 设置窗体图标
  4. 设置窗体大小和背景颜色
  5. 在主线程中不断更新界面,如果遇到关闭窗口事件,就退出

在main.py文件写入如下代码:(可以作为实现系统窗体的主要框架)

import pygame

size=1000,484              # 窗体大小
FPS=60                     # 设置帧率(屏幕每秒的刷新次数)
# 设置背景颜色
DARKBLUE=(73,119,142)
BG=DARKBLUE

# 1.初始化
pygame.init()
# 2.设置窗体名称
pygame.display.set_caption('智能停车场车牌识别计费系统')
# 3.加载图片,设置图标
ic_launcher=pygame.image.load('file/ic_launcher.jpg')
pygame.display.set_icon(ic_launcher)
# 4.设置窗体大小、背景颜色
screen=pygame.display.set_mode(size)
screen.fill(BG)

# 游戏循环帧率设置(控制程序运行时间)
clock=pygame.time.Clock()

# 主线程
while True:

    for event in pygame.event.get():
        # 关闭页面游戏退出
        if event.type==pygame.QUIT:
            pygame.quit()
            exit()

    pygame.display.flip()        # 更新界面
    clock.tick(FPS)              # 控制游戏最大帧率为60

部分代码说明:

  1. pygame.event.get():获取事件队列,使用for…in遍历所有事件;
  2. event.type:用于判断事件类型;
  3. pygame.QUIT为关闭pygame窗口事件

运行效果如图:
智能停车场车牌识别系统(一)_第2张图片

获取摄像头画面:(opencv-python模块)

  1. 导入opencv-python模块;
  2. 初始化摄像头,并创建摄像头实例。VideoCapture( )方法可以采集摄像头捕获到的图像,其中参数为摄像头的ID,设置为0表示第一个摄像头,如果有多个摄像头就设置为摄像头ID;
  3. 通过摄像头实例,在while循环中获取图片并保存在file文件夹的test.jpg中,然后把图片绘制到窗体上。

此时的main.py代码如下:

import pygame

import cv2

size=1000,484              # 窗体大小
FPS=60                     # 设置帧率(屏幕每秒的刷新次数)
# 设置背景颜色
DARKBLUE=(73,119,142)
BG=DARKBLUE

# 1.初始化
pygame.init()
# 2.设置窗体名称
pygame.display.set_caption('智能停车场车牌识别计费系统')
# 3.加载图片,设置图标
ic_launcher=pygame.image.load('file/ic_launcher.jpg')
pygame.display.set_icon(ic_launcher)
# 4.设置窗体大小、背景颜色
screen=pygame.display.set_mode(size)
screen.fill(BG)

try:
    cam=cv2.VideoCapture(0)  # 创建摄像头实例
except:
    print('请连接摄像头')

# 游戏循环帧率设置(控制程序运行时间)
clock=pygame.time.Clock()

# 主线程
while True:

    # 从摄像头读取图片
    sucess, img = cam.read()
    # 保存图片
    cv2.imwrite('file/test.jpg', img)
    # 加载图像
    image = pygame.image.load('file/test.jpg')
    # 设置图片大小
    image = pygame.transform.scale(image, (640, 480))
    # 绘制视频画面
    screen.blit(image, (2, 2))

    for event in pygame.event.get():
        # 关闭页面游戏退出
        if event.type==pygame.QUIT:
            pygame.quit()
            exit()

    pygame.display.flip()        # 更新界面
    clock.tick(FPS)              # 控制游戏最大帧率为60

运行效果如图:

智能停车场车牌识别系统(一)_第3张图片

注意:如果运行失败,可能是自己电脑的摄像头驱动有问题,需要重新下载。我当时就遇到了这个问题。
下载网址:https://newsupport.lenovo.com.cn/driveDownloads_index.html
点击【在站内查找设备驱动】,然后按照主机编号和电脑型号下载摄像头驱动

创建保存数据文件:(pandas模块)

该项目需要创建两个表,一个用于保存当前停车场里的车辆信息,另一个用于保存所有进入过停车场的车辆进出信息。主要用到pandas模块和os模块。
main.py文件代码如下:

import pygame

import pandas as pd
from pandas import DataFrame
import os
import cv2


size=1000,484              # 窗体大小
FPS=60                     # 设置帧率(屏幕每秒的刷新次数)
# 设置背景颜色
DARKBLUE=(73,119,142)
BG=DARKBLUE
#定义颜色
BLAK=(0,0,0)
WHITE=(255,255,255)
GREEN=(0,255,0)
BLUE=(72,61,139)
GRAY=(96,96,96)
RED=(220,20,60)
YELLOW=(255,255,0)


#获取当前项目的路径
cdir=os.getcwd()
#文件路径
path=cdir+'/datafile/'
if not os.path.exists(path):
    os.makedirs(path) #根据路径建立文件夹
    #车牌号、日期、价格、状态
    carnfile=pd.DataFrame(columns=['carnumber','date','price','state'])
    #生成.xlsx文件
    carnfile.to_excel(path+'停车场车辆表.xlsx',sheet_name='data')
    carnfile.to_excel(path+'停车场信息表.xlsx', sheet_name='data')

# 1.初始化
pygame.init()
# 2.设置窗体名称
pygame.display.set_caption('智能停车场车牌识别计费系统')
# 3.加载图片,设置图标
ic_launcher=pygame.image.load('file/ic_launcher.jpg')
pygame.display.set_icon(ic_launcher)
# 4.设置窗体大小、背景颜色
screen=pygame.display.set_mode(size)
screen.fill(BG)

try:
    cam=cv2.VideoCapture(0)  # 创建摄像头实例
except:
    print('请连接摄像头')

# 游戏循环帧率设置(控制程序运行时间)
clock=pygame.time.Clock()

# 主线程
while True:

    # 从摄像头读取图片
    sucess, img = cam.read()
    # 保存图片
    cv2.imwrite('file/test.jpg', img)
    # 加载图像
    image = pygame.image.load('file/test.jpg')
    # 设置图片大小
    image = pygame.transform.scale(image, (640, 480))
    # 绘制视频画面
    screen.blit(image, (2, 2))

    
    for event in pygame.event.get():
        # 关闭页面游戏退出
        if event.type==pygame.QUIT:
            pygame.quit()
            exit()
    pygame.display.flip()        # 更新界面
    clock.tick(FPS)              # 控制游戏最大帧率为60


运行效果如图:

在这里插入图片描述

识别车牌(核心功能):

申请百度的图片识别Key:

  1. 进入官网:https://ai.baidu.com/,点击右上角的控制台,进行登录;
  2. 登录成功之后,在左侧栏目中依次选择【人工智能】→【图像识别】
  3. 再点击【创建应用】,应用名称和应用类型可以自己写,【接口选择】部分把【文字识别】里面的【车牌识别】选上,其他部分可以不管。创建成功之后界面如下:

智能停车场车牌识别系统(一)_第4张图片

  1. 再把这3个信息写到file/key.txt文件里面,格式如下:

在这里插入图片描述

识别车牌模块:

在ocrutil.py文件中实现车牌识别,调用百度AI接口识别图片,获取车牌号,代码如下:

from aip import AipOcr
import os

#百度识别车牌
filename='file/key.txt'                               # 记录申请的key的文件位置
if os.path.exists(filename):                          # 判断文件是否存在
    with open(filename,"r") as file:                  # 以只读方式打开文件
        dictkey=eval(file.readlines()[0])             # 读取全部内容,并且转换为字典
        APP_ID=dictkey['APP_ID']                      # 获取申请的APIID
        API_KEY=dictkey['API_KEY']                    # 获取申请的APIKEY
        SECRET_KEY=dictkey['SECRET_KEY']              # 获取申请的SECRETKEY
else:
    print("请先在file目录下创建key.txt")

#初始化AipOcr对象
client=AipOcr(APP_ID,API_KEY,SECRET_KEY)


#根据文件返回车牌号
def getcn():
    # 读取图片
    with open('file/test.jpg','rb') as fp:
        image=fp.read()
        
    results=client.licensePlate(image)['words_result']['number'] # 调用车牌识别
    
    print('车牌号:'+results) # 输出车牌号
    return  results

按钮模块:

由于百度AI接口每天会限制调用次数,所以在项目中添加“识别”按钮。当车牌出现在摄像头中的时候点击“识别”按钮,再调用识别车牌接口。

设置按钮的主要内容有:

  1. 设置按钮大小
  2. 设置按钮在窗体中的位置
  3. 填充按钮颜色
  4. 把文本(“识别”两个字)写到按钮上
  5. 设置文本在按钮上的位置
  6. 将整体作为一个图像,绘制到窗体上

btn.py代码如下:

import pygame

#自定义按钮
class Button():
    #msg为要在按钮中显示的文本
    def __init__(self,screen,centerxy,width,height,button_color,text_color,msg,size):
        ''' 初始化按钮的属性 '''
        self.screen=screen
        self.width,self.height=width,height                # 设置按钮的宽和高
        self.button_color=button_color                     # 设置按钮的rect对象颜色为深蓝
        self.text_color=text_color                         # 设置文本的颜色为白色

        # 1.设置文本字体与大小
        self.font=pygame.font.SysFont('SimHei',size)
        # 2.设置按钮大小
        self.rect=pygame.Rect(0,0,self.width,self.height)
        # 3.创建按钮的rect对象,并设置按钮的中心位置
        self.rect.centerx=centerxy[0]-self.width/2+2
        self.rect.centery=centerxy[1]-self.height/2+2
        # 4.填充颜色
        self.screen.fill(self.button_color, self.rect)

        #渲染图像
        self.deal_msg(msg)

    def deal_msg(self,msg):
        '''将msg渲染为图像,并将其在按钮上居中'''
        # 5.将文本写到按钮上
        self.msg_img=self.font.render(msg,True,self.text_color,self.button_color)
        # 6.设置文本在按钮上的位置:文本的中心就是按钮的中心(即文本居中)
        self.msg_img_rect=self.msg_img.get_rect()
        self.msg_img_rect.center=self.rect.center
        # 7.绘制到屏幕上
        self.screen.blit(self.msg_img, self.msg_img_rect)
        

在main.py主文件中调用按钮模块,在while循环里面创建“识别”按钮。并且判断单击的位置是否为按钮的位置,如果是,就调用车牌识别模块ocrutil的getcn()方法进行车牌识别,代码如下:

import pygame

import pandas as pd
from pandas import DataFrame
import os
import cv2

import btn
import ocrutil

size=1000,484              # 窗体大小
FPS=60                     # 设置帧率(屏幕每秒的刷新次数)
# 设置背景颜色
DARKBLUE=(73,119,142)
BG=DARKBLUE
#定义颜色
BLAK=(0,0,0)
WHITE=(255,255,255)
GREEN=(0,255,0)
BLUE=(72,61,139)
GRAY=(96,96,96)
RED=(220,20,60)
YELLOW=(255,255,0)

#获取当前项目的路径
cdir=os.getcwd()
#文件路径
path=cdir+'/datafile/'
if not os.path.exists(path):
    os.makedirs(path) #根据路径建立文件夹
    #车牌号、日期、价格、状态
    carnfile=pd.DataFrame(columns=['carnumber','date','price','state'])
    #生成.xlsx文件
    carnfile.to_excel(path+'停车场车辆表.xlsx',sheet_name='data')
    carnfile.to_excel(path+'停车场信息表.xlsx', sheet_name='data')


# 1.初始化
pygame.init()
# 2.设置窗体名称
pygame.display.set_caption('智能停车场车牌识别计费系统')
# 3.加载图片,设置图标
ic_launcher=pygame.image.load('file/ic_launcher.jpg')
pygame.display.set_icon(ic_launcher)
# 4.设置窗体大小、背景颜色
screen=pygame.display.set_mode(size)
screen.fill(BG)

try:
    cam=cv2.VideoCapture(0)  # 创建摄像头实例
except:
    print('请连接摄像头')

# 游戏循环帧率设置(控制程序运行时间)
clock=pygame.time.Clock()

# 主线程
while True:

    # 从摄像头读取图片
    sucess, img = cam.read()
    # 保存图片
    cv2.imwrite('file/test.jpg', img)
    # 加载图像
    image = pygame.image.load('file/test.jpg')
    # 设置图片大小
    image = pygame.transform.scale(image, (640, 480))
    # 绘制视频画面
    screen.blit(image, (2, 2))

    # 创建识别按钮
    btn.Button(screen, (640, 480), 150, 60, BLUE, WHITE, "识别", 25)

    for event in pygame.event.get():
        # 关闭页面游戏退出
        if event.type==pygame.QUIT:
            pygame.quit()
            exit()
        elif event.type==pygame.MOUSEBUTTONDOWN:
            print(str(event.pos[0])+':'+str(event.pos[1]))
            #识别按钮
            if 492<=event.pos[0] and event.pos[0]<=642 and 422<=event.pos[1] and event.pos[1]<=482:
                print('点击识别')
                try:
                    carnumber=ocrutil.getcn()  #获取识别的车牌号
                except:
                    print('识别错误')
                    continue
                pass

    pygame.display.flip()        # 更新界面
    clock.tick(FPS)              # 控制游戏最大帧率为60


运行效果图如下

智能停车场车牌识别系统(一)_第5张图片
上述图片是我自己在网上找的车牌图片,对准摄像头,点击“识别”按钮,就会在控制台上输出车牌号,效果图如下:

智能停车场车牌识别系统(一)_第6张图片

车辆信息的保存与读取

【其实就是.xlsx文件的读取与修改(插入,删除)】

进一步设置窗体界面,用于显示车辆信息

  1. 创建text0()方法,用于设置背景、绘制横线、绘制信息框
  2. 创建text1()方法,用于显示车位文字,包括共有车位数量和剩余车位数量(初始化设置共有车位数量为100)
  3. 创建text2()方法,用于设置停车场表头信息,包括车辆号和进入停车场的时间

main.py文件代码如下:

import pygame

import pandas as pd
from pandas import DataFrame
import os
import cv2

import btn
import ocrutil

size=1000,484              # 窗体大小
FPS=60                     # 设置帧率(屏幕每秒的刷新次数)
# 设置背景颜色
DARKBLUE=(73,119,142)
BG=DARKBLUE
#定义颜色
BLAK=(0,0,0)
WHITE=(255,255,255)
GREEN=(0,255,0)
BLUE=(72,61,139)
GRAY=(96,96,96)
RED=(220,20,60)
YELLOW=(255,255,0)

Total =100            # 一共有多少车位

#获取当前项目的路径
cdir=os.getcwd()
#文件路径
path=cdir+'/datafile/'
if not os.path.exists(path):
    os.makedirs(path) #根据路径建立文件夹
    #车牌号、日期、价格、状态
    carnfile=pd.DataFrame(columns=['carnumber','date','price','state'])
    #生成.xlsx文件
    carnfile.to_excel(path+'停车场车辆表.xlsx',sheet_name='data')
    carnfile.to_excel(path+'停车场信息表.xlsx', sheet_name='data')

# 读取文件内容
pi_table=pd.read_excel(path+'停车场车辆表.xlsx',sheet_name='data')
pi_info_table=pd.read_excel(path+'停车场信息表.xlsx', sheet_name='data')
# 停车场车辆,获取所需列的值
cars=pi_table[['carnumber','date','state']].values
# 已进入停车场数量
carn=len(cars)



# 1.初始化
pygame.init()
# 2.设置窗体名称
pygame.display.set_caption('智能停车场车牌识别计费系统')
# 3.加载图片,设置图标
ic_launcher=pygame.image.load('file/ic_launcher.jpg')
pygame.display.set_icon(ic_launcher)
# 4.设置窗体大小、背景颜色
screen=pygame.display.set_mode(size)
screen.fill(BG)

try:
    cam=cv2.VideoCapture(0)  # 创建摄像头实例
except:
    print('请连接摄像头')


#背景和信息文字
def text0(screen):
    pygame.draw.rect(screen,BG,(650,2,350,640))  # 底色
    pygame.draw.aaline(screen,GREEN,(662,50),(980,50),1)  # 绘制横线
    pygame.draw.rect(screen,GREEN,(650,350,342,85),1)  # 绘制信息矩形框

    xtfont=pygame.font.SysFont('SimHei',15)   # 使用系统字体
    textstart=xtfont.render('信息',True,GREEN)  # 信息文字

    text_rect=textstart.get_rect()  # 获取文字图像位置
    #设置文字图像中心点
    text_rect.centerx=675
    text_rect.centery=365

    screen.blit(textstart,text_rect)  # 绘制内容


#车位文字
def text1(screen):
    k=Total-carn  # 剩余车位
    if k<10:
        sk='0'+str(k)
    else:
        sk=str(k)
    xtfont = pygame.font.SysFont('SimHei', 20)
    textstart=xtfont.render('共有车位:'+str(Total)+'   剩余车位:'+sk,True,WHITE)  # 添加文字信息
    text_rect=textstart.get_rect()  # 获取文字图像位置
    # 设置文字图像中心点
    text_rect.centerx=820
    text_rect.centery=30
    # 绘制内容
    screen.blit(textstart,text_rect)


#停车场信息表头
def text2(screen):
    xtfont = pygame.font.SysFont('SimHei', 15)
    textstart = xtfont.render('车号      时间' , True, WHITE)  # 添加文字信息
    text_rect = textstart.get_rect()  # 获取文字图像位置
    # 设置文字图像中心点
    text_rect.centerx = 820
    text_rect.centery = 70

    screen.blit(textstart, text_rect)  # 绘制内容




# 游戏循环帧率设置(控制程序运行时间)
clock=pygame.time.Clock()

# 主线程
while True:

    # 从摄像头读取图片
    sucess, img = cam.read()
    # 保存图片
    cv2.imwrite('file/test.jpg', img)
    # 加载图像
    image = pygame.image.load('file/test.jpg')
    # 设置图片大小
    image = pygame.transform.scale(image, (640, 480))
    # 绘制视频画面
    screen.blit(image, (2, 2))

    text0(screen)  # 背景和信息文字
    text1(screen)  # 停车位信息
    text2(screen)  # 停车场信息表头

    # 创建识别按钮
    btn.Button(screen, (640, 480), 150, 60, BLUE, WHITE, "识别", 25)

    for event in pygame.event.get():
        # 关闭页面游戏退出
        if event.type==pygame.QUIT:
            pygame.quit()
            exit()
        elif event.type==pygame.MOUSEBUTTONDOWN:
            print(str(event.pos[0])+':'+str(event.pos[1]))
            #识别按钮
            if 492<=event.pos[0] and event.pos[0]<=642 and 422<=event.pos[1] and event.pos[1]<=482:
                print('点击识别')
                try:
                    carnumber=ocrutil.getcn()  #获取识别的车牌号
                except:
                    print('识别错误')
                    continue
                pass

    pygame.display.flip()        # 更新界面
    clock.tick(FPS)              # 控制游戏最大帧率为60

可以看出每个方法主要有四步:(如果要给窗体写入文本就分为四步)
①pygame.font.SysFont(’ ', ): 设置文本的字体和大小,第一个参数为字体样式,第二个参数为字体大小;
例如:xtfont = pygame.font.SysFont(‘SimHei’, 15)

②render(’ ’ , True, ) :设置写到窗体的文本,以及文本的颜色,第一个参数为写到窗体的内容,第三个参数为字体颜色
例如:textstart = xtfont.render(‘车号 时间’ , True, WHITE)

③get_rect():获取文字图像位置,并且设置文字图像在x轴y轴中的位置
例如:
text_rect = textstart.get_rect()
text_rect.centerx = 820
text_rect.centery = 70

④screen.blit( , ):将文本图像绘制到窗体中
例如:screen.blit(textstart, text_rect)

运行效果图:

智能停车场车牌识别系统(一)_第7张图片

在主窗体显示停车场车辆信息

主窗体主要显示三部分内容:

  1. 显示 进入停车场的车号和时间:创建text3()方法,读取停车场车辆表.xlsx,循环显示进入停车场的车辆的车号和进入时间。如果停车场车辆数大于10的话,就显示最近的10个车辆信息。

  2. 显示停车时间最长的车辆号和停车时间:创建text4()方法,读取停车场车辆表.xlsx,直接获取第一行信息就是停车时间最长的信息,调用timeutil.py文件的DtCalc()方法计算停车时间,然后显示到窗体中。

  3. 在信息框中显示提示信息:创建text5()方法显示提示信息,还是上面提到的主要四步。

  4. 修改代码,点击识别按钮时候,先调用车辆识别模块获取车牌号,再判断车牌号是否在停车场车辆表.xlsx文件中,如果在文件中的话计算停车费并且删除车辆信息,如果不在文件中又分为两种情况:一是停车场车辆未满,则在文件中插入车辆信息,可以停车;另一种情况是停车场已经满了,则不能停车,显示没有空位的提示信息。

  5. 停车场信息表.xlsx文件中,state列有三个值:state=0表示车辆进入停车场并且还有空位;state=1表示车辆离开停车场;state=2表示车辆进入停车场但是没有空位了。

main.py文件代码如下:

import time

import pygame

import pandas as pd
from pandas import DataFrame
import os
import cv2

import btn
import ocrutil
import timeutil

size=1000,484              # 窗体大小
FPS=60                     # 设置帧率(屏幕每秒的刷新次数)
# 设置背景颜色
DARKBLUE=(73,119,142)
BG=DARKBLUE
#定义颜色
BLAK=(0,0,0)
WHITE=(255,255,255)
GREEN=(0,255,0)
BLUE=(72,61,139)
GRAY=(96,96,96)
RED=(220,20,60)
YELLOW=(255,255,0)

#信息内容
txt1=''
txt2=''
txt3=''

Total =5            # 一共有多少车位

#获取当前项目的路径
cdir=os.getcwd()
#文件路径
path=cdir+'/datafile/'
if not os.path.exists(path):
    os.makedirs(path) #根据路径建立文件夹
    #车牌号、日期、价格、状态
    carnfile=pd.DataFrame(columns=['carnumber','date','price','state'])
    #生成.xlsx文件
    carnfile.to_excel(path+'停车场车辆表.xlsx',sheet_name='data')
    carnfile.to_excel(path+'停车场信息表.xlsx', sheet_name='data')

# 读取文件内容
pi_table=pd.read_excel(path+'停车场车辆表.xlsx',sheet_name='data')
pi_info_table=pd.read_excel(path+'停车场信息表.xlsx', sheet_name='data')
# 停车场车辆,获取所需列的值
cars=pi_table[['carnumber','date','state']].values
# 已进入停车场数量
carn=len(cars)



# 1.初始化
pygame.init()
# 2.设置窗体名称
pygame.display.set_caption('智能停车场车牌识别计费系统')
# 3.加载图片,设置图标
ic_launcher=pygame.image.load('file/ic_launcher.jpg')
pygame.display.set_icon(ic_launcher)
# 4.设置窗体大小、背景颜色
screen=pygame.display.set_mode(size)
screen.fill(BG)

try:
    cam=cv2.VideoCapture(0)  # 创建摄像头实例
except:
    print('请连接摄像头')


#背景和信息文字
def text0(screen):
    pygame.draw.rect(screen,BG,(650,2,350,640))  # 底色
    pygame.draw.aaline(screen,GREEN,(662,50),(980,50),1)  # 绘制横线
    pygame.draw.rect(screen,GREEN,(650,350,342,85),1)  # 绘制信息矩形框

    xtfont=pygame.font.SysFont('SimHei',15)   # 使用系统字体
    textstart=xtfont.render('信息',True,GREEN)  # 信息文字

    text_rect=textstart.get_rect()  # 获取文字图像位置
    #设置文字图像中心点
    text_rect.centerx=675
    text_rect.centery=365

    screen.blit(textstart,text_rect)  # 绘制内容


#车位文字
def text1(screen):
    k=Total-carn  # 剩余车位
    if k<10:
        sk='0'+str(k)
    else:
        sk=str(k)
    xtfont = pygame.font.SysFont('SimHei', 20)
    textstart=xtfont.render('共有车位:'+str(Total)+'   剩余车位:'+sk,True,WHITE)  # 添加文字信息
    text_rect=textstart.get_rect()  # 获取文字图像位置
    # 设置文字图像中心点
    text_rect.centerx=820
    text_rect.centery=30
    # 绘制内容
    screen.blit(textstart,text_rect)


#停车场信息表头
def text2(screen):
    xtfont = pygame.font.SysFont('SimHei', 15)
    textstart = xtfont.render('车号      时间' , True, WHITE)  # 添加文字信息
    text_rect = textstart.get_rect()  # 获取文字图像位置
    # 设置文字图像中心点
    text_rect.centerx = 820
    text_rect.centery = 70

    screen.blit(textstart, text_rect)  # 绘制内容


#停车场车辆信息
def text3(screen):
    xtfont=pygame.font.SysFont('SimHei',12)
    cars = pi_table[['carnumber', 'date', 'state']].values  # 获取停车场车辆信息
    # 页面绘制10辆车信息
    if len(cars)>10:
        cars=pd.read_excel(path+'停车场车辆表.xlsx',skiprows=len(cars)-10,sheet_name='data').values
    n=0
    # 循环显示车辆信息
    for car in cars:
        n+=1
        textstart=xtfont.render('     '+str(car[0])+'    '+str(car[1]),True,WHITE)  # 显示车号和进入时间
        text_rect=textstart.get_rect()  # 获取文字图像位置
        # 设置文字图像中心点
        text_rect.centerx=820
        text_rect.centery=70+20*n
        # 绘制内容
        screen.blit(textstart,text_rect)


#最长停放的车辆和时间
def text4(screen):
    cars = pi_table[['carnumber', 'date', 'state']].values
    #print(len(cars))
    if len(cars)>0:
        longcar=cars[0][0]
        cartime=cars[0][1]
        #print(cartime)
        xtfont=pygame.font.SysFont('SimHei',15)
        #转换当前时间2020-8-5 19:07
        localtime = time.strftime('%Y-%m-%d %H:%M', time.localtime())
        htime=timeutil.DtCalc(cartime,localtime)
        # 添加文字
        textscar=xtfont.render('停车时间最长车辆:'+str(longcar),True,RED)
        texttime=xtfont.render('已停车:'+str(htime)+'小时',True,RED)
        # 获取文字图像位置
        text_rect1=textscar.get_rect()
        text_rect2=texttime.get_rect()
        # 设置文字图像中心点
        text_rect1.centerx = 820
        text_rect1.centery = 320
        text_rect2.centerx = 820
        text_rect2.centery = 335
        # 绘制内容
        screen.blit(textscar,text_rect1)
        screen.blit(texttime,text_rect2)

#在信息框中显示信息
def text5(screen,txt1,txt2,txt3):
    xtfont = pygame.font.SysFont('SimHei', 15)

    texttxt1=xtfont.render(txt1,True,GREEN)
    text_rect=texttxt1.get_rect()
    text_rect.centerx=820
    text_rect.centery=355+20
    screen.blit(texttxt1,text_rect)

    texttxt2 = xtfont.render(txt2, True, GREEN)
    text_rect = texttxt2.get_rect()
    text_rect.centerx = 820
    text_rect.centery = 355 + 40
    screen.blit(texttxt2, text_rect)

    texttxt3 = xtfont.render(txt3, True, GREEN)
    text_rect = texttxt3.get_rect()
    text_rect.centerx = 820
    text_rect.centery = 355 + 60
    screen.blit(texttxt3, text_rect)




# 游戏循环帧率设置(控制程序运行时间)
clock=pygame.time.Clock()

# 主线程
while True:

    # 从摄像头读取图片
    sucess, img = cam.read()
    # 保存图片
    cv2.imwrite('file/test.jpg', img)
    # 加载图像
    image = pygame.image.load('file/test.jpg')
    # 设置图片大小
    image = pygame.transform.scale(image, (640, 480))
    # 绘制视频画面
    screen.blit(image, (2, 2))

    text0(screen)  # 背景和信息文字
    text1(screen)  # 停车位信息
    text2(screen)  # 停车场信息表头
    text3(screen)  # 停车场车辆信息
    text4(screen)  # 最长停放的车辆和时间
    text5(screen, txt1, txt2, txt3)  # 在信息框中显示信息

    # 创建识别按钮
    btn.Button(screen, (640, 480), 150, 60, BLUE, WHITE, "识别", 25)

    for event in pygame.event.get():
        # 关闭页面游戏退出
        if event.type==pygame.QUIT:
            pygame.quit()
            exit()
        elif event.type==pygame.MOUSEBUTTONDOWN:
            print(str(event.pos[0])+':'+str(event.pos[1]))
            # 识别按钮
            if 492 <= event.pos[0] and event.pos[0] <= 642 and 422 <= event.pos[1] and event.pos[1] <= 482:
                print('点击识别')
                try:
                    carnumber = ocrutil.getcn()  # 获取识别的车牌号
                    # 格式化当前时间
                    localtime = time.strftime('%Y-%m-%d %H:%M', time.localtime())

                    carsk = pi_table['carnumber'].values  # 获取车牌号列数据
                    # 判断当前识别的车是否为停车场车辆
                    if carnumber in carsk:
                        txt1 = '车牌号: ' + carnumber
                        y = 0  # 时间差
                        kcar = 0 # 获取行数用
                        # 获取车辆信息
                        cars = pi_table[['carnumber', 'date', 'state']].values
                        for car in cars:
                            if carnumber == car[0]:
                                y = timeutil.DtCalc(car[1], localtime)  # 计算时间差,停车时间
                                break
                            kcar = kcar + 1
                        if y == 0:
                            y = 1
                        txt2 = '停车费: ' + str(3 * y) + '元'
                        txt3 = '出停车场时间: ' + localtime
                        # 删除此辆车的车辆信息
                        pi_table = pi_table.drop([kcar], axis=0)

                        # 更新停车场信息
                        pi_info_table = pi_info_table.append({'carnumber': carnumber,
                                                              'date': localtime,
                                                              'price': 3 * y,
                                                              'state': 1}, ignore_index=True)
                        # 保存信息更新xlsx文件
                        DataFrame(pi_table).to_excel(path + '停车场车辆表.xlsx',
                                                     sheet_name='data', index=False, header=True)
                        DataFrame(pi_info_table).to_excel(path + '停车场信息表.xlsx',
                                                          sheet_name='data', index=False, header=True)
                        carn -= 1  # 更新停车场车辆数目

                    else:
                        # print('输出:'+str(carn))
                        if carn < Total:
                            # 添加车辆信息
                            pi_table = pi_table.append({'carnumber': carnumber,
                                                        'date': localtime,
                                                        'state': 0}, ignore_index=True)
                            # 更新xlsx文件
                            DataFrame(pi_table).to_excel(path + '停车场车辆表.xlsx',
                                                         sheet_name='data', index=False, header=True)
                            if carn == Total - 1:
                                # state=2表示停车场没有车位
                                pi_info_table = pi_info_table.append({'carnumber': carnumber,
                                                                      'date': localtime,
                                                                      'state': 2}, ignore_index=True)
                            else:
                                # state=0表示停车场还有车位
                                pi_info_table = pi_info_table.append({'carnumber': carnumber,
                                                                      'date': localtime,
                                                                      'state': 0}, ignore_index=True)
                            carn += 1
                            DataFrame(pi_info_table).to_excel(path + '停车场信息表.xlsx',
                                                              sheet_name='data', index=False, header=True)
                            # 有停车位的提示信息
                            txt1 = '车牌号:' + carnumber
                            txt2 = '有空余车位,可以进入停车场'
                            txt3 = '进停车场时间:' + localtime
                        else:
                            # 没有停车位的提示信息
                            txt1 = '车牌号:' + carnumber
                            txt2 = '没有空余车位,不可以进入停车场'
                            txt3 = '时间:' + localtime

                except Exception as e:
                    print('错误原因:', e)
                    continue
                pass

    pygame.display.flip()        # 更新界面
    clock.tick(FPS)              # 控制游戏最大帧率为60

为了测试各种情况,把停车场总车位数量改成了5位

运行效果如图:

①车辆进入停车场:可以看到剩余车位在变化,车号和时间也显示出来了,停车时间最长车辆就是第一个进入停车场的车,提示信息也显示出来了。

智能停车场车牌识别系统(一)_第8张图片
②可以看到当前停车场已经满了,剩余车位是0。此时沪KR9888车辆进来之后,点击识别,会出现提示信息:没有空余车位,不可以进入停车场。

智能停车场车牌识别系统(一)_第9张图片

③车辆离开停车场,上一张图可以看到京PT3G98已经进入停车场了,此时又要出停车场,此时会计算停车费(停车费每小时3元计算),并且从停车场文件中删除该车辆信息。

智能停车场车牌识别系统(一)_第10张图片
此时两个文件的内容如下:

①停车场车辆表.xlsx文件:主要保存的是该停车场里的车辆信息,进入停车场就插入信息,离开停车场就删除信息

智能停车场车牌识别系统(一)_第11张图片
②停车场信息表.xlsx文件:保存的是所有进出过该停车场的车辆信息。state列有三个值:state=0表示车辆进入停车场并且还有空位;state=1表示车辆离开停车场;state=2表示车辆进入停车场但是没有空位了。

智能停车场车牌识别系统(一)_第12张图片

该项目的核心内容已经完成了,下一篇文章主要实现收入统计功能和满预警功能。
链接:智能停车场车牌识别系统(二)
转载请注明链接出处,谢谢!
自己完成的一个小项目,记录一下吧。
有什么问题或者需要源代码的,可以评论。我看到的就会回复!!!

你可能感兴趣的:(python)