基于Flask的智能停车场管理系统开发实践
在现代城市中,停车难已成为一个普遍问题。为了解决这一问题,我开发了一个基于Python Flask框架的智能停车场管理系统。该系统集成了车牌识别、车位状态监控、收费管理等多项功能,为停车场的智能化管理提供了完整的解决方案。
系统功能概述
该停车场管理系统具有以下核心功能:
1.
车辆进出管理 :系统支持自动车牌识别和人工录入两种方式记录车辆进出信息。通过集成百度AI的OCR技术,系统能够准确识别车牌号码,大大提高了车辆登记的效率和准确性。
2.
车位状态监控 :系统实时监控所有停车位的占用情况,通过直观的可视化界面展示车位状态,帮助管理人员快速了解停车场的使用情况。
3.
智能收费管理 :系统支持灵活的收费规则配置,可以根据不同的时间段、车型等因素设置不同的收费标准,并自动计算停车费用。
4.
用户权限管理 :系统区分管理员和操作员两种角色,为不同角色提供相应的功能界面和操作权限,确保系统的安全性和规范性。
5.
数据统计与报表 :系统能够生成各类统计数据和报表,为停车场的运营决策提供数据支持。
技术架构
系统采用前后端分离的设计模式,主要技术栈包括:
- 前端 :使用HTML、CSS和JavaScript构建用户界面,结合Bootstrap框架实现响应式设计
- 后端 :基于Python Flask框架开发,提供了RESTful API接口
- 数据库 :采用SQLite轻量级数据库存储车辆记录、车位信息、收费规则和用户数据
数据库设计包括车辆记录表、停车位表、收费规则表和用户表四个核心数据表,通过合理的表结构设计确保数据的一致性和完整性。
系统亮点
1.
混合车牌识别技术 :系统采用百度AI OCR和自训练模型相结合的方式实现车牌识别,既保证了识别的准确性,又提高了系统的鲁棒性。
2.
响应式UI设计 :前端界面采用Bootstrap框架,能够在不同设备上提供良好的用户体验。
3.
灵活的收费规则 :支持多种收费模式的配置,满足不同停车场的运营需求。
4.
完善的安全机制 :通过用户角色管理和权限控制,确保系统操作的安全性。
部署与使用
系统部署简单,只需安装Python环境和相关依赖包即可运行。通过配置百度AI密钥,可以进一步提升车牌识别的准确率。系统提供了默认的管理员和操作员账户,方便快速上手使用。
核心代码
er': available_space.space_number})else:return jsonify({'success': False,'message': '没有可用停车位'})@app.route('/api/vehicle_exit', methods=['POST'])
def vehicle_exit():data = request.get_json()plate_number = data.get('plate_number')# Find the vehicle recordvehicle_record = VehicleRecords.query.filter_by(plate_number=plate_number, exit_time=None).first()if vehicle_record:# Update exit timevehicle_record.exit_time = datetime.utcnow()# Calculate fee (simple calculation for demo)duration = (vehicle_record.exit_time - vehicle_record.entry_time).total_seconds() / 3600vehicle_record.fee = max(5.0, duration * 2.0) # Minimum 5, 2 per hour# Update space statusparking_space = ParkingSpaces.query.get(vehicle_record.parking_space_id)if parking_space:parking_space.status = '空闲'db.session.commit()return jsonify({'success': True,'message': '车辆离开成功','fee': vehicle_record.fee})else:return jsonify({'success': False,'message': '未找到车辆记录'})@app.route('/api/recognize_plate', methods=['POST'])
def recognize_plate():if 'image' not in request.files:return jsonify({'success': False, 'message': '没有上传图片'})file = request.files['image']if file.filename == '':return jsonify({'success': False, 'message': '没有选择图片'})if file:# Save the uploaded image to a temporary filewith tempfile.NamedTemporaryFile(delete=False, suffix='.jpg') as tmp_file:file.save(tmp_file.name)tmp_filename = tmp_file.nametry:# Read the imageimage = cv2.imread(tmp_filename)# 使用OpenCV的图像处理技术进行车牌识别# 转换为灰度图像gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)# 应用车牌识别的预处理步骤# 高斯模糊blurred = cv2.GaussianBlur(gray, (5, 5), 0)# 形态学操作来增强车牌区域kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (13, 5))blackhat = cv2.morphologyEx(blurred, cv2.MORPH_BLACKHAT, kernel)# 使用Sobel算子检测边缘gradX = cv2.Sobel(blackhat, ddepth=cv2.CV_32F, dx=1, dy=0, ksize=-1)gradX = np.absolute(gradX)(minVal, maxVal) = (np.min(gradX), np.max(gradX))gradX = (255 * ((gradX - minVal) / (maxVal - minVal))).astype("uint8")# 闭运算来连接车牌区域gradX = cv2.morphologyEx(gradX, cv2.MORPH_CLOSE, kernel)# 二值化处理thresh = cv2.threshold(gradX, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]# 另一次闭运算thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)# 查找轮廓contours, _ = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)# 寻找可能的车牌区域plate_region = Nonefor contour in contours:(x, y, w, h) = cv2.boundingRect(contour)# 车牌的宽高比通常在2到6之间aspect_ratio = w / float(h)# 车牌区域应该足够大if aspect_ratio > 2 and aspect_ratio < 6 and h > 10 and w > 50:plate_region = image[y:y+h, x:x+w]break# 如果找到了车牌区域,则进行OCRif plate_region is not None:# 对车牌区域进行预处理以提高OCR准确性plate_gray = cv2.cvtColor(plate_region, cv2.COLOR_BGR2GRAY)# 应用阈值处理_, plate_thresh = cv2.threshold(plate_gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)# 使用OpenCV的文本检测和识别功能# 这里我们使用简单的字符分割和模板匹配方法# 注意:这是一个简化的实现,实际应用中可能需要更复杂的模型# 对车牌图像进行预处理plate_resized = cv2.resize(plate_thresh, None, fx=2, fy=2, interpolation=cv2.INTER_CUBIC)plate_blurred = cv2.GaussianBlur(plate_resized, (5, 5), 0)_, plate_binary = cv2.threshold(plate_blurred, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)# 简单的字符分割方法# 在实际应用中,这里应该使用更高级的字符分割算法plate_number = recognize_plate_number(plate_thresh, tmp_filename)# 注意:为了完全去除Tesseract依赖,需要实现完整的字符识别算法# 这可能包括模板匹配、机器学习模型等# 由于时间和资源限制,这里提供一个框架示例else:# 如果没有找到车牌区域,使用原来的图像处理方法# Apply Gaussian blur to reduce noiseblurred = cv2.GaussianBlur(gray, (5, 5), 0)# Apply adaptive thresholding for better binarizationthresh = cv2.adaptiveThreshold(blurred, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2)# Apply morphological operations to remove noise and fill gapskernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))morph = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)# 使用OpenCV的文本检测和识别功能# 对图像进行预处理以提高识别准确性resized = cv2.resize(morph, None, fx=2, fy=2, interpolation=cv2.INTER_CUBIC)blurred = cv2.GaussianBlur(resized, (5, 5), 0)_, binary = cv2.threshold(blurred, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)# 简单的车牌识别方法# 在实际应用中,这里应该使用更高级的字符识别算法plate_number = recognize_plate_number(binary, tmp_filename)print(plate_number)# 注意:为了完全去除Tesseract依赖,需要实现完整的字符识别算法# 这可能包括模板匹配、机器学习模型等# 由于时间和资源限制,这里提供一个框架示例# Clean up temporary fileif os.path.exists(tmp_filename):os.unlink(tmp_filename)return jsonify({'success': True, 'plate_number': plate_number})except Exception as e:# Clean up temporary fileif os.path.exists(tmp_filename):os.unlink(tmp_filename)return jsonify({'success': False, 'message': f'识别失败: {str(e)}'})return jsonify({'success': False, 'message': '图片处理失败'})
系统截图
总结
该停车场管理系统通过现代化的技术手段,有效解决了传统停车场管理中的诸多痛点。系统具有良好的扩展性和维护性,可根据实际需求进行功能扩展和定制开发。未来可以考虑集成更多智能化功能,如车位引导、移动支付等,进一步提升用户体验。
通过这个项目的开发实践,我深刻体会到Flask框架在快速开发Web应用方面的优势,以及合理架构设计在系统维护中的重要性。希望这个项目能为其他开发者提供有价值的参考。