python实现小区车牌识别计费程序

python实现小区车牌识别计费程序

示例简介

python利用百度文字识别功能,实现小区车辆进出识别,并显示进出信息和收费信息;可查看停车信息,也可查看历史数据;

开发环境:Windows7+python3.7+pycharm2018.2.4(开发工具);

目录机构:

最终效果:由于涉及隐私,不能上传动态效果;左边为摄像头的画面(这里是视频播放页面),右上角显示车位情况和最近十条车辆信息,右下角显示识别信息、收费信息或提示信息;

百度端创建应用

创建过程参考《微信小程序利用百度AI实现扫描身份证获取信息功能》(把“图像识别”换为“文字识别”)。

实现过程

1、文件“settings.py”用来设置该程序的基础信息;

classSettings():definit(self):“”“初始化设置”“”#屏幕设置(宽、高、背景色、线颜色)self.screen_width=1000self.screen_height=484self.bg_color=(255,255,255)#停车位self.total=100#识别颜色、车牌号、进来时间、出入场信息self.ocr_color=(212,35,122)self.carnumber=‘’self.comeInTime=‘’self.message=‘’

2、文件“timeutil.py”有两个函数:

函数time_cmp主要用来比较出场时间跟卡有效期,判断业主是否需要收费;

函数priceCalc用来计算停车时间,里面存在两种情况,一种是外来车,只需要比较出入场时间差;另一种是业主车,入场时,卡未到期,但出场时间已经到期,所以需要比较卡有效期和出场时间的差值;

Tips:由于读取Excel的卡有效期字段,会多“.xxxx”这部分,所以需要经过split(‘.’)处理。

importdatetimeimportmath#计算两个日期大小deftime_cmp(first_time,second_time):#由于有效期获取后会有小数数据firstTime=datetime.datetime.strptime(str(first_time).split(‘.’)[0],“%Y-%m-%d%H:%M:%S”)secondTime=datetime.datetime.strptime(str(second_time),“%Y-%m-%d%H:%M”)number=1iffirstTime>secondTimeelse0returnnumber#计算停车时间四舍五入defpriceCalc(inDate,outDate):if‘.’instr(inDate):inDate=str(inDate).split(‘.’)[0]inDate=datetime.datetime.strptime(inDate,“%Y-%m-%d%H:%M:%S”)print(‘特殊处理’)else:inDate=datetime.datetime.strptime(inDate,“%Y-%m-%d%H:%M”)outDate=datetime.datetime.strptime(str(outDate),“%Y-%m-%d%H:%M”)rtn=outDate-inDate#计算停车多少小时(往上取整)y=math.ceil(rtn.total_seconds()/60/60)returny

3、文件“button.py”用来绘制按钮,这里用来绘制“识别”按钮;

importpygame.fontclassButton():definit(self,screen,msg):“”“初始化按钮的属性”“”self.screen=screenself.screen_rect=screen.get_rect()#设置按钮的尺寸和其他属性self.width,self.height=100,50self.button_color=(0,120,215)self.text_color=(255,255,255)self.font=pygame.font.SysFont(‘SimHei’,25)#创建按钮的rect对象,并使其居中self.rect=pygame.Rect(0,0,self.width,self.height)#创建按钮的rect对象,并设置按钮中心位置self.rect.centerx=640-self.width/2+2self.rect.centery=480-self.height/2+2#按钮的标签只需创建一次self.prep_msg(msg)defprep_msg(self,msg):“”“将msg渲染为图像,并使其在按钮上居中”“”self.msg_image=self.font.render(msg,True,self.text_color,self.button_color)self.msg_image_rect=self.msg_image.get_rect()self.msg_image_rect.center=self.rect.centerdefdraw_button(self):#绘制一个用颜色填充的按钮,再绘制文本self.screen.fill(self.button_color,self.rect)self.screen.blit(self.msg_image,self.msg_image_rect)

4、文件“textboard.py”用来绘制背景和文字;

