pranit144/Institute_Inspection_image_processing
0
1from flask import Flask, render_template, request, jsonify
2import os
3os.environ["CUDA_VISIBLE_DEVICES"] = "-1"
4import PyPDF2
5from keras.models import load_model
6from PIL import Image, ImageOps
7import numpy as np
8import pandas as pd
9from inference_sdk import InferenceHTTPClient
10import cv2
11import base64
12import io
13from flask import send_file
14from reportlab.pdfgen import canvas
15from io import BytesIO
16
17EXCEL_FILE = "Book2.xlsx"
18
19# Initialize the Roboflow clients for different models
20CLIENTS = {
21 'classroom': InferenceHTTPClient(
22 api_url="https://detect.roboflow.com",
23 api_key="bNLTnCBq5hIm7R0O3hU4"
24 ),
25 'chemical_lab': InferenceHTTPClient(
26 api_url="https://detect.roboflow.com",
27 api_key="bNLTnCBq5hIm7R0O3hU4"
28 ),
29 'mechanical_workshop': InferenceHTTPClient(
30 api_url="https://detect.roboflow.com",
31 api_key="bNLTnCBq5hIm7R0O3hU4"
32 ),
33 'computer_lab': InferenceHTTPClient(
34 api_url="https://detect.roboflow.com",
35 api_key="bNLTnCBq5hIm7R0O3hU4"
36 ),
37 'cctv' :InferenceHTTPClient(
38 api_url="https://detect.roboflow.com",
39 api_key="bNLTnCBq5hIm7R0O3hU4"
40),
41 'notice_board' :InferenceHTTPClient(
42 api_url="https://detect.roboflow.com",
43 api_key="bNLTnCBq5hIm7R0O3hU4"
44 ),
45 'bench': InferenceHTTPClient(
46 api_url="https://detect.roboflow.com",
47 api_key="IkQtIl5NGRTc0llwyIMo"
48 )
49
50}
51# Model IDs for each environment
52MODEL_IDS = {
53 'classroom': "sih-object-detection/1",
54 'chemical_lab': "chem-dz924/1",
55 'mechanical_workshop': "mech-npugl/1",
56 'computer_lab': "sih-object-detection/1",
57 'cctv' : "bench-bcvxh/2",
58 'notice_board' : "cctv-cofid/2",
59 'bench' : "bench-bcvxh/2",
60}
61app = Flask(__name__)
62app.secret_key = 'super_secret_key'
63
64# Configuration
65app.config['UPLOAD_FOLDER'] = os.path.abspath('uploads/')
66os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True)
67
68FACILITIES = [
69 # Essential Academic and Safety Facilities
70 "Classroom model",
71 "Library model",
72 "Computer lab model",
73 "elearning model",
74
75 "Drawing Halls model",
76 "Fire extinguisher model",
77
78 # Faculty and Administrative Needs
79 "Faculty cabin model",
80 "Server Room model",
81 "TPO model",
82
83 # Recreational and Co-curricular Support
84 "Ground model",
85 "Sports equipment model",
86 "Workshop model",
87 "Seminar hall model",
88 "Conference Halls model",
89
90 # Comfort and Utility Facilities
91 "Canteen model",
92
93 "Medical Room Model",
94 "Parking model",
95
96 # Backup and Miscellaneous
97 "Generator model",
98 "Audi model",
99
100]
101
102
103# Mapping for PDFs (names might differ from model names)
104PDF_NAMES = {
105 "Audi model": "Audi.pdf",
106 "Canteen model": "Canteen.pdf",
107 "Classroom model": "Classroom.pdf",
108 "Computer lab model": "Computer Lab.pdf",
109 "Conference Halls model": "Conference Hall.pdf",
110 "Drawing Halls model": "Drawing Halls.pdf",
111 "Faculty cabin model": "Faculty Cabin.pdf",
112 "Fire extinguisher model": "Fire Extinguishers.pdf",
113 "Generator model": "Generator.pdf",
114 "Ground model": "Grounds.pdf",
115 "Library model": "Library.pdf",
116 "Medical Room Model": "Medical Room.pdf",
117 "Parking model": "Parking.pdf",
118 "Restroom Model": "Restroom.pdf",
119 "Seminar hall model": "Seminar Hall.pdf",
120 "Server Room model": "Server Room.pdf",
121 "Sports equipment model": "Sports Equipment.pdf",
122 "TPO model": "TPO (Training and Placement Office).pdf",
123 "Workshop model": "Workshop.pdf",
124 "elearning model": "elearning.pdf",
125}
126
127# Paths
128MODEL_PATHS = {
129 facility: {
130 "model": f"MODELS/{facility}/keras_model.h5",
131 "labels": f"MODELS/{facility}/labels.txt",
132 }
133 for facility in FACILITIES
134}
135
136PDF_PATHS = {
137 facility: f"pdfs/{PDF_NAMES[facility]}"
138 for facility in FACILITIES
139}
140
141# Routes
142@app.route('/')
143def index():
144 # Extract questions from PDFs for each facility
145 questions = {facility: extract_questions(PDF_PATHS.get(facility, "")) for facility in FACILITIES}
146 return render_template('index.html', facilities=FACILITIES, questions=questions)
147
148
149@app.route('/calculate', methods=['POST'])
150def calculate():
151 data = request.json
152 num_students = int(data.get('num_students', 0))
153 num_divisions = int(data.get('num_divisions', 0))
154 num_courses = int(data.get('num_courses', 0))
155 course_duration = int(data.get('course_duration', 0))
156
157 calculated_facilities = calculate_required_facilities(num_students, num_divisions, num_courses, course_duration)
158 return jsonify(calculated_facilities)
159
160
161
162
163@app.route('/upload/<facility>', methods=['POST'])
164def upload(facility):
165 facility = facility.strip()
166
167 # Check if facility exists in MODEL_PATHS
168 normalized_facility = next(
169 (key for key in MODEL_PATHS if key.lower() == facility.lower()), None
170 )
171 if not normalized_facility:
172 return jsonify({"error": f"Facility '{facility}' not found in MODEL_PATHS"}), 400
173
174 if 'images' not in request.files:
175 return jsonify({"error": "No files uploaded"}), 400
176
177 files = request.files.getlist('images')
178 if not files:
179 return jsonify({"error": "No files selected"}), 400
180
181 results = []
182 for file in files:
183 try:
184 filepath = os.path.join(app.config['UPLOAD_FOLDER'], file.filename)
185 file.save(filepath)
186
187 # Perform verification using the model
188 model_path = MODEL_PATHS[normalized_facility]["model"]
189 labels_path = MODEL_PATHS[normalized_facility]["labels"]
190
191 result = verify_image(filepath, model_path, labels_path)
192 result["file_name"] = file.filename
193 result["facility"] = normalized_facility
194
195 # Log to Excel if verified
196 if result["confidence"] >= 0.8:
197 log_to_excel(result)
198
199 results.append(result)
200
201 except Exception as e:
202 print(f"Error during file upload: {e}")
203 results.append({"error": str(e), "file": file.filename})
204
205 return jsonify(results)
206
207def log_to_excel(data):
208 """
209 Logs verified image data to an Excel file.
210 :param data: Dictionary containing facility, file name, label, and confidence score.
211 """
212 # Prepare a DataFrame row
213 row = {
214 "Facility": data["facility"],
215 "Name of Image": data["file_name"],
216 "Class of Prediction": data["label"],
217 "Confidence Score": data["confidence"]
218 }
219
220 # Convert row to DataFrame
221 df_row = pd.DataFrame([row])
222
223 # If the file exists, append; otherwise, create a new file
224 if os.path.exists(EXCEL_FILE):
225 df_existing = pd.read_excel(EXCEL_FILE)
226 df_updated = pd.concat([df_existing, df_row], ignore_index=True)
227 df_updated.to_excel(EXCEL_FILE, index=False)
228 else:
229 df_row.to_excel(EXCEL_FILE, index=False)
230
231
232
233@app.route('/submit_answers', methods=['POST'])
234def submit_answers():
235 data = request.json
236 # Process submitted answers (if needed, save or process them)
237 return jsonify({"message": "Answers submitted successfully!"})
238
239
240# Utility Functions
241def calculate_required_facilities(num_students, num_divisions, num_courses, course_duration):
242 """
243 Calculate required facilities based on student population and institutional parameters.
244
245 Args:
246 - num_students: Total number of students
247 - num_divisions: Number of student divisions
248 - num_courses: Number of courses
249 - course_duration: Duration of courses
250
251 Returns:
252 - Dictionary of required facilities with their quantities
253 """
254 results = {
255 # Classroom Calculation: Based on divisions, course duration, and utilization
256 "Classroom model": max(1, int(num_divisions * course_duration * 0.5)),
257 # Computer Lab Calculation: Considering courses, student density
258 "Computer lab model": max(1, int((num_courses * course_duration + num_students / 400) * 0.75)),
259 # Facilities typically singular in a college
260 "Audi model": 1, # One main auditorium
261 "TPO model": 1, # One Training and Placement Office
262 "Medical Room Model": 1, # One central medical room
263 "Server Room model": 1, # One central server room
264 "Conference Halls model": 1, # One main conference hall
265 "Seminar hall model": 1, # One primary seminar hall
266 # Facilities with more variable allocation
267 "Workshop model": max(1, num_students // 600),
268 "Sports equipment model": 1,
269 # Canteen Calculation: Scaled with student population
270 "Canteen model": 1,
271 # Additional facilities with minimum allocation
272 "Drawing Halls model": 1,
273 "Faculty cabin model": max(1, num_students//20),
274 "Fire extinguisher model": max(1, num_divisions)+20,
275 "Generator model": 1,
276 "Ground model": 1,
277 "Library model": 1, # Typically one main library
278 "Parking model": 1,
279 "Restroom Model": max(2, num_students // 500),
280 }
281
282 return results
283
284def verify_image(image_path, model_path, labels_path):
285 try:
286 print(f"Loading model from: {model_path}")
287 model = load_model(model_path)
288 except Exception as e:
289 print(f"Error loading model: {e}")
290 raise
291
292 try:
293 with open(labels_path, 'r') as f:
294 labels = [line.strip() for line in f.readlines()]
295 print(f"Labels loaded: {labels}")
296 except Exception as e:
297 print(f"Error loading labels: {e}")
298 raise
299
300 try:
301 image = Image.open(image_path).convert('RGB')
302 image = ImageOps.fit(image, (224, 224), Image.Resampling.LANCZOS)
303 image_array = np.asarray(image)
304 normalized_image_array = (image_array.astype(np.float32) / 127.5) - 1
305 data = np.expand_dims(normalized_image_array, axis=0)
306
307 print("Running prediction...")
308 prediction = model.predict(data)
309 index = np.argmax(prediction)
310 confidence_score = prediction[0][index]
311
312 # Convert numpy.float32 to Python float for JSON serialization
313 return {"label": labels[index], "confidence": float(confidence_score)}
314 except Exception as e:
315 print(f"Error during prediction: {e}")
316 raise
317
318
319def extract_questions(pdf_path):
320 """Extracts questions from a given PDF file."""
321 if not os.path.exists(pdf_path):
322 return []
323
324 questions = []
325 try:
326 with open(pdf_path, 'rb') as pdf_file:
327 reader = PyPDF2.PdfReader(pdf_file)
328 for page in reader.pages:
329 text = page.extract_text()
330 # Extract lines ending with "?" (assuming questions end with "?")
331 questions.extend([line.strip() for line in text.split('\n') if line.strip().endswith('?')])
332 except Exception as e:
333 print(f"Error extracting questions from {pdf_path}: {e}")
334
335 return questions
336
337
338def process_single_image(file, environment):
339 """Helper function to process a single image"""
340 if file.filename == '':
341 raise ValueError('No selected file')
342
343 # Validate file type
344 allowed_extensions = {'png', 'jpg', 'jpeg'}
345 if not file.filename.lower().endswith(tuple(allowed_extensions)):
346 raise ValueError('Invalid file type. Please upload a PNG or JPEG image.')
347
348 # Read and process image
349 image_bytes = file.read()
350 img = Image.open(io.BytesIO(image_bytes))
351 if img.mode == 'RGBA':
352 img = img.convert('RGB')
353
354 # Save image temporarily
355 temp_path = f"temp_image_{environment}.jpg"
356 img.save(temp_path)
357
358 # Keep a copy for drawing
359 img_draw = np.array(img)
360 img_draw = cv2.cvtColor(img_draw, cv2.COLOR_RGB2BGR)
361
362 # Perform detection
363 results = CLIENTS[environment].infer(temp_path, model_id=MODEL_IDS[environment])
364 detections = []
365
366 # Process results
367 for i, prediction in enumerate(results.get('predictions', [])):
368 x1 = int(prediction['x'] - prediction['width'] / 2)
369 y1 = int(prediction['y'] - prediction['height'] / 2)
370 x2 = int(prediction['x'] + prediction['width'] / 2)
371 y2 = int(prediction['y'] + prediction['height'] / 2)
372
373 class_name = prediction['class']
374 confidence = prediction['confidence']
375
376 detections.append({
377 'bbox': [x1, y1, x2, y2],
378 'class': class_name,
379 'confidence': round(confidence, 2),
380 'id': f'{environment}-detection-{i}'
381 })
382
383 # Draw bounding box
384 cv2.rectangle(img_draw, (x1, y1), (x2, y2), (0, 255, 0), 1)
385 cv2.putText(img_draw, f'{class_name} {confidence:.2f}', (x1, y1 - 10),
386 cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 1)
387
388 # Clean up temporary file
389 if os.path.exists(temp_path):
390 os.remove(temp_path)
391
392 # Convert the image to base64
393 _, buffer = cv2.imencode('.jpg', img_draw)
394 img_str = base64.b64encode(buffer).decode()
395
396 return {
397 'image': f'data:image/jpeg;base64,{img_str}',
398 'detections': detections
399 }
400
401
402@app.route('/detect', methods=['POST'])
403def detect():
404 try:
405 required_environments = ['classroom', 'chemical_lab', 'mechanical_workshop',
406 'computer_lab', 'cctv', 'notice_board', 'bench']
407 results = {}
408
409 # Check if all required images are provided
410 for env in required_environments:
411 if f'image_{env}' not in request.files:
412 return jsonify({
413 'success': False,
414 'error': f'No image file provided for {env}'
415 }), 400
416
417 # Process each image
418 for env in required_environments:
419 try:
420 file = request.files[f'image_{env}']
421 results[env] = process_single_image(file, env)
422 except Exception as e:
423 return jsonify({
424 'success': False,
425 'error': f'Error processing {env} image: {str(e)}'
426 }), 400
427
428 return jsonify({
429 'success': True,
430 'results': results
431 })
432
433 except Exception as e:
434 app.logger.error(f"Error in detect route: {str(e)}")
435 return jsonify({
436 'success': False,
437 'error': f'Server error: {str(e)}'
438 }), 500
439
440@app.route('/download_report', methods=['GET'])
441def download_report():
442 # Generate PDF report
443 buffer = BytesIO()
444 pdf = canvas.Canvas(buffer)
445
446 # Write content to PDF (example content)
447 pdf.drawString(100, 800, "Facility Management System Report")
448 pdf.drawString(100, 780, "This is an auto-generated report.")
449
450 # Sample table (adjust as per your needs)
451 y = 750
452 for facility in FACILITIES:
453 pdf.drawString(100, y, f"Facility: {facility}")
454 y -= 20 # Move to next line
455
456 pdf.save()
457 buffer.seek(0)
458
459 return send_file(buffer, as_attachment=True, download_name="facility_report.pdf", mimetype='application/pdf')
460
461
462@app.route('/download_excel', methods=['GET'])
463def download_excel():
464 if os.path.exists(EXCEL_FILE):
465 return send_file(EXCEL_FILE, as_attachment=True, download_name="facility_data.xlsx",
466 mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
467 else:
468 return jsonify({"error": "Excel file not found"}), 404
469
470
471if __name__ == '__main__':
472 app.run(debug=True)
473 