dss_sih_final / main.py
Ishan1923's picture
Upload 3 files
92f1c87 verified
import uuid
import os
import shutil
import cv2
import numpy as np
import torch
import torch.nn.functional as F
# --- CHANGE 1: Import APIRouter ---
from fastapi import FastAPI, File, Form, UploadFile, APIRouter
from fastapi.responses import JSONResponse
from fastapi.staticfiles import StaticFiles
from PIL import Image
from transformers import SegformerImageProcessor, SegformerForSemanticSegmentation
from typing import Optional
import json
# (Your CONFIGURATION, MODEL LOADING, and HELPER FUNCTIONS stay exactly the same)
# ...
COLOR_MAP = {0: ("Built Area", [128, 128, 128]), 1: ("Vegetation", [0, 255, 0]), 2: ("Water", [255, 0, 0]), 3: ("Barren Land", [135, 184, 222])}
ADE20K_TO_LULC = { 0: 0, 1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 0, 11: 0, 15: 0, 16: 0, 18: 0, 29: 0, 30: 0, 34: 0, 41: 0, 42: 0, 54: 0, 55: 0, 56: 0, 60: 0, 64: 0, 67: 0, 71: 0, 84: 0, 91: 0, 92: 0, 96: 0, 98: 0, 100: 0, 102: 0, 107: 0, 112: 0, 118: 0, 119: 0, 120: 0, 122: 0, 125: 0, 129: 0, 134: 0, 138: 0, 148: 0, 9: 1, 13: 1, 22: 1, 33: 1, 45: 1, 14: 2, 25: 2, 89: 2, 12: 3, 20: 3, 44: 3, 70: 3, }
PROCESSOR = SegformerImageProcessor.from_pretrained("nvidia/segformer-b1-finetuned-ade-512-512")
MODEL = SegformerForSemanticSegmentation.from_pretrained("nvidia/segformer-b1-finetuned-ade-512-512")
def postprocess_output(mask_2d):
height, width = mask_2d.shape
color_mask_bgr = np.zeros((height, width, 3), dtype=np.uint8)
total_pixels = height * width
percentages = {}
for lulc_index, (class_name, color) in COLOR_MAP.items():
pixels = (mask_2d == lulc_index)
color_mask_bgr[pixels] = color
pixel_count = np.sum(pixels)
percentage = (pixel_count / total_pixels) * 100
percentages[class_name] = f"{percentage:.2f}%"
return color_mask_bgr, percentages
# ...
app = FastAPI()
# --- CHANGE 2: Create a router object ---
router = APIRouter()
app.mount("/processed", StaticFiles(directory="processed"), name="processed_files")
# --- CHANGE 3: Use @router instead of @app for the endpoints ---
@router.post("/predict/lulc")
async def process_lulc_image(
file: UploadFile = File(...),
labels_json: Optional[str] = Form(None)
):
# --- YOUR EXISTING FUNCTION LOGIC IS UNCHANGED ---
# (Just copy-paste your whole function here)
try:
if labels_json:
print("Received Optional Labels:", json.loads(labels_json))
upload_filename = f"uploads/{uuid.uuid4()}_{file.filename}"
with open(upload_filename, "wb") as buffer:
shutil.copyfileobj(file.file, buffer)
image = Image.open(upload_filename).convert("RGB")
original_size = image.size[::-1]
inputs = PROCESSOR(images=image, return_tensors="pt")
with torch.no_grad():
outputs = MODEL(**inputs)
logits = outputs.logits.cpu()
interpolated_logits = F.interpolate(logits, size=original_size, mode="bilinear", align_corners=False)
prediction_mask_150_classes = interpolated_logits.argmax(dim=1)[0].numpy().astype(np.uint8)
simplified_mask = np.full(prediction_mask_150_classes.shape, -1, dtype=np.uint8)
for original_class, lulc_class in ADE20K_TO_LULC.items():
simplified_mask[prediction_mask_150_classes == original_class] = lulc_class
colored_mask, class_percentages = postprocess_output(simplified_mask)
processed_filename_base = f"{uuid.uuid4()}.png"
processed_filename_path = f"processed/{processed_filename_base}"
cv2.imwrite(processed_filename_path, colored_mask)
processed_image_url = f"/processed/{processed_filename_base}"
return JSONResponse(content={"message": "Processing successful", "processed_image_url": processed_image_url, "labels": class_percentages})
except Exception as e:
import traceback
print(traceback.format_exc())
return JSONResponse(content={"error": str(e)}, status_code=500)
@router.get("/")
def read_root():
return {"message": "LULC Model API is running."}
# --- CHANGE 4: Include the router in the main app ---
app.include_router(router)