importpygame.font#线颜色line_color=(0,0,0)#显示文字信息时使用的字体设置text_color=(0,0,0)defdraw_bg(screen):#背景文图案bgfont=pygame.font.SysFont(‘SimHei’,15)#绘制横线pygame.draw.aaline(screen,line_color,(662,30),(980,30),1)#渲染为图片text_image=bgfont.render(‘识别信息:’,True,text_color)#获取文字图像位置text_rect=text_image.get_rect()#设置文字图像中心点text_rect.left=660text_rect.top=370#绘制内容screen.blit(text_image,text_rect)#绘制文字(text-文字内容、xpos-x坐标、ypos-y坐标、fontSize-字体大小)defdraw_text(screen,text,xpos,ypos,fontsize,tc=text_color):#使用系统字体xtfont=pygame.font.SysFont(‘SimHei’,fontsize)text_image=xtfont.render(text,True,tc)#获取文字图像位置text_rect=text_image.get_rect()#设置文字图像中心点text_rect.left=xpostext_rect.top=ypos#绘制内容screen.blit(text_image,text_rect)

5、文件“ocrutil.py”用来调用百度文字识别SDK,获取图片中的车牌信息;

Tips:文件“test.jpg”为从摄像头读取的图片,每次循环获取一次,这里为了测试方便使用视频;

fromaipimportAipOcrimportos#百度识别车牌#申请地址https://login.bce.baidu.com/filename='file/key.txt'#记录申请的Key的文件位置ifos.path.exists(filename):#判断文件是否存在withopen(filename,"r")asfile:#打开文件dictkey=eval(file.readlines()[0])#读取全部内容转换为字典#以下获取的三个Key是进入百度AI开放平台的控制台的应用列表里创建应用得来的APP_ID=dictkey['APP_ID']#获取申请的APIIDAPI_KEY=dictkey['API_KEY']#获取申请的APIKEYSECRET_KEY=dictkey['SECRET_KEY']#获取申请的SECRETKEYelse:print("请先在file目录下创建key.txt,并且写入申请的Key!格式如下:""n{'APP_ID':'申请的APIID','API_KEY':'申请的APIKEY','SECRET_KEY':'申请的SECRETKEY'}")#初始化AipOcr对象client=AipOcr(APP_ID,API_KEY,SECRET_KEY)#读取文件defget_file_content(filePath):withopen(filePath,'rb')asfp:returnfp.read()#根据图片返回车牌号defgetcn():#读取图片image=get_file_content('images/test.jpg')#调用车牌识别results=client.licensePlate(image)['words_result']['number']#输出车牌号returnresults

6、文件“procedure_functions.py”存放跟程序相关的业务逻辑函数;

里面比较复杂的就是点击“识别”按钮后的逻辑处理(event.type==pygame.MOUSEBUTTONDOWN):

1)当停车场没有停车时,只需要识别后,把车辆信息存入“停车场车辆表”并把相关信息显示到界面右下角;

2)当停车场已有停车时,会出现两种情况,一种是入场,一种是出场:

入场需判断是否停车场已满,已满则不给进入并显示提示信息;未满则把车辆信息存入“停车场车辆表”并把相关信息显示到界面右下角;

出场分业主有效、业主过期、外来车三种情况收费,并删除车辆表相应的车辆信息,并把车辆信息和收费信息等存入“停车场历史表”(可用于后面数据的汇总统计);

