基于Flask的智能停车场管理系统开发实践

发布于:2025-07-29 ⋅ 阅读:(20) ⋅ 点赞:(0)

在现代城市中,停车难已成为一个普遍问题。为了解决这一问题,我开发了一个基于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应用方面的优势,以及合理架构设计在系统维护中的重要性。希望这个项目能为其他开发者提供有价值的参考。


网站公告

今日签到

点亮在社区的每一天
去签到