在现代城市中,停车难已成为一个普遍问题。为了解决这一问题,我开发了一个基于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 record
vehicle_record = VehicleRecords.query.filter_by(
plate_number=plate_number,
exit_time=None
).first()
if vehicle_record:
# Update exit time
vehicle_record.exit_time = datetime.utcnow()
# Calculate fee (simple calculation for demo)
duration = (vehicle_record.exit_time - vehicle_record.entry_time).total_seconds() / 3600
vehicle_record.fee = max(5.0, duration * 2.0) # Minimum 5, 2 per hour
# Update space status
parking_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 file
with tempfile.NamedTemporaryFile(delete=False, suffix='.jpg') as tmp_file:
file.save(tmp_file.name)
tmp_filename = tmp_file.name
try:
# Read the image
image = 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 = None
for 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
# 如果找到了车牌区域,则进行OCR
if 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 noise
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
# Apply adaptive thresholding for better binarization
thresh = cv2.adaptiveThreshold(blurred, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2)
# Apply morphological operations to remove noise and fill gaps
kernel = 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 file
if os.path.exists(tmp_filename):
os.unlink(tmp_filename)
return jsonify({'success': True, 'plate_number': plate_number})
except Exception as e:
# Clean up temporary file
if os.path.exists(tmp_filename):
os.unlink(tmp_filename)
return jsonify({'success': False, 'message': f'识别失败: {str(e)}'})
return jsonify({'success': False, 'message': '图片处理失败'})
系统截图
总结
该停车场管理系统通过现代化的技术手段,有效解决了传统停车场管理中的诸多痛点。系统具有良好的扩展性和维护性,可根据实际需求进行功能扩展和定制开发。未来可以考虑集成更多智能化功能,如车位引导、移动支付等,进一步提升用户体验。
通过这个项目的开发实践,我深刻体会到Flask框架在快速开发Web应用方面的优势,以及合理架构设计在系统维护中的重要性。希望这个项目能为其他开发者提供有价值的参考。