Modify this code to get entity name on top of bounding box

import json
import pandas as pd
import cv2
from thefuzz import fuzz
from thefuzz import process
import numpy as np

def read_textract_output(csv_path):
    return pd.read_csv(csv_path)

def read_json_entities(json_path):
    with open(json_path, 'r') as file:
        return json.load(file)
    
def find_entity_bounding_boxes(entity_text, textract_df, image_size):
    entity_tokens = entity_text.split()
    results = pd.DataFrame()

    for token in entity_tokens:
        choices = textract_df["text"].dropna().tolist()
        best_match, score = process.extractOne(token, choices, scorer=fuzz.token_sort_ratio)
        if score > 70:
            best_matches_df = textract_df[textract_df["text"] == best_match]
            results = pd.concat([results, best_matches_df])

    bounding_boxes = []
    try:
        # Sort by line and word number to cluster words that are on the same line
        sorted_results = results.sort_values(by=["line_num", "word_num"])

        # Group the resulting bounding boxes by line number
        grouped_results = sorted_results.groupby("line_num")

        for _, group in grouped_results:
            # Calculate scaling factors based on image size and original image dimensions
            image_width, image_height = group.iloc[0]["image_width"], group.iloc[0]["image_height"]
            scale_x = image_size[0] / image_width
            scale_y = image_size[1] / image_height

            # Calculate the bounding box for the whole line
            min_left = np.min(group["left"])
            min_top = np.min(group["top"])
            max_right = np.max(group["left"] + group["width"])
            max_bottom = np.max(group["top"] + group["height"])
            bbox = (min_left * scale_x, min_top * scale_y, (max_right - min_left) * scale_x, (max_bottom - min_top) * scale_y)
            bounding_boxes.append(bbox)
            
    except Exception as e:
        print(f"An error occurred: {e}")

    return bounding_boxes
        
def draw_bounding_boxes(image_path, entities, textract_df):
    image = cv2.imread(image_path)
    image_size = image.shape[1], image.shape[0]

    for category, details in entities.items():
        if category == "invoice_details" or category == "Payment Details" or category == "amounts_and_tax":
            for entity, value in details.items():
                if value:
                    bounding_boxes = find_entity_bounding_boxes(value, textract_df, image_size)
                    try:
                        for bbox in bounding_boxes:
                            x, y, w, h = map(int, bbox)
                            cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)
                    except:
                        pass
        else:
            pass

    cv2.imwrite('/home/ritik1s/Desktop/bbox_issues/temp_GPT/annotated_invoice.jpg', image)
    
    
IMAGE_PATH = '/home/ritik1s/Desktop/bbox_issues/temp_GPT/check.jpeg'
CSV_PATH = "/home/ritik1s/Desktop/bbox_issues/temp_GPT/check.csv"
JSON_PATH = "/home/ritik1s/Desktop/bbox_issues/temp_GPT/row_skip.json"

# Read Textract output and JSON entities
textract_df = read_textract_output(CSV_PATH)
entities = read_json_entities(JSON_PATH)

# Draw the bounding boxes
draw_bounding_boxes(IMAGE_PATH, entities, textract_df)