hi can you make this professianl with good names and good function "import pika
import base64
import json
from fastapi import FastAPI, File, UploadFile, HTTPException
from fastapi.responses import StreamingResponse, HTMLResponse
from detectron2.utils.logger import setup_logger
import numpy as np
import cv2
import os
from detectron2 import model_zoo
from detectron2.engine import DefaultPredictor
from detectron2.config import get_cfg
from detectron2.utils.visualizer import Visualizer, ColorMode
from detectron2.data import MetadataCatalog
import io
from PIL import Image
import uvicorn

import matplotlib
matplotlib.use('Agg')

import os
os.environ['KMP_DUPLICATE_LIB_OK'] = 'TRUE'

app = FastAPI()
setup_logger()

cfg = get_cfg()
cfg.MODEL.DEVICE = "cpu"

cfg.merge_from_file("./detectron2_repo/configs/COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_3x.yaml")
cfg.DATASETS.TRAIN = ("line_doc3",)
cfg.DATASETS.TEST = ()   # no metrics implemented for this dataset
cfg.DATALOADER.NUM_WORKERS = 2
cfg.SOLVER.IMS_PER_BATCH = 2
cfg.SOLVER.BASE_LR = 0.02
cfg.SOLVER.MAX_ITER = 10000   # 300 iterations seem good enough, but you can certainly train longer
cfg.MODEL.ROI_HEADS.BATCH_SIZE_PER_IMAGE = 128   # faster, and good enough for this toy dataset
cfg.MODEL.ROI_HEADS.NUM_CLASSES = 3  # 3 classes (data, fig, hazelnut)

# Use the pretrained model from the Detectron2 model zoo for initialization
cfg.MODEL.WEIGHTS = "detectron2://COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_3x/137849600/model_final_f10217.pkl"

# Save the trained model to the specified directory
cfg.OUTPUT_DIR = "./models/"
cfg.MODEL.WEIGHTS = os.path.join(cfg.OUTPUT_DIR, "model_letter.pth")
cfg.MODEL.ROI_HEADS.SCORE_THRESH_TEST = 0.5   # set the testing threshold for this model



predictor = DefaultPredictor(cfg)

# Ensure the "save" folder exists
if not os.path.exists("save"):
    os.makedirs("save")

def get_detectron2_predictions(image):
    outputs = predictor(image)

    # Get predictions from the model
    instances = outputs["instances"].to("cpu")
    num_instances = len(instances)

    print(f"Number of instances detected: {num_instances}")

    # Draw bounding boxes on the image
    v = Visualizer(image[:, :, ::-1], MetadataCatalog.get(cfg.DATASETS.TRAIN[0]), scale=0.8)

    # Ensure that there are instances to draw
    if num_instances > 0:
        out = v.draw_instance_predictions(instances)
        processed_image = out.get_image()[:, :, ::-1]
        print("Bounding boxes drawn.")
    else:
        processed_image = image
        print("No instances detected, returning the original image.")

    return processed_image


@app.post('/process_image', response_class=HTMLResponse, status_code=200)
async def process_image(file: UploadFile = File(...)):
    try:
        contents = await file.read()
        image = Image.open(io.BytesIO(contents)).convert("RGB")
        image_array = np.array(image)[:, :, ::-1].copy()

        # Get predictions using the Detectron2 model
        processed_image = get_detectron2_predictions(image_array)

        # Encode the processed image to base64 for embedding in HTML
        _, buffer = cv2.imencode('.jpg', processed_image)
        if not buffer[0]:
            raise HTTPException(status_code=500, detail="Error encoding image.")

        encoded_image = base64.b64encode(buffer).decode("utf-8")

        # Display the processed image in the HTML response
        html_content = f"""
        <body>
            <img src="data:image/jpeg;base64,{encoded_image}" />
        </body>
        """

        return HTMLResponse(content=html_content)
    except Exception as e:
        print(f"Error processing image: {str(e)}")
        raise HTTPException(status_code=500, detail=f"Error processing image: {str(e)}")

@app.get("/")
async def main():
    content = """
    <body>
        <form action="/process_image" enctype="multipart/form-data" method="post">
            <input name="file" type="file" accept="image/*">
            <input type="submit">
        </form>
    </body>
    """
    return HTMLResponse(content)

if __name__ == "__main__":


    uvicorn.run(app, host="127.0.0.1", port=8000)