import gradio as gr import random import openpyxl from openpyxl.styles import Font, Alignment import tempfile from roboflow import Roboflow from inference import get_model import supervision as sv from PIL import Image import cv2 import numpy as np import os from gradio_calendar import Calendar import datetime import google.generativeai as genai excel_tempfile_state = gr.State() roll_number_state = gr.State() sno_state = gr.State() roll_number_state.value=1 sno_state.value=1 str_nums = {"zero":0,"one":1,"two":2,"three":3,"four":4,"five":5,"six":6,"seven":7,"eight":8,"nine":9} genai.configure(api_key="AIzaSyBXu8JrmDtmuK0FQCGZMyB3T-hb35UCtGM") def upload_to_gemini(path, mime_type=None): try: file = genai.upload_file(path, mime_type=mime_type) print(f"Uploaded file '{file.display_name}' as: {file.uri}") return file except Exception as e: print(f"Error uploading file: {e}") return None # Create the model generation_config = { "temperature": 1, "top_p": 0.95, "top_k": 64, "max_output_tokens": 8192, "response_mime_type": "text/plain", } model = genai.GenerativeModel( model_name="gemini-2.0-flash-lite-preview-02-05", generation_config=generation_config, system_instruction="Identify the single handwritten digit on the given image, some times there will be blank images given.In that case give blank as output", ) def task1(Examination, Date_Of_Exam, Program, Branch, Course, Name_Of_Faculty, Academic_Year): with tempfile.NamedTemporaryFile(suffix=".xlsx", delete=False) as temp_file: workbook = openpyxl.Workbook() sheet = workbook.active # Define font styles font_size_20 = Font(name="Times New Roman", size=20, bold=True) font_size_18 = Font(name="Times New Roman", size=18, bold=True) font_size_16 = Font(name="Times New Roman", size=16, bold=True) font_size_12_bold = Font(name="Times New Roman", size=12, bold=True) # Define alignment alignment_center = Alignment(horizontal="center") # Merge cells for first two rows sheet.merge_cells('A1:P1') sheet.merge_cells('A2:P2') sheet['A1'].value = "LAKIREDDY BALI REDDY COLLEGE OF ENGINEERING" sheet['A2'].value = "(AUTONOMOUS)" sheet['A1'].font = font_size_20 sheet['A2'].font = font_size_20 sheet['A1'].alignment = alignment_center sheet['A2'].alignment = alignment_center # Merge cells for third row sheet.merge_cells('A3:P3') sheet['A3'].value = "DEPARTMENT OF COMPUTER SCIENCE AND ENGINEERING" sheet['A3'].font = font_size_18 sheet['A3'].alignment = alignment_center # Merge cells for fourth row sheet.merge_cells('A4:P4') sheet['A4'].value = "MID DESCRIPTIVE MARKS LIST" sheet['A4'].font = font_size_16 sheet['A4'].alignment = alignment_center # Merge cells for fifth row sheet.merge_cells('A5:H5') sheet.merge_cells('I5:P5') sheet['A5'].value = f"Examination : {Examination}" sheet['I5'].value = f"Date of Exam : {Date_Of_Exam}" sheet['A5'].font = font_size_12_bold sheet['I5'].font = font_size_12_bold # Merge cells for sixth row sheet.merge_cells('A6:H6') sheet.merge_cells('I6:P6') sheet['A6'].value = f"Program : {Program}" sheet['I6'].value = f"Branch : {Branch}" sheet['A6'].font = font_size_12_bold sheet['I6'].font = font_size_12_bold # Merge cells for seventh row sheet.merge_cells('A7:H7') sheet.merge_cells('I7:P7') sheet['A7'].value = f"Course : {Course}" sheet['I7'].value = "Maximum Marks : 15" sheet['A7'].font = font_size_12_bold sheet['I7'].font = font_size_12_bold # Merge cells for eighth row sheet.merge_cells('A8:H8') sheet.merge_cells('I8:P8') sheet['A8'].value = f"Name of the Faculty: {Name_Of_Faculty}" sheet['I8'].value = f"Academic Year : {Academic_Year}" sheet['A8'].font = font_size_12_bold sheet['I8'].font = font_size_12_bold ##part two # Merge cells for SNo sheet.merge_cells('A9:A10') sheet['A9'] = "SNo" sheet['A9'].font = font_size_12_bold sheet['A9'].alignment = alignment_center # Add data for Regd Num sheet.merge_cells('B9:B10') sheet['B9'] = "Regd Num" sheet['B9'].font = font_size_12_bold sheet['B9'].alignment = alignment_center # Add data for Q. No 1 sheet.merge_cells('C9:F9') sheet['C9'] = "Q. No 1" sheet['C9'].font = font_size_12_bold sheet['C9'].alignment = alignment_center sheet['C10'] = "A" sheet['C10'].font = font_size_12_bold sheet['C10'].alignment = alignment_center sheet['D10'] = "B" sheet['D10'].font = font_size_12_bold sheet['D10'].alignment = alignment_center sheet['E10'] = "C" sheet['E10'].font = font_size_12_bold sheet['E10'].alignment = alignment_center sheet['F10'] = "D" sheet['F10'].font = font_size_12_bold sheet['F10'].alignment = alignment_center # Add data for Q. No 2 sheet.merge_cells('G9:J9') sheet['G9'] = "Q. No 2" sheet['G9'].font = font_size_12_bold sheet['G9'].alignment = alignment_center sheet['G10'] = "A" sheet['G10'].font = font_size_12_bold sheet['G10'].alignment = alignment_center sheet['H10'] = "B" sheet['H10'].font = font_size_12_bold sheet['H10'].alignment = alignment_center sheet['I10'] = "C" sheet['I10'].font = font_size_12_bold sheet['I10'].alignment = alignment_center sheet['J10'] = "D" sheet['J10'].font = font_size_12_bold sheet['J10'].alignment = alignment_center # Add data for Q. No 3 sheet.merge_cells('K9:N9') sheet['K9'] = "Q. No 3" sheet['K9'].font = font_size_12_bold sheet['K9'].alignment = alignment_center sheet['K10'] = "A" sheet['K10'].font = font_size_12_bold sheet['K10'].alignment = alignment_center sheet['L10'] = "B" sheet['L10'].font = font_size_12_bold sheet['L10'].alignment = alignment_center sheet['M10'] = "C" sheet['M10'].font = font_size_12_bold sheet['M10'].alignment = alignment_center sheet['N10'] = "D" sheet['N10'].font = font_size_12_bold sheet['N10'].alignment = alignment_center # Add data for Total(30M) sheet.merge_cells('O9:O10') sheet['O9'] = "Total(30M)" sheet['O9'].font = font_size_12_bold sheet['O9'].alignment = alignment_center # Add data for (Total 15 M) sheet.merge_cells('P9:P10') sheet['P9'] = "(Total 15 M)" sheet['P9'].font = font_size_12_bold sheet['P9'].alignment = alignment_center workbook.save(temp_file.name) excel_tempfile_state.value = temp_file.name print(excel_tempfile_state.value) return temp_file.name #configuring interface 1 inputs = [ gr.Dropdown(["I Mid","II Mid"], value=["I Mid", "II Mid"], label="Examination"), Calendar(type="date", label="Date Of Examination"), gr.Dropdown(["B-Tech R20","M-Tech R20","MBA R20","B-Tech R17","M-Tech R17","MBA-R17"], value=["B-Tech R20","M-Tech R20","MBA R20","B-Tech R17","M-Tech R17","MBA-R17"], label="Program"), gr.Dropdown(["ASE","AI&DS","Civil","CSE","CSE(AI&ML)","ECE","EEE","IT","MECH","MBA"], value=["ASE","AI&DS","Civil","CSE","CSE(AI&ML)","ECE","EEE","IT","MECH","MBA"], label="Branch"), gr.components.Textbox(label="Course"), gr.components.Textbox(label="Name Of Faculty"), gr.components.Textbox(label="Academic Year"), ] # interface one iface1 = gr.Interface( fn=task1, inputs=inputs, outputs="file", title="Automating Examination Mark Entry with Deep Learning" ) def predict_and_crop(image_np, api_key, model_id, confidence=40, overlap=30): # Convert the image to the format expected by the model (e.g., numpy array) image = image_np # Get the Roboflow model and run inference model = get_model(model_id=model_id, api_key=api_key) results = model.infer(image)[0] # Print and process results print("Results:", results) # Load the results into the supervision Detections API detections = sv.Detections.from_inference(results) print("detections:", detections) # Create supervision annotators bounding_box_annotator = sv.BoxAnnotator() label_annotator = sv.LabelAnnotator() # Annotate the image with bounding boxes and labels annotated_image = bounding_box_annotator.annotate(scene=image, detections=detections) annotated_image = label_annotator.annotate(scene=annotated_image, detections=detections) # Display the image with annotations sv.plot_image(annotated_image) # Now, extract the bounding box details from detections for cropping for detection in detections.xyxy: # Extract coordinates from detections (xyxy format: [x1, y1, x2, y2]) x1, y1, x2, y2 = map(int, detection) # Crop the image based on the bounding box cropped_img = image[y1:y2, x1:x2] # Convert cropped image to PIL for rotation handling (if needed) cropped_img_pil = Image.fromarray(cropped_img) cropped_img_np = np.array(cropped_img_pil) # Rotate the image if height is greater than width h, w, c = cropped_img_np.shape if h > w: cropped_img_np = cv2.rotate(cropped_img_np, cv2.ROTATE_90_CLOCKWISE) print(cropped_img_np) return cropped_img_np, image # Return both cropped image and original image # Function to resize and insert cropped image def resize_and_insert(cropped_image, output_image_path): # base_image = cv2.imread(base_image_path) base_height, base_width = (460, 1158) base_aspect_ratio = base_width / base_height new_width = int(base_height * base_aspect_ratio) resized_cropped_img = cv2.resize(cropped_image, (new_width, base_height)) return resized_cropped_img # Function to convert string to integer based on confidence level def convert_str_int(var, conf): if conf < 0.5: return " " else: return str_nums[var] def append_to_workbook(cells_data, excel_file_path): workbook = openpyxl.load_workbook(excel_file_path) sheet = workbook.active # Retrieve current SNo and roll number from state sno = sno_state.value rno = roll_number_state.value if rno<10: rno_str = "21761A420"+str(rno) else: rno_str = "21761A42"+str(rno) # Increment SNo and roll number sno_state.value = sno + 1 roll_number_state.value = rno + 1 next_row = sheet.max_row + 1 # Insert roll number and SNo sheet.cell(row=next_row, column=1, value=sno) sheet.cell(row=next_row, column=2, value=rno_str) for col, value in enumerate(cells_data, start=3): sheet.cell(row=next_row, column=col, value=value) marks=[] for i in cells_data: if str(i).isdigit(): marks.append(int(i)) else: marks.append(0) total_30_marks = max(sum(marks[0:2]),sum(marks[2:4]))+max(sum(marks[4:6]),sum(marks[6:8]))+max(sum(marks[8:10]),sum(marks[10:12])) total_15_marks = round(total_30_marks / 2, 2) sheet.cell(row=next_row, column=15, value=total_30_marks) sheet.cell(row=next_row, column=16, value=total_15_marks) # Save the workbook workbook.save(excel_file_path) #All Functions for interface 2 def task2(image_np): api_key = "UyAumhQJOJpo7vUu3LaK" project_name = "marks_table_detection_lbrce" model_id = "marks_table_detection_lbrce/2" model_version = 1 base_image_path = "/content/base_img.png" temp_image_path = "/content/temp_image.jpg" output_image_path = "/content/merged_image.jpg" #API and requirements for OCR Model # rf = Roboflow(api_key="XsMt3y86MNDGihOYcWDY") # project = rf.workspace().project("mnist-cjkff") # model = project.version(2).model # model = get_model(model_id="mnist-cjkff", api_key="XsMt3y86MNDGihOYcWDY") # Predict and crop # cropped_image, original_image = predict_and_crop(image_np, api_key, project_name, model_version) cropped_image, original_image = predict_and_crop(image_np, api_key, model_id) # Resize and insert result_image = resize_and_insert(cropped_image, output_image_path) # Cell coordinates cell_coordinates = cell_coordinates = [(235, 129), (475, 223), (496, 125), (685, 225), (708, 127), (896, 225), (919, 125), (1140, 217), (232, 253), (473, 346), (500, 249), (687, 347), (708, 250), (896, 346), (920, 249), (1142, 345), (232, 375), (474, 442), (496, 371), (686, 442), (708, 373), (897, 444), (922, 373), (1147, 443)] cells_data = [] qno = 0 for i in range(0, len(cell_coordinates), 2): top_left = cell_coordinates[i] bottom_right = cell_coordinates[i + 1] cell = result_image[top_left[1]:bottom_right[1], top_left[0]:bottom_right[0]] cell_gray = cv2.cvtColor(cell, cv2.COLOR_BGR2GRAY) _, thresholded_cell = cv2.threshold(cell_gray, 127, 255, cv2.THRESH_BINARY_INV) _, temp_thresholded_path = tempfile.mkstemp(suffix=".jpg") cv2.imwrite(temp_thresholded_path, thresholded_cell) image_path = "/content/temp_image_12.jpg" # Make sure the image is in the correct path mime_type = "image/jpeg" # Use the appropriate MIME type # Upload the image to Gemini file = upload_to_gemini(temp_thresholded_path, mime_type) # Start a chat session and send the image as input chat_session = model.start_chat( history=[ { "role": "user", "parts": [ file, "Identify the digit", ], }, ] ) # Send a message to process the image response = chat_session.send_message("Identify the digit") print(response.text) # Output the model's response dt = response.text[::2] if dt.isdigit(): cells_data.append(int(dt)) else: cells_data.append(0) qno += 1 excel_file_path = excel_tempfile_state.value append_to_workbook(cells_data,excel_file_path) print(cells_data) return cropped_image, cells_data, excel_file_path iface2 = gr.Interface( fn=task2, elem_id="my-interface", inputs=[ gr.components.Image(type="numpy", label="Upload Image") ], outputs=[ gr.components.Image(type="numpy", label="Cropped Image"), gr.components.Textbox(label="Detected Marks"), gr.components.File(label="marks_sheet") ], # examples=[['IMG_20240215_210403.jpg'],['IMG_20240215_210530.jpg'],['IMG_20240215_210534.jpg'],['IMG_20240215_210611.jpg']], title="Automating Examination Mark Entry with Deep Learning", theme="huggingface" ) demo = gr.TabbedInterface([iface1, iface2], ["Configure Excel Sheet Data", "Extract marks from Answer Sheets"]) # Run the interface demo.launch(share=True,debug=True)