importsysimportpygameimporttimeimportpandasaspdimportocrutilimporttimeutil#事件defcheck_events(settings,recognition_button,ownerInfo_table,carInfo_table,history_table,path):“”“响应按键和鼠标事件”“”foreventinpygame.event.get():ifevent.type==pygame.QUIT:sys.exit()elifevent.type==pygame.MOUSEBUTTONDOWN:mouse_x,mouse_y=pygame.mouse.get_pos()button_clicked=recognition_button.rect.collidepoint(mouse_x,mouse_y)ifbutton_clicked:try:#获取车牌carnumber=ocrutil.getcn()#转换当前时间2018-12-1116:18localtime=time.strftime(‘%Y-%m-%d%H:%M’,time.localtime())settings.carnumber=‘车牌号码:’+carnumber#判断进入车辆是否业主车辆#获取业主车辆信息(只显示卡未过期)ownerInfo_table=ownerInfo_table[ownerInfo_table[‘validityDate’]>localtime]owner_carnumbers=ownerInfo_table[[‘carnumber’,‘validityDate’]].valuescarnumbers=ownerInfo_table[‘carnumber’].values#获取车辆表信息carInfo_carnumbers=carInfo_table[[‘carnumber’,‘inDate’,‘isOwner’,‘validityDate’]].valuescars=carInfo_table[‘carnumber’].values#增加车辆信息append_carInfo={‘carnumber’:carnumber}#增加历史信息append_history={‘carnumber’:carnumber}carInfo_length=len(carInfo_carnumbers)#车辆表未有数据ifcarInfo_length==0:print(‘未有车辆数据入场’)in_park(owner_carnumbers,carnumbers,carInfo_table,append_carInfo,carnumber,localtime,settings,path)#车辆表有数据else:ifcarnumberincars:#出停车场i=0forcarInfo_carnumberincarInfo_carnumbers:ifcarnumber==carInfo_carnumber[0]:ifcarInfo_carnumber[2]==1:iftimeutil.time_cmp(carInfo_carnumber[3],localtime):print(‘业主车,自动抬杠’)msgMessage=‘业主车,可出停车场’parkPrice=‘业主卡’else:print(‘业主车,但卡已过期,收费抬杠’)#比较卡有效期时间price=timeutil.priceCalc(carInfo_carnumber[3],localtime)msgMessage=‘停车费用:’+str(5*int(price))+‘(提醒业主,卡已到期)’parkPrice=5*int(price)else:print(‘外来车,收费抬杠’)#比较入场时间price=timeutil.priceCalc(carInfo_carnumber[1],localtime)msgMessage=‘停车费用:’+str(5*price)parkPrice=5*int(price)print(i)carInfo_table=carInfo_table.drop([i])#增加数据到历史表append_history[‘inDate’]=carInfo_carnumber[1]append_history[‘outData’]=localtimeappend_history[‘price’]=parkPriceappend_history[‘isOwner’]=carInfo_carnumber[2]append_history[‘validityDate’]=carInfo_carnumber[3]history_table=history_table.append(append_history,ignore_index=True)settings.comeInTime=‘出场时间:’+localtimesettings.message=msgMessage#更新车辆表和历史表pd.DataFrame(carInfo_table).to_excel(path+‘停车场车辆表’+‘.xlsx’,sheet_name=‘data’,index=False,header=True)pd.DataFrame(history_table).to_excel(path+‘停车场历史表’+‘.xlsx’,sheet_name=‘data’,index=False,header=True)breaki+=1else:#入停车场print(‘有车辆表数据入场’)ifcarInfo_length<settings.total:in_park(owner_carnumbers,carnumbers,carInfo_table,append_carInfo,carnumber,localtime,settings,path)else:print(‘停车场已满’)settings.comeInTime=‘进场时间:’+localtimesettings.message=‘停车场已满,无法进入’exceptExceptionase:print(“错误原因:”,e)continuepass#车辆入停车场defin_park(owner_carnumbers,carnumbers,carInfo_table,append_carInfo,carnumber,localtime,settings,path):ifcarnumberincarnumbers:forowner_carnumberinowner_carnumbers:ifcarnumber==owner_carnumber[0]:print(‘业主车,自动抬杠’)msgMessage=‘提示信息:业主车,可入停车场’append_carInfo[‘isOwner’]=1append_carInfo[‘validityDate’]=owner_carnumber[1]#退出循环breakelse:print(‘外来车,识别抬杠’)msgMessage=‘提示信息:外来车,可入停车场’append_carInfo[‘isOwner’]=0append_carInfo[‘inDate’]=localtimesettings.comeInTime=‘进场时间:’+localtimesettings.message=msgMessage#添加信息到车辆表carInfo_table=carInfo_table.append(append_carInfo,ignore_index=True)#更新车辆表pd.DataFrame(carInfo_table).to_excel(path+‘停车场车辆表’+‘.xlsx’,sheet_name=‘data’,index=False,header=True)

