当前位置:   article > 正文

python实现小区车牌识别计费程序_ocrutil.getcn()

ocrutil.getcn()

示例简介

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

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

目录机构:

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

百度端创建应用

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

实现过程

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

  1. class Settings():
  2. def __init__(self):
  3. """ 初始化设置 """
  4. # 屏幕设置(宽、高、背景色、线颜色)
  5. self.screen_width = 1000
  6. self.screen_height = 484
  7. self.bg_color = (255, 255, 255)
  8. # 停车位
  9. self.total = 100
  10. # 识别颜色、车牌号、进来时间、出入场信息
  11. self.ocr_color = (212, 35, 122)
  12. self.carnumber = ''
  13. self.comeInTime = ''
  14. self.message = ''

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

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

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

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

  1. import datetime
  2. import math
  3. # 计算两个日期大小
  4. def time_cmp(first_time, second_time):
  5. # 由于有效期获取后会有小数数据
  6. firstTime = datetime.datetime.strptime(str(first_time).split('.')[0], "%Y-%m-%d %H:%M:%S")
  7. secondTime = datetime.datetime.strptime(str(second_time), "%Y-%m-%d %H:%M")
  8. number = 1 if firstTime > secondTime else 0
  9. return number
  10. # 计算停车时间
  11. def priceCalc(inDate, outDate):
  12. if '.' in str(inDate):
  13. inDate = str(inDate).split('.')[0]
  14. inDate = datetime.datetime.strptime(inDate, "%Y-%m-%d %H:%M:%S")
  15. print('特殊处理')
  16. else:
  17. inDate = datetime.datetime.strptime(inDate, "%Y-%m-%d %H:%M")
  18. outDate = datetime.datetime.strptime(str(outDate), "%Y-%m-%d %H:%M")
  19. rtn = outDate - inDate
  20. # 计算停车多少小时(往上取整)
  21. y = math.ceil(rtn.total_seconds() / 60 / 60)
  22. return y

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

  1. import pygame.font
  2. class Button():
  3. def __init__(self, screen, msg):
  4. """初始化按钮的属性"""
  5. self.screen = screen
  6. self.screen_rect = screen.get_rect()
  7. # 设置按钮的尺寸和其他属性
  8. self.width, self.height = 100, 50
  9. self.button_color = (0, 120, 215)
  10. self.text_color = (255, 255, 255)
  11. self.font = pygame.font.SysFont('SimHei', 25)
  12. # 创建按钮的rect对象,并使其居中
  13. self.rect = pygame.Rect(0, 0, self.width, self.height)
  14. # 创建按钮的rect对象,并设置按钮中心位置
  15. self.rect.centerx = 640 - self.width / 2 + 2
  16. self.rect.centery = 480 - self.height / 2 + 2
  17. # 按钮的标签只需创建一次
  18. self.prep_msg(msg)
  19. def prep_msg(self, msg):
  20. """将msg渲染为图像,并使其在按钮上居中"""
  21. self.msg_image = self.font.render(msg, True, self.text_color, self.button_color)
  22. self.msg_image_rect = self.msg_image.get_rect()
  23. self.msg_image_rect.center = self.rect.center
  24. def draw_button(self):
  25. # 绘制一个用颜色填充的按钮,再绘制文本
  26. self.screen.fill(self.button_color, self.rect)
  27. self.screen.blit(self.msg_image, self.msg_image_rect)

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

  1. import pygame.font
  2. # 线颜色
  3. line_color = (0, 0, 0)
  4. # 显示文字信息时使用的字体设置
  5. text_color = (0, 0, 0)
  6. def draw_bg(screen):
  7. # 背景文图案
  8. bgfont = pygame.font.SysFont('SimHei', 15)
  9. # 绘制横线
  10. pygame.draw.aaline(screen, line_color, (662, 30), (980, 30), 1)
  11. # 渲染为图片
  12. text_image = bgfont.render('识别信息:', True, text_color)
  13. # 获取文字图像位置
  14. text_rect = text_image.get_rect()
  15. # 设置文字图像中心点
  16. text_rect.left = 660
  17. text_rect.top = 370
  18. # 绘制内容
  19. screen.blit(text_image, text_rect)
  20. # 绘制文字(text-文字内容、xpos-x坐标、ypos-y坐标、fontSize-字体大小)
  21. def draw_text(screen, text, xpos, ypos, fontsize, tc=text_color):
  22. # 使用系统字体
  23. xtfont = pygame.font.SysFont('SimHei', fontsize)
  24. text_image = xtfont.render(text, True, tc)
  25. # 获取文字图像位置
  26. text_rect = text_image.get_rect()
  27. # 设置文字图像中心点
  28. text_rect.left = xpos
  29. text_rect.top = ypos
  30. # 绘制内容
  31. screen.blit(text_image, text_rect)

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

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

  1. from aip import AipOcr
  2. import os
  3. # 百度识别车牌
  4. # 申请地址 https://login.bce.baidu.com/
  5. filename = 'file/key.txt' # 记录申请的Key的文件位置
  6. if os.path.exists(filename): # 判断文件是否存在
  7. with open(filename, "r") as file: # 打开文件
  8. dictkey = eval(file.readlines()[0]) # 读取全部内容转换为字典
  9. # 以下获取的三个Key是进入百度AI开放平台的控制台的应用列表里创建应用得来的
  10. APP_ID = dictkey['APP_ID'] # 获取申请的APIID
  11. API_KEY = dictkey['API_KEY'] # 获取申请的APIKEY
  12. SECRET_KEY = dictkey['SECRET_KEY'] # 获取申请的SECRETKEY
  13. else:
  14. print("请先在file目录下创建key.txt,并且写入申请的Key!格式如下:"
  15. "\n{'APP_ID':'申请的APIID', 'API_KEY':'申请的APIKEY', 'SECRET_KEY':'申请的SECRETKEY'}")
  16. # 初始化AipOcr对象
  17. client = AipOcr(APP_ID, API_KEY, SECRET_KEY)
  18. # 读取文件
  19. def get_file_content(filePath):
  20. with open(filePath, 'rb') as fp:
  21. return fp.read()
  22. # 根据图片返回车牌号
  23. def getcn():
  24. # 读取图片
  25. image = get_file_content('images/test.jpg')
  26. # 调用车牌识别
  27. results = client.licensePlate(image)['words_result']['number']
  28. # 输出车牌号
  29. return results

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

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

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

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

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

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

  1. import sys
  2. import pygame
  3. import time
  4. import pandas as pd
  5. import ocrutil
  6. import timeutil
  7. # 事件
  8. def check_events(settings, recognition_button, ownerInfo_table, carInfo_table, history_table, path):
  9. """ 响应按键和鼠标事件 """
  10. for event in pygame.event.get():
  11. if event.type == pygame.QUIT:
  12. sys.exit()
  13. elif event.type == pygame.MOUSEBUTTONDOWN:
  14. mouse_x, mouse_y = pygame.mouse.get_pos()
  15. button_clicked = recognition_button.rect.collidepoint(mouse_x, mouse_y)
  16. if button_clicked:
  17. try:
  18. # 获取车牌
  19. carnumber = ocrutil.getcn()
  20. # 转换当前时间 2018-12-11 16:18
  21. localtime = time.strftime('%Y-%m-%d %H:%M', time.localtime())
  22. settings.carnumber = '车牌号码:' + carnumber
  23. # 判断进入车辆是否业主车辆
  24. # 获取业主车辆信息(只显示卡未过期)
  25. ownerInfo_table = ownerInfo_table[ownerInfo_table['validityDate'] > localtime]
  26. owner_carnumbers = ownerInfo_table[['carnumber', 'validityDate']].values
  27. carnumbers = ownerInfo_table['carnumber'].values
  28. # 获取车辆表信息
  29. carInfo_carnumbers = carInfo_table[['carnumber', 'inDate', 'isOwner', 'validityDate']].values
  30. cars = carInfo_table['carnumber'].values
  31. # 增加车辆信息
  32. append_carInfo = {
  33. 'carnumber': carnumber
  34. }
  35. # 增加历史信息
  36. append_history = {
  37. 'carnumber': carnumber
  38. }
  39. carInfo_length = len(carInfo_carnumbers)
  40. # 车辆表未有数据
  41. if carInfo_length == 0:
  42. print('未有车辆数据入场')
  43. in_park(owner_carnumbers, carnumbers, carInfo_table, append_carInfo, carnumber, localtime, settings, path)
  44. # 车辆表有数据
  45. else:
  46. if carnumber in cars:
  47. # 出停车场
  48. i = 0
  49. for carInfo_carnumber in carInfo_carnumbers:
  50. if carnumber == carInfo_carnumber[0]:
  51. if carInfo_carnumber[2] == 1:
  52. if timeutil.time_cmp(carInfo_carnumber[3], localtime):
  53. print('业主车,自动抬杠')
  54. msgMessage = '业主车,可出停车场'
  55. parkPrice = '业主卡'
  56. else:
  57. print('业主车,但卡已过期,收费抬杠')
  58. # 比较卡有效期时间
  59. price = timeutil.priceCalc(carInfo_carnumber[3], localtime)
  60. msgMessage = '停车费用:' + str(5 * int(price)) + '(提醒业主,卡已到期)'
  61. parkPrice = 5 * int(price)
  62. else:
  63. print('外来车,收费抬杠')
  64. # 比较入场时间
  65. price = timeutil.priceCalc(carInfo_carnumber[1], localtime)
  66. msgMessage = '停车费用:' + str(5 * price)
  67. parkPrice = 5 * int(price)
  68. print(i)
  69. carInfo_table = carInfo_table.drop([i])
  70. # 增加数据到历史表
  71. append_history['inDate'] = carInfo_carnumber[1]
  72. append_history['outData'] = localtime
  73. append_history['price'] = parkPrice
  74. append_history['isOwner'] = carInfo_carnumber[2]
  75. append_history['validityDate'] = carInfo_carnumber[3]
  76. history_table = history_table.append(append_history, ignore_index=True)
  77. settings.comeInTime = '出场时间:' + localtime
  78. settings.message = msgMessage
  79. # 更新车辆表和历史表
  80. pd.DataFrame(carInfo_table).to_excel(path + '停车场车辆表' + '.xlsx', sheet_name='data',
  81. index=False, header=True)
  82. pd.DataFrame(history_table).to_excel(path + '停车场历史表' + '.xlsx', sheet_name='data',
  83. index=False, header=True)
  84. break
  85. i += 1
  86. else:
  87. # 入停车场
  88. print('有车辆表数据入场')
  89. if carInfo_length < settings.total:
  90. in_park(owner_carnumbers, carnumbers, carInfo_table, append_carInfo, carnumber, localtime, settings, path)
  91. else:
  92. print('停车场已满')
  93. settings.comeInTime = '进场时间:' + localtime
  94. settings.message = '停车场已满,无法进入'
  95. except Exception as e:
  96. print("错误原因:", e)
  97. continue
  98. pass
  99. # 车辆入停车场
  100. def in_park(owner_carnumbers, carnumbers, carInfo_table, append_carInfo, carnumber, localtime, settings, path):
  101. if carnumber in carnumbers:
  102. for owner_carnumber in owner_carnumbers:
  103. if carnumber == owner_carnumber[0]:
  104. print('业主车,自动抬杠')
  105. msgMessage = '提示信息:业主车,可入停车场'
  106. append_carInfo['isOwner'] = 1
  107. append_carInfo['validityDate'] = owner_carnumber[1]
  108. # 退出循环
  109. break
  110. else:
  111. print('外来车,识别抬杠')
  112. msgMessage = '提示信息:外来车,可入停车场'
  113. append_carInfo['isOwner'] = 0
  114. append_carInfo['inDate'] = localtime
  115. settings.comeInTime = '进场时间:' + localtime
  116. settings.message = msgMessage
  117. # 添加信息到车辆表
  118. carInfo_table = carInfo_table.append(append_carInfo, ignore_index=True)
  119. # 更新车辆表
  120. pd.DataFrame(carInfo_table).to_excel(path + '停车场车辆表' + '.xlsx', sheet_name='data',
  121. index=False, header=True)

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

  1. import pygame
  2. import cv2
  3. import os
  4. import pandas as pd
  5. # 引入自定义模块
  6. from settings import Settings
  7. from button import Button
  8. import textboard
  9. import procedure_functions as pf
  10. def run_procedure():
  11. # 获取文件的路径
  12. cdir = os.getcwd()
  13. # 文件夹路径
  14. path = cdir + '/file/'
  15. # 读取路径
  16. if not os.path.exists(path + '停车场车辆表' + '.xlsx'):
  17. # 车牌号 进入时间 离开时间 价格 是否业主
  18. carnfile = pd.DataFrame(columns=['carnumber', 'inDate', 'outData', 'price', 'isOwner', 'validityDate'])
  19. # 生成xlsx文件
  20. carnfile.to_excel(path + '停车场车辆表' + '.xlsx', sheet_name='data')
  21. carnfile.to_excel(path + '停车场历史表' + '.xlsx', sheet_name='data')
  22. settings = Settings()
  23. # 初始化并创建一个屏幕对象
  24. pygame.init()
  25. pygame.display.set_caption('智能小区车牌识别系统')
  26. ic_launcher = pygame.image.load('images/icon_launcher.png')
  27. pygame.display.set_icon(ic_launcher)
  28. screen = pygame.display.set_mode((settings.screen_width, settings.screen_height))
  29. try:
  30. # cam = cv2.VideoCapture(0) # 开启摄像头
  31. cam = cv2.VideoCapture('file/test.mp4')
  32. except:
  33. print('请连接摄像头')
  34. # 循环帧率设置
  35. clock = pygame.time.Clock()
  36. running = True
  37. # 开始主循环
  38. while running:
  39. screen.fill(settings.bg_color)
  40. # 从摄像头读取图片
  41. sucess, img = cam.read()
  42. # 保存图片,并退出。
  43. if sucess:
  44. cv2.imwrite('images/test.jpg', img)
  45. else:
  46. # 识别不到图片或者设备停止,则退出系统
  47. running = False
  48. # 加载图像
  49. image = pygame.image.load('images/test.jpg')
  50. # 设置图片大小
  51. image = pygame.transform.scale(image, (640, 480))
  52. # 绘制视频画面
  53. screen.blit(image, (2, 2))
  54. # 创建识别按钮
  55. recognition_button = Button(screen, '识别')
  56. recognition_button.draw_button()
  57. # 读取文件内容
  58. ownerInfo_table = pd.read_excel(path + '住户车辆表.xlsx', sheet_name='data')
  59. carInfo_table = pd.read_excel(path + '停车场车辆表.xlsx', sheet_name='data')
  60. history_table = pd.read_excel(path + '停车场历史表.xlsx', sheet_name='data')
  61. inNumber = len(carInfo_table['carnumber'].values)
  62. # 绘制背景
  63. textboard.draw_bg(screen)
  64. # 绘制信息标题
  65. textboard.draw_text(screen, '共有车位:' + str(settings.total) + ' 剩余车位:' + str(settings.total - inNumber), 680, 0, 20)
  66. # 绘制信息表头
  67. textboard.draw_text(screen, ' 车牌号 进入时间', 700, 40, 15)
  68. # 绘制停车场车辆前十条信息
  69. carInfos = carInfo_table.sort_values(by='inDate', ascending=False)
  70. i = 0
  71. for carInfo in carInfos.values:
  72. if i >= 10:
  73. break
  74. i += 1
  75. textboard.draw_text(screen, str(carInfo[1])+' '+str(carInfo[2]), 700, 40 + i * 30, 15)
  76. # 绘制识别信息
  77. textboard.draw_text(screen, settings.carnumber, 660, 400, 15, settings.ocr_color)
  78. textboard.draw_text(screen, settings.comeInTime, 660, 422, 15, settings.ocr_color)
  79. textboard.draw_text(screen, settings.message, 660, 442, 15, settings.ocr_color)
  80. """ 响应鼠标事件 """
  81. pf.check_events(settings, recognition_button, ownerInfo_table, carInfo_table, history_table, path)
  82. pygame.display.flip()
  83. # 控制游戏最大帧率为 60
  84. clock.tick(60)
  85. # 关闭摄像头
  86. cam.release()
  87. run_procedure()

 

                                                                             扫描公众号,了解更多实例分享

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/708903
推荐阅读
相关标签
  

闽ICP备14008679号