Spaces:
Build error
Build error
| from flask import Flask, render_template, request, jsonify | |
| import os | |
| os.environ["CUDA_VISIBLE_DEVICES"] = "-1" | |
| import PyPDF2 | |
| from keras.models import load_model | |
| from PIL import Image, ImageOps | |
| import numpy as np | |
| import pandas as pd | |
| from inference_sdk import InferenceHTTPClient | |
| import cv2 | |
| import base64 | |
| import io | |
| from flask import send_file | |
| from reportlab.pdfgen import canvas | |
| from io import BytesIO | |
| EXCEL_FILE = "Book2.xlsx" | |
| # Initialize the Roboflow clients for different models | |
| CLIENTS = { | |
| 'classroom': InferenceHTTPClient( | |
| api_url="https://detect.roboflow.com", | |
| api_key="bNLTnCBq5hIm7R0O3hU4" | |
| ), | |
| 'chemical_lab': InferenceHTTPClient( | |
| api_url="https://detect.roboflow.com", | |
| api_key="bNLTnCBq5hIm7R0O3hU4" | |
| ), | |
| 'mechanical_workshop': InferenceHTTPClient( | |
| api_url="https://detect.roboflow.com", | |
| api_key="bNLTnCBq5hIm7R0O3hU4" | |
| ), | |
| 'computer_lab': InferenceHTTPClient( | |
| api_url="https://detect.roboflow.com", | |
| api_key="bNLTnCBq5hIm7R0O3hU4" | |
| ), | |
| 'cctv' :InferenceHTTPClient( | |
| api_url="https://detect.roboflow.com", | |
| api_key="bNLTnCBq5hIm7R0O3hU4" | |
| ), | |
| 'notice_board' :InferenceHTTPClient( | |
| api_url="https://detect.roboflow.com", | |
| api_key="bNLTnCBq5hIm7R0O3hU4" | |
| ), | |
| 'bench': InferenceHTTPClient( | |
| api_url="https://detect.roboflow.com", | |
| api_key="IkQtIl5NGRTc0llwyIMo" | |
| ) | |
| } | |
| # Model IDs for each environment | |
| MODEL_IDS = { | |
| 'classroom': "sih-object-detection/1", | |
| 'chemical_lab': "chem-dz924/1", | |
| 'mechanical_workshop': "mech-npugl/1", | |
| 'computer_lab': "sih-object-detection/1", | |
| 'cctv' : "bench-bcvxh/2", | |
| 'notice_board' : "cctv-cofid/2", | |
| 'bench' : "bench-bcvxh/2", | |
| } | |
| app = Flask(__name__) | |
| app.secret_key = 'super_secret_key' | |
| # Configuration | |
| app.config['UPLOAD_FOLDER'] = os.path.abspath('uploads/') | |
| os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True) | |
| FACILITIES = [ | |
| # Essential Academic and Safety Facilities | |
| "Classroom model", | |
| "Library model", | |
| "Computer lab model", | |
| "elearning model", | |
| "Drawing Halls model", | |
| "Fire extinguisher model", | |
| # Faculty and Administrative Needs | |
| "Faculty cabin model", | |
| "Server Room model", | |
| "TPO model", | |
| # Recreational and Co-curricular Support | |
| "Ground model", | |
| "Sports equipment model", | |
| "Workshop model", | |
| "Seminar hall model", | |
| "Conference Halls model", | |
| # Comfort and Utility Facilities | |
| "Canteen model", | |
| "Medical Room Model", | |
| "Parking model", | |
| # Backup and Miscellaneous | |
| "Generator model", | |
| "Audi model", | |
| ] | |
| # Mapping for PDFs (names might differ from model names) | |
| PDF_NAMES = { | |
| "Audi model": "Audi.pdf", | |
| "Canteen model": "Canteen.pdf", | |
| "Classroom model": "Classroom.pdf", | |
| "Computer lab model": "Computer Lab.pdf", | |
| "Conference Halls model": "Conference Hall.pdf", | |
| "Drawing Halls model": "Drawing Halls.pdf", | |
| "Faculty cabin model": "Faculty Cabin.pdf", | |
| "Fire extinguisher model": "Fire Extinguishers.pdf", | |
| "Generator model": "Generator.pdf", | |
| "Ground model": "Grounds.pdf", | |
| "Library model": "Library.pdf", | |
| "Medical Room Model": "Medical Room.pdf", | |
| "Parking model": "Parking.pdf", | |
| "Restroom Model": "Restroom.pdf", | |
| "Seminar hall model": "Seminar Hall.pdf", | |
| "Server Room model": "Server Room.pdf", | |
| "Sports equipment model": "Sports Equipment.pdf", | |
| "TPO model": "TPO (Training and Placement Office).pdf", | |
| "Workshop model": "Workshop.pdf", | |
| "elearning model": "elearning.pdf", | |
| } | |
| # Paths | |
| MODEL_PATHS = { | |
| facility: { | |
| "model": f"MODELS/{facility}/keras_model.h5", | |
| "labels": f"MODELS/{facility}/labels.txt", | |
| } | |
| for facility in FACILITIES | |
| } | |
| PDF_PATHS = { | |
| facility: f"pdfs/{PDF_NAMES[facility]}" | |
| for facility in FACILITIES | |
| } | |
| # Routes | |
| def index(): | |
| # Extract questions from PDFs for each facility | |
| questions = {facility: extract_questions(PDF_PATHS.get(facility, "")) for facility in FACILITIES} | |
| return render_template('index.html', facilities=FACILITIES, questions=questions) | |
| def calculate(): | |
| data = request.json | |
| num_students = int(data.get('num_students', 0)) | |
| num_divisions = int(data.get('num_divisions', 0)) | |
| num_courses = int(data.get('num_courses', 0)) | |
| course_duration = int(data.get('course_duration', 0)) | |
| calculated_facilities = calculate_required_facilities(num_students, num_divisions, num_courses, course_duration) | |
| return jsonify(calculated_facilities) | |
| def upload(facility): | |
| facility = facility.strip() | |
| # Check if facility exists in MODEL_PATHS | |
| normalized_facility = next( | |
| (key for key in MODEL_PATHS if key.lower() == facility.lower()), None | |
| ) | |
| if not normalized_facility: | |
| return jsonify({"error": f"Facility '{facility}' not found in MODEL_PATHS"}), 400 | |
| if 'images' not in request.files: | |
| return jsonify({"error": "No files uploaded"}), 400 | |
| files = request.files.getlist('images') | |
| if not files: | |
| return jsonify({"error": "No files selected"}), 400 | |
| results = [] | |
| for file in files: | |
| try: | |
| filepath = os.path.join(app.config['UPLOAD_FOLDER'], file.filename) | |
| file.save(filepath) | |
| # Perform verification using the model | |
| model_path = MODEL_PATHS[normalized_facility]["model"] | |
| labels_path = MODEL_PATHS[normalized_facility]["labels"] | |
| result = verify_image(filepath, model_path, labels_path) | |
| result["file_name"] = file.filename | |
| result["facility"] = normalized_facility | |
| # Log to Excel if verified | |
| if result["confidence"] >= 0.8: | |
| log_to_excel(result) | |
| results.append(result) | |
| except Exception as e: | |
| print(f"Error during file upload: {e}") | |
| results.append({"error": str(e), "file": file.filename}) | |
| return jsonify(results) | |
| def log_to_excel(data): | |
| """ | |
| Logs verified image data to an Excel file. | |
| :param data: Dictionary containing facility, file name, label, and confidence score. | |
| """ | |
| # Prepare a DataFrame row | |
| row = { | |
| "Facility": data["facility"], | |
| "Name of Image": data["file_name"], | |
| "Class of Prediction": data["label"], | |
| "Confidence Score": data["confidence"] | |
| } | |
| # Convert row to DataFrame | |
| df_row = pd.DataFrame([row]) | |
| # If the file exists, append; otherwise, create a new file | |
| if os.path.exists(EXCEL_FILE): | |
| df_existing = pd.read_excel(EXCEL_FILE) | |
| df_updated = pd.concat([df_existing, df_row], ignore_index=True) | |
| df_updated.to_excel(EXCEL_FILE, index=False) | |
| else: | |
| df_row.to_excel(EXCEL_FILE, index=False) | |
| def submit_answers(): | |
| data = request.json | |
| # Process submitted answers (if needed, save or process them) | |
| return jsonify({"message": "Answers submitted successfully!"}) | |
| # Utility Functions | |
| def calculate_required_facilities(num_students, num_divisions, num_courses, course_duration): | |
| """ | |
| Calculate required facilities based on student population and institutional parameters. | |
| Args: | |
| - num_students: Total number of students | |
| - num_divisions: Number of student divisions | |
| - num_courses: Number of courses | |
| - course_duration: Duration of courses | |
| Returns: | |
| - Dictionary of required facilities with their quantities | |
| """ | |
| results = { | |
| # Classroom Calculation: Based on divisions, course duration, and utilization | |
| "Classroom model": max(1, int(num_divisions * course_duration * 0.5)), | |
| # Computer Lab Calculation: Considering courses, student density | |
| "Computer lab model": max(1, int((num_courses * course_duration + num_students / 400) * 0.75)), | |
| # Facilities typically singular in a college | |
| "Audi model": 1, # One main auditorium | |
| "TPO model": 1, # One Training and Placement Office | |
| "Medical Room Model": 1, # One central medical room | |
| "Server Room model": 1, # One central server room | |
| "Conference Halls model": 1, # One main conference hall | |
| "Seminar hall model": 1, # One primary seminar hall | |
| # Facilities with more variable allocation | |
| "Workshop model": max(1, num_students // 600), | |
| "Sports equipment model": 1, | |
| # Canteen Calculation: Scaled with student population | |
| "Canteen model": 1, | |
| # Additional facilities with minimum allocation | |
| "Drawing Halls model": 1, | |
| "Faculty cabin model": max(1, num_students//20), | |
| "Fire extinguisher model": max(1, num_divisions)+20, | |
| "Generator model": 1, | |
| "Ground model": 1, | |
| "Library model": 1, # Typically one main library | |
| "Parking model": 1, | |
| "Restroom Model": max(2, num_students // 500), | |
| } | |
| return results | |
| def verify_image(image_path, model_path, labels_path): | |
| try: | |
| print(f"Loading model from: {model_path}") | |
| model = load_model(model_path) | |
| except Exception as e: | |
| print(f"Error loading model: {e}") | |
| raise | |
| try: | |
| with open(labels_path, 'r') as f: | |
| labels = [line.strip() for line in f.readlines()] | |
| print(f"Labels loaded: {labels}") | |
| except Exception as e: | |
| print(f"Error loading labels: {e}") | |
| raise | |
| try: | |
| image = Image.open(image_path).convert('RGB') | |
| image = ImageOps.fit(image, (224, 224), Image.Resampling.LANCZOS) | |
| image_array = np.asarray(image) | |
| normalized_image_array = (image_array.astype(np.float32) / 127.5) - 1 | |
| data = np.expand_dims(normalized_image_array, axis=0) | |
| print("Running prediction...") | |
| prediction = model.predict(data) | |
| index = np.argmax(prediction) | |
| confidence_score = prediction[0][index] | |
| # Convert numpy.float32 to Python float for JSON serialization | |
| return {"label": labels[index], "confidence": float(confidence_score)} | |
| except Exception as e: | |
| print(f"Error during prediction: {e}") | |
| raise | |
| def extract_questions(pdf_path): | |
| """Extracts questions from a given PDF file.""" | |
| if not os.path.exists(pdf_path): | |
| return [] | |
| questions = [] | |
| try: | |
| with open(pdf_path, 'rb') as pdf_file: | |
| reader = PyPDF2.PdfReader(pdf_file) | |
| for page in reader.pages: | |
| text = page.extract_text() | |
| # Extract lines ending with "?" (assuming questions end with "?") | |
| questions.extend([line.strip() for line in text.split('\n') if line.strip().endswith('?')]) | |
| except Exception as e: | |
| print(f"Error extracting questions from {pdf_path}: {e}") | |
| return questions | |
| def process_single_image(file, environment): | |
| """Helper function to process a single image""" | |
| if file.filename == '': | |
| raise ValueError('No selected file') | |
| # Validate file type | |
| allowed_extensions = {'png', 'jpg', 'jpeg'} | |
| if not file.filename.lower().endswith(tuple(allowed_extensions)): | |
| raise ValueError('Invalid file type. Please upload a PNG or JPEG image.') | |
| # Read and process image | |
| image_bytes = file.read() | |
| img = Image.open(io.BytesIO(image_bytes)) | |
| if img.mode == 'RGBA': | |
| img = img.convert('RGB') | |
| # Save image temporarily | |
| temp_path = f"temp_image_{environment}.jpg" | |
| img.save(temp_path) | |
| # Keep a copy for drawing | |
| img_draw = np.array(img) | |
| img_draw = cv2.cvtColor(img_draw, cv2.COLOR_RGB2BGR) | |
| # Perform detection | |
| results = CLIENTS[environment].infer(temp_path, model_id=MODEL_IDS[environment]) | |
| detections = [] | |
| # Process results | |
| for i, prediction in enumerate(results.get('predictions', [])): | |
| x1 = int(prediction['x'] - prediction['width'] / 2) | |
| y1 = int(prediction['y'] - prediction['height'] / 2) | |
| x2 = int(prediction['x'] + prediction['width'] / 2) | |
| y2 = int(prediction['y'] + prediction['height'] / 2) | |
| class_name = prediction['class'] | |
| confidence = prediction['confidence'] | |
| detections.append({ | |
| 'bbox': [x1, y1, x2, y2], | |
| 'class': class_name, | |
| 'confidence': round(confidence, 2), | |
| 'id': f'{environment}-detection-{i}' | |
| }) | |
| # Draw bounding box | |
| cv2.rectangle(img_draw, (x1, y1), (x2, y2), (0, 255, 0), 1) | |
| cv2.putText(img_draw, f'{class_name} {confidence:.2f}', (x1, y1 - 10), | |
| cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 1) | |
| # Clean up temporary file | |
| if os.path.exists(temp_path): | |
| os.remove(temp_path) | |
| # Convert the image to base64 | |
| _, buffer = cv2.imencode('.jpg', img_draw) | |
| img_str = base64.b64encode(buffer).decode() | |
| return { | |
| 'image': f'data:image/jpeg;base64,{img_str}', | |
| 'detections': detections | |
| } | |
| def detect(): | |
| try: | |
| required_environments = ['classroom', 'chemical_lab', 'mechanical_workshop', | |
| 'computer_lab', 'cctv', 'notice_board', 'bench'] | |
| results = {} | |
| # Check if all required images are provided | |
| for env in required_environments: | |
| if f'image_{env}' not in request.files: | |
| return jsonify({ | |
| 'success': False, | |
| 'error': f'No image file provided for {env}' | |
| }), 400 | |
| # Process each image | |
| for env in required_environments: | |
| try: | |
| file = request.files[f'image_{env}'] | |
| results[env] = process_single_image(file, env) | |
| except Exception as e: | |
| return jsonify({ | |
| 'success': False, | |
| 'error': f'Error processing {env} image: {str(e)}' | |
| }), 400 | |
| return jsonify({ | |
| 'success': True, | |
| 'results': results | |
| }) | |
| except Exception as e: | |
| app.logger.error(f"Error in detect route: {str(e)}") | |
| return jsonify({ | |
| 'success': False, | |
| 'error': f'Server error: {str(e)}' | |
| }), 500 | |
| def download_report(): | |
| # Generate PDF report | |
| buffer = BytesIO() | |
| pdf = canvas.Canvas(buffer) | |
| # Write content to PDF (example content) | |
| pdf.drawString(100, 800, "Facility Management System Report") | |
| pdf.drawString(100, 780, "This is an auto-generated report.") | |
| # Sample table (adjust as per your needs) | |
| y = 750 | |
| for facility in FACILITIES: | |
| pdf.drawString(100, y, f"Facility: {facility}") | |
| y -= 20 # Move to next line | |
| pdf.save() | |
| buffer.seek(0) | |
| return send_file(buffer, as_attachment=True, download_name="facility_report.pdf", mimetype='application/pdf') | |
| def download_excel(): | |
| if os.path.exists(EXCEL_FILE): | |
| return send_file(EXCEL_FILE, as_attachment=True, download_name="facility_data.xlsx", | |
| mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') | |
| else: | |
| return jsonify({"error": "Excel file not found"}), 404 | |
| if __name__ == '__main__': | |
| app.run(debug=True) | |