| 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 |
|
|
| |
| 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 |
| |
| 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) |
|
|
| |
| alignment_center = Alignment(horizontal="center") |
|
|
| |
| 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 |
|
|
| |
| 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 |
|
|
| |
| sheet.merge_cells('A4:P4') |
| sheet['A4'].value = "MID DESCRIPTIVE MARKS LIST" |
| sheet['A4'].font = font_size_16 |
| sheet['A4'].alignment = alignment_center |
|
|
| |
| 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 |
|
|
| |
| 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 |
|
|
| |
| 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 |
|
|
| |
| 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 |
|
|
|
|
| |
|
|
|
|
| |
| sheet.merge_cells('A9:A10') |
| sheet['A9'] = "SNo" |
| sheet['A9'].font = font_size_12_bold |
| sheet['A9'].alignment = alignment_center |
|
|
| |
| sheet.merge_cells('B9:B10') |
| sheet['B9'] = "Regd Num" |
| sheet['B9'].font = font_size_12_bold |
| sheet['B9'].alignment = alignment_center |
|
|
| |
| 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 |
|
|
| |
| 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 |
|
|
| |
| 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 |
|
|
| |
| sheet.merge_cells('O9:O10') |
| sheet['O9'] = "Total(30M)" |
| sheet['O9'].font = font_size_12_bold |
| sheet['O9'].alignment = alignment_center |
|
|
| |
| 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 |
|
|
|
|
|
|
|
|
| |
| 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"), |
| ] |
| |
| 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): |
| |
| image = image_np |
|
|
| |
| model = get_model(model_id=model_id, api_key=api_key) |
| results = model.infer(image)[0] |
|
|
| |
| print("Results:", results) |
|
|
| |
| detections = sv.Detections.from_inference(results) |
| print("detections:", detections) |
|
|
| |
| bounding_box_annotator = sv.BoxAnnotator() |
| label_annotator = sv.LabelAnnotator() |
|
|
| |
| annotated_image = bounding_box_annotator.annotate(scene=image, detections=detections) |
| annotated_image = label_annotator.annotate(scene=annotated_image, detections=detections) |
|
|
| |
| sv.plot_image(annotated_image) |
|
|
| |
| for detection in detections.xyxy: |
| |
| x1, y1, x2, y2 = map(int, detection) |
|
|
| |
| cropped_img = image[y1:y2, x1:x2] |
|
|
| |
| cropped_img_pil = Image.fromarray(cropped_img) |
| cropped_img_np = np.array(cropped_img_pil) |
|
|
| |
| 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 |
|
|
|
|
| |
| def resize_and_insert(cropped_image, output_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 |
|
|
| |
| 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 |
|
|
| |
| sno = sno_state.value |
| rno = roll_number_state.value |
| if rno<10: |
| rno_str = "21761A420"+str(rno) |
| else: |
| rno_str = "21761A42"+str(rno) |
| |
| sno_state.value = sno + 1 |
| roll_number_state.value = rno + 1 |
|
|
| next_row = sheet.max_row + 1 |
|
|
| |
| 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) |
| |
| workbook.save(excel_file_path) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
| 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" |
|
|
| |
| |
| |
| |
| |
|
|
| |
| |
| cropped_image, original_image = predict_and_crop(image_np, api_key, model_id) |
|
|
| |
| result_image = resize_and_insert(cropped_image, output_image_path) |
|
|
| |
| 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" |
| mime_type = "image/jpeg" |
|
|
| |
| file = upload_to_gemini(temp_thresholded_path, mime_type) |
|
|
| |
| chat_session = model.start_chat( |
| history=[ |
| { |
| "role": "user", |
| "parts": [ |
| file, |
| "Identify the digit", |
| ], |
| }, |
| ] |
| ) |
|
|
| |
| response = chat_session.send_message("Identify the digit") |
| print(response.text) |
| 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") |
| ], |
| |
| title="Automating Examination Mark Entry with Deep Learning", |
| theme="huggingface" |
| ) |
| demo = gr.TabbedInterface([iface1, iface2], ["Configure Excel Sheet Data", "Extract marks from Answer Sheets"]) |
|
|
| |
| demo.launch(share=True,debug=True) |