这东西是真的难写,我搞了一晚上到两点,就睡了6个小时第二天还弄到早上十一点点半才弄完
程序运行效果
(时间显示和卡顿问题那块代码已经更新优化了,以实际代码运行为准)
###记得替换成自己的百度API里申请的东西
还有记得申请车牌识别的免费使用额度
登入进入该网址领取:
https://console.bce.baidu.com/ai/#/ai/ocr/overview/resource/getFree
{"APP_ID":"####", "API_KEY":"###", "SECRET_KEY":"###"}
其他不想解释了,想参考的可以看代码里的注释,或者加q:2234067636 问我
今晚还会更新,改一下结构,让代码更好读(改完了)
# -*- coding: utf-8 -*-
# @Time : 2021/7/22 16:45
# @Author : hzh
# @File : homework4.py
# @Software : PyCharm
#建议按住ctrl+鼠标左键点击进入源码查看导入的函数的用法
import pygame
import cv2
import datetime
import openpyxl
import json
import base64
import requests
import urllib
import pandas
import matplotlib.pyplot as plt0
# 保证表格中 中文字体可以用
plt0.rcParams['font.sans-serif'] = ['SimHei']
plt0.rcParams['axes.unicode_minus'] = False
#每次更新界面
def windowsupdate():
# 相机更新(拍照保存并读取输出到界面上)
ret, pic = cap.read()
cv2.imwrite('./file/test.jpg', pic)
img = pygame.image.load('./file/test.jpg')
screen.blit(img, (0, 0))
#数据更新1(读入excel并且得到表格和剩余车位的基础信息)
excelfile = openpyxl.load_workbook('./datafile/停车场信息表.xlsx')
excelfile2 = openpyxl.load_workbook('./datafile/停车场车辆表.xlsx')
sheet = excelfile['data']
sheet2 = excelfile2['data']
nrows = sheet.max_row
nrows2 = sheet2.max_row
carparknum = 100 - nrows2 + 1
totaltext0 = font2.render("共有车位:100 剩余车位:%d" % carparknum, True, (255, 255, 255))
#数据更新2 (显示左侧车辆出入信息)
sheettext = []
for i in range(nrows, 1,-1):
sheettext.append(font4.render("%s %s"%(str(sheet['B%s'%(str(i),)].value),sheet['C%s'%(str(i),)].value.strftime("%Y-%m-%d %H:%M:%S")),True,(255,255,255)))
pygame.draw.rect(screen,(73, 119, 142),pygame.Rect(totalx+30,totaly+65,280,240))
for i in range(0,nrows-1):
if totaly+65+i*20>240:
break
screen.blit(sheettext[i],(totalx+30,totaly+65+i*20))
#数据更新3 (计算并输出停最久的车)
nowtime = datetime.datetime.now()
midtime = []
for i in range(2,nrows2+1):
midtime.append((nowtime-sheet2['C%s'%(str(i),)].value,i))
timemax = sorted(midtime, key=lambda t: t[0], reverse= True)[0]
totaltext = font4.render("停车时间最长车辆:%s" % sheet2['B%s'%(str(timemax[1]),)].value, True, (220, 20, 60))
parkseconds = int(timemax[0].seconds)
parkhours = int(parkseconds/60/60)
parkminutes = (parkseconds/60)-parkhours*60
parkseconds %= 60
totaltext2 = font4.render("已停车:%s天%d小时%d分钟%d秒" %(timemax[0].days,parkhours,parkminutes,parkseconds), True, (220, 20, 60))
screen.blit(totaltext,(totalx+30,totaly+255))
screen.blit(totaltext2,(totalx+30,totaly+270))
#数据更新4 (预报更新)
weeknum = [[0,i] for i in range(0, 8)]
for i in range(2, nrows+1):
day = sheet['C%s' % (str(i),)].value.isoweekday()
weeknum[day][0] += 1
if (nowtime.isoweekday()+1) % 7 == sorted(weeknum, key=lambda t: t[0], reverse= True)[0][1]:
warningbg = pygame.Rect(0, 0, 640, 30)
pygame.draw.rect(screen, (255, 255, 0), warningbg)
warningtext = font2.render("根据数据分析,明天可能出现车位紧张的情况,请提前做好调度!", True, (220, 20, 60))
screen.blit(warningtext, (5, 5))
#固定元素更新(固定元素需要更新是为了处理按下统计后界面变化需要重新处理)
pygame.draw.rect(screen,(0,120,215),reconizearea)
screen.blit(reconizetext,(640-100+10,480-50+5))
pygame.draw.rect(screen,(220,20,60),staticarea)
screen.blit(starictext,(infox+205,infoy+115))
screen.blit(totaltext0,(totalx,totaly))
pygame.draw.line(screen,(0,128,0),(totalx-20,totaly+30),(totalx+270,totaly+30),width=2)
screen.blit(exceltitletext,(totalx+50,totaly+45))
#按下识别后,识别提示信息的更新
pygame.draw.rect(screen,(73, 119, 142),informationarea)
pygame.draw.rect(screen,(0,128,0),informationarea,width=2)
screen.blit(cartext1, informationarea1)
screen.blit(cartext2, informationarea2)
screen.blit(cartext3, informationarea3)
screen.blit(cartext4, informationarea4)
#将更新的信息显示
pygame.display.update()#flip函数将重新绘制整个屏幕对应的窗口,update函数仅仅重新绘制窗口中有变化的区域。
return sheet
#获取更新窗口,并生成图表等信息
def staticpic():
months = ['1月','2月','3月','4月','5月','6月','7月','8月','9月','10月','11月','12月']
sheet = windowsupdate()
nrows = sheet.max_row
sumprice = 0
for i in range(2,nrows+1):
sumprice += int(sheet['D%s'%(str(i),)].value)
sumpricetext = font2.render("共计收入:%s"%str(sumprice),True,(255,255,255))
screen.blit(sumpricetext,(1000+190,totaly))
monthprice = [0 for i in range(0,12)]
for i in range(2,nrows+1):
month = sheet['C%s'%(str(i),)].value.month
monthprice[month-1]+=int(sheet['D%s'%(str(i),)].value)
# matplotlib.rcParams['font.sans-serif'] = ['KaiTi']
plt = pandas.Series({months[i]: monthprice[i] for i in range(0,12)})
plt = plt.plot.bar(color="green",title = "每月收入统计",rot = 0,figsize = (4,4.2))
# .bar(x=months,y=monthprice,color="orange",title="每月收入统计").get_figure()
plt.get_figure().savefig("./file/income.png")
incomeimg = pygame.image.load("./file/income.png")
screen.blit(incomeimg,(1000+50,totaly+30))
pygame.display.update()
#按下识别键后,通过百度API获取车牌
def getcarnumber():
with open('./file/key.txt', 'r') as f:
x = f.read()
key = json.loads(x)
params = {'grant_type': 'client_credentials', 'client_id': key['API_KEY'], 'client_secret': key['SECRET_KEY']}
TOKEN_URL = 'https://aip.baidubce.com/oauth/2.0/token'
res = requests.post(url=TOKEN_URL, params=params)
token = json.loads(res.content.decode('utf-8'))['access_token']
url = 'https://aip.baidubce.com/rest/2.0/ocr/v1/license_plate' + "?access_token=" + token # 车牌检测
with open('./file/test.jpg', 'rb') as f:
carimg = f.read()
res2 = requests.post(url, urllib.parse.urlencode({'image': base64.b64encode(carimg),'top_num': 1}))
print(res2.content.decode('utf-8'))
try:
number = json.loads(res2.content.decode('utf-8'))['words_result']["number"]
except:
number = None
return number
#获取识别到的车牌后,处理识别的信息,并保存进excel
def excelupdate(carnumber):
excelfile = openpyxl.load_workbook('./datafile/停车场信息表.xlsx')
excelfile2 = openpyxl.load_workbook('./datafile/停车场车辆表.xlsx')
sheet = excelfile['data']
sheet2 = excelfile2['data']
nrows = sheet.max_row
nrows2 = sheet2.max_row
existedcar = {}
for i in range(2,nrows2+1):
existedcar[sheet2['B%d'%i].value]=(i,sheet2['C%d'%(i)].value)
nowtime = datetime.datetime.now()
sheet['B%d'%(nrows+1)] = carnumber
sheet['C%d'%(nrows+1)] = nowtime
# print(existedcar.keys())
if carnumber not in existedcar.keys():
sheet['E%d' % (nrows + 1)] = '入'
sheet['D%d'%(nrows+1)] = 0
cartext1= font4.render("信息" , True, (0, 255, 0))
cartext2= font4.render("车牌号:%s"%carnumber, True, (0, 255, 0))
if 100 - nrows2 +1 >0:
cartext3= font4.render("有空余车辆,可以进入停车场" , True, (0, 255, 0))
sheet2['B%d' % (nrows2 + 1)] = carnumber
sheet2['C%d' % (nrows2 + 1)] = nowtime
else:
cartext3 = font4.render("目前暂无位置,请耐心等待", True, (0, 255, 0))
cartext4= font4.render("进停车场时间:%s"%str(nowtime.strftime("%Y-%m-%d %H:%M:%S")) , True, (0, 255, 0))
else:
parktime = nowtime-existedcar[carnumber][1]
sheet['E%d' % (nrows + 1)] = '出'
sheet['D%d' % (nrows + 1)] = parktime.days*72+int(parktime.seconds/60/60)*3#按照一小时三块钱计费
sheet2.delete_rows(existedcar[carnumber][0])
# cartext = font4.render("信息\n车牌号:%s\n停车费:%d元\n出停车场时间:%s" % (carnumber,sheet['D%d' % (nrows + 1)].value, str(nowtime)), True, (0, 255, 0))
cartext1= font4.render("信息" , True, (0, 255, 0))
cartext2= font4.render("车牌号:%s"%carnumber, True, (0, 255, 0))
cartext3= font4.render("停车费:%d元"%sheet['D%d' % (nrows + 1)].value , True, (0, 255, 0))
cartext4= font4.render("出停车场时间:%s"%str(nowtime.strftime("%Y-%m-%d %H:%M:%S")) , True, (0, 255, 0))
excelfile.save('./datafile/停车场信息表.xlsx')
excelfile2.save('./datafile/停车场车辆表.xlsx')
return cartext1,cartext2,cartext3,cartext4
if __name__ == '__main__':
#界面元素初始化
carparknum = 100
pygame.init()
pygame.display.set_caption('智能停车场车牌识别计费系统')
iconimg = pygame.image.load('./file/ic_launcher.png')
pygame.display.set_icon(iconimg)
screen = pygame.display.set_mode(size = (1000,480))
screen.fill((73, 119, 142))
font = pygame.font.SysFont("simsunnsimsun", 40)
font2 = pygame.font.SysFont("simsunnsimsun", 20)
font3 = pygame.font.SysFont("simsunnsimsun", 30)
font4 = pygame.font.SysFont("simsunnsimsun", 15)
font5 = pygame.font.SysFont("simsunnsimsun", 10)
reconizearea = pygame.Rect(640-100,480-50,100,50)
reconizetext = font.render("识别", True, (255, 255, 255))
totalx = 640+50
totaly = 20
exceltitletext = font4.render("车号 时间",True,(255,255,255))
infox = 640+10
infoy = 480-170
informationarea = pygame.Rect(infox,infoy,340,100)
informationarea1 = pygame.Rect(infox+10,infoy+15,100,15)
informationarea2 = pygame.Rect(infox+110,infoy+30,100,15)
informationarea3 = pygame.Rect(infox+110,infoy+45,100,15)
informationarea4 = pygame.Rect(infox+10,infoy+60,100,15)
staticarea = pygame.Rect(infox+190,infoy+110,150,40)
starictext = font3.render("收入统计",True,(255,255,255))
cartext1 = font4.render("", True, (0, 255, 0))
cartext2 = font4.render("", True, (0, 255, 0))
cartext3 = font4.render("", True, (0, 255, 0))
cartext4 = font4.render("", True, (0, 255, 0))
cap = cv2.VideoCapture(0)#引入摄像机
windowsupdate()
windowstate = 0#记录是否按了统计健
while True:
event = pygame.event.wait(timeout=10)#超过10秒每接受到就跳过更新,不加timeout参数会出现卡顿的情况
if event.type == 1025:#按下了鼠标左键
x = event.__dict__['pos'][0]
y = event.__dict__['pos'][1]
if staticarea.collidepoint(x,y):#按到了统计
if windowstate == 1:
screen = pygame.display.set_mode(size=(1000, 480))
screen.fill((73, 119, 142))
windowstate = 0
else:
windowstate = 1
screen = pygame.display.set_mode(size=(1500, 480))
screen.fill((73, 119, 142))
staticpic()
continue
elif reconizearea.collidepoint(x,y):#按到了识别
carnumber = getcarnumber()
if carnumber is not None:
cartext1,cartext2,cartext3,cartext4 = excelupdate(carnumber)
else:
cartext1 = font4.render("信息", True, (0, 255, 0))
cartext2 = font4.render("无车辆", True, (0, 255, 0))
cartext3 = font4.render("", True, (0, 255, 0))
cartext4 = font4.render("", True, (0, 255, 0))
elif event.type == 256:#按到了退出
break
windowsupdate()