7、文件“main.py”为程序的主函数,用来初始化程序,并同步更新程序的信息。

importpygameimportcv2importosimportpandasaspd#引入自定义模块fromsettingsimportSettingsfrombuttonimportButtonimporttextboardimportprocedure_functionsaspfdefrun_procedure():#获取文件的路径cdir=os.getcwd()#文件夹路径path=cdir+‘/file/’#读取路径ifnotos.path.exists(path+‘停车场车辆表’+‘.xlsx’):#车牌号进入时间离开时间价格是否业主carnfile=pd.DataFrame(columns=[‘carnumber’,‘inDate’,‘outData’,‘price’,‘isOwner’,‘validityDate’])#生成xlsx文件carnfile.to_excel(path+‘停车场车辆表’+‘.xlsx’,sheet_name=‘data’)carnfile.to_excel(path+‘停车场历史表’+‘.xlsx’,sheet_name=‘data’)settings=Settings()#初始化并创建一个屏幕对象pygame.init()pygame.display.set_caption(‘智能小区车牌识别系统’)ic_launcher=pygame.image.load(‘images/icon_launcher.png’)pygame.display.set_icon(ic_launcher)screen=pygame.display.set_mode((settings.screen_width,settings.screen_height))try:#cam=cv2.VideoCapture(0)#开启摄像头cam=cv2.VideoCapture(‘file/test.mp4’)except:print(‘请连接摄像头’)#循环帧率设置clock=pygame.time.Clock()running=True#开始主循环whilerunning:screen.fill(settings.bg_color)#从摄像头读取图片sucess,img=cam.read()#保存图片,并退出。ifsucess:cv2.imwrite(‘images/test.jpg’,img)else:#识别不到图片或者设备停止,则退出系统running=False#加载图像image=pygame.image.load(‘images/test.jpg’)#设置图片大小image=pygame.transform.scale(image,(640,480))#绘制视频画面screen.blit(image,(2,2))#创建识别按钮recognition_button=Button(screen,‘识别’)recognition_button.draw_button()#读取文件内容ownerInfo_table=pd.read_excel(path+‘住户车辆表.xlsx’,sheet_name=‘data’)carInfo_table=pd.read_excel(path+‘停车场车辆表.xlsx’,sheet_name=‘data’)history_table=pd.read_excel(path+‘停车场历史表.xlsx’,sheet_name=‘data’)inNumber=len(carInfo_table[‘carnumber’].values)#绘制背景textboard.draw_bg(screen)#绘制信息标题textboard.draw_text(screen,‘共有车位:’+str(settings.total)+‘剩余车位:’+str(settings.total-inNumber),680,0,20)#绘制信息表头textboard.draw_text(screen,‘车牌号进入时间’,700,40,15)#绘制停车场车辆前十条信息carInfos=carInfo_table.sort_values(by=‘inDate’,ascending=False)i=0forcarInfoincarInfos.values:ifi>=10:breaki+=1textboard.draw_text(screen,str(carInfo[1])+‘’+str(carInfo[2]),700,40+i*30,15)#绘制识别信息textboard.draw_text(screen,settings.carnumber,660,400,15,settings.ocr_color)textboard.draw_text(screen,settings.comeInTime,660,422,15,settings.ocr_color)textboard.draw_text(screen,settings.message,660,442,15,settings.ocr_color)“”“响应鼠标事件”“”pf.check_events(settings,recognition_button,ownerInfo_table,carInfo_table,history_table,path)pygame.display.flip()#控制游戏最大帧率为60clock.tick(60)#关闭摄像头cam.release()run_procedure()

本站所有文章资讯、展示的图片素材等内容均为注册用户上传(部分报媒/平媒内容转载自网络合作媒体),仅供学习参考。 用户通过本站上传、发布的任何内容的知识产权归属用户或原始著作权人所有。如有侵犯您的版权,请联系我们反馈本站将在三个工作日内改正。