Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
|
@@ -72,8 +72,8 @@ def process_image(
|
|
| 72 |
image: Optional[Image.Image],
|
| 73 |
url: Optional[str],
|
| 74 |
model_name: str,
|
|
|
|
| 75 |
for_json: bool = False,
|
| 76 |
-
confidence_threshold: float = CONFIDENCE_THRESHOLD
|
| 77 |
) -> Union[Dict, Tuple[Optional[Image.Image], Optional[pd.DataFrame], Optional[pd.DataFrame], Optional[pd.DataFrame], str]]:
|
| 78 |
"""
|
| 79 |
Process an image for object detection or panoptic segmentation, handling Gradio and FastAPI inputs.
|
|
@@ -81,18 +81,21 @@ def process_image(
|
|
| 81 |
image: PIL Image object from file upload (optional).
|
| 82 |
url: URL of the image to process (optional).
|
| 83 |
model_name: Name of the model to use (must be in VALID_MODELS).
|
| 84 |
-
for_json: If True, return JSON dict for API/JSON tab; else, return tuple for Gradio Home tab.
|
| 85 |
confidence_threshold: Minimum confidence score for detection (default: 0.5).
|
|
|
|
| 86 |
Returns:
|
| 87 |
For JSON: Dict with base64-encoded image, detected objects, and confidence scores.
|
| 88 |
For Gradio: Tuple of (annotated image, objects DataFrame, unique objects DataFrame, properties DataFrame, error message).
|
| 89 |
"""
|
|
|
|
| 90 |
try:
|
| 91 |
# Validate input: ensure exactly one of image or URL is provided
|
| 92 |
if image is None and not url:
|
| 93 |
-
|
|
|
|
| 94 |
if image and url:
|
| 95 |
-
|
|
|
|
| 96 |
if model_name not in VALID_MODELS:
|
| 97 |
error_msg = f"Invalid model: {model_name}. Choose from: {VALID_MODELS}"
|
| 98 |
return {"error": error_msg} if for_json else (None, None, None, None, error_msg)
|
|
@@ -232,7 +235,7 @@ def process_image(
|
|
| 232 |
pd.DataFrame({"Unique Object": unique_objects, "Confidence Score": [f"{score:.2f}" for score in unique_confidences]})
|
| 233 |
if unique_objects else pd.DataFrame(columns=["Unique Object", "Confidence Score"])
|
| 234 |
)
|
| 235 |
-
properties_df = pd.DataFrame([properties])
|
| 236 |
return image, objects_df, unique_objects_df, properties_df, ""
|
| 237 |
except requests.RequestException as e:
|
| 238 |
# Handle URL fetch errors
|
|
@@ -279,7 +282,7 @@ async def detect_objects_endpoint(
|
|
| 279 |
contents = await file.read()
|
| 280 |
image = Image.open(BytesIO(contents)).convert("RGB")
|
| 281 |
# Process image with specified parameters
|
| 282 |
-
result = process_image(image, image_url, model_name,
|
| 283 |
if "error" in result:
|
| 284 |
raise HTTPException(status_code=400, detail=result["error"])
|
| 285 |
return JSONResponse(content=result)
|
|
@@ -359,8 +362,7 @@ def create_gradio_ui() -> gr.Blocks:
|
|
| 359 |
)
|
| 360 |
# Clear all inputs and outputs
|
| 361 |
clear_btn.click(
|
| 362 |
-
fn=lambda:
|
| 363 |
-
inputs=None,
|
| 364 |
outputs=[image_input, image_url_input, model_choice, confidence_slider, output_image, objects_output, unique_objects_output, properties_output, error_output],
|
| 365 |
)
|
| 366 |
# JSON tab for API-like output
|
|
@@ -393,14 +395,13 @@ def create_gradio_ui() -> gr.Blocks:
|
|
| 393 |
url_output = gr.JSON(label="API Response")
|
| 394 |
# Process image and return JSON when Process button is clicked
|
| 395 |
url_submit_btn.click(
|
| 396 |
-
fn=lambda img, url, model, conf: process_image(img, url, model,
|
| 397 |
inputs=[image_input_json, image_url_input_json, url_model_choice, confidence_slider_json],
|
| 398 |
outputs=[url_output],
|
| 399 |
)
|
| 400 |
# Clear inputs and output
|
| 401 |
url_clear_btn.click(
|
| 402 |
-
fn=lambda:
|
| 403 |
-
inputs=None,
|
| 404 |
outputs=[image_input_json, image_url_input_json, url_model_choice, confidence_slider_json, url_output],
|
| 405 |
)
|
| 406 |
# Help tab with usage instructions
|
|
|
|
| 72 |
image: Optional[Image.Image],
|
| 73 |
url: Optional[str],
|
| 74 |
model_name: str,
|
| 75 |
+
confidence_threshold: float = CONFIDENCE_THRESHOLD,
|
| 76 |
for_json: bool = False,
|
|
|
|
| 77 |
) -> Union[Dict, Tuple[Optional[Image.Image], Optional[pd.DataFrame], Optional[pd.DataFrame], Optional[pd.DataFrame], str]]:
|
| 78 |
"""
|
| 79 |
Process an image for object detection or panoptic segmentation, handling Gradio and FastAPI inputs.
|
|
|
|
| 81 |
image: PIL Image object from file upload (optional).
|
| 82 |
url: URL of the image to process (optional).
|
| 83 |
model_name: Name of the model to use (must be in VALID_MODELS).
|
|
|
|
| 84 |
confidence_threshold: Minimum confidence score for detection (default: 0.5).
|
| 85 |
+
for_json: If True, return JSON dict for API/JSON tab; else, return tuple for Gradio Home tab.
|
| 86 |
Returns:
|
| 87 |
For JSON: Dict with base64-encoded image, detected objects, and confidence scores.
|
| 88 |
For Gradio: Tuple of (annotated image, objects DataFrame, unique objects DataFrame, properties DataFrame, error message).
|
| 89 |
"""
|
| 90 |
+
error_msg = ""
|
| 91 |
try:
|
| 92 |
# Validate input: ensure exactly one of image or URL is provided
|
| 93 |
if image is None and not url:
|
| 94 |
+
error_msg = "Please provide an image or URL"
|
| 95 |
+
return {"error": error_msg} if for_json else (None, None, None, None, error_msg)
|
| 96 |
if image and url:
|
| 97 |
+
error_msg = "Provide either an image or URL, not both"
|
| 98 |
+
return {"error": error_msg} if for_json else (None, None, None, None, error_msg)
|
| 99 |
if model_name not in VALID_MODELS:
|
| 100 |
error_msg = f"Invalid model: {model_name}. Choose from: {VALID_MODELS}"
|
| 101 |
return {"error": error_msg} if for_json else (None, None, None, None, error_msg)
|
|
|
|
| 235 |
pd.DataFrame({"Unique Object": unique_objects, "Confidence Score": [f"{score:.2f}" for score in unique_confidences]})
|
| 236 |
if unique_objects else pd.DataFrame(columns=["Unique Object", "Confidence Score"])
|
| 237 |
)
|
| 238 |
+
properties_df = pd.DataFrame([properties])
|
| 239 |
return image, objects_df, unique_objects_df, properties_df, ""
|
| 240 |
except requests.RequestException as e:
|
| 241 |
# Handle URL fetch errors
|
|
|
|
| 282 |
contents = await file.read()
|
| 283 |
image = Image.open(BytesIO(contents)).convert("RGB")
|
| 284 |
# Process image with specified parameters
|
| 285 |
+
result = process_image(image, image_url, model_name, confidence_threshold=confidence_threshold, for_json=True)
|
| 286 |
if "error" in result:
|
| 287 |
raise HTTPException(status_code=400, detail=result["error"])
|
| 288 |
return JSONResponse(content=result)
|
|
|
|
| 362 |
)
|
| 363 |
# Clear all inputs and outputs
|
| 364 |
clear_btn.click(
|
| 365 |
+
fn=lambda: (None, "", VALID_MODELS[0], 0.5, None, pd.DataFrame(columns=["Object", "Confidence Score"]), pd.DataFrame(columns=["Unique Object", "Confidence Score"]), pd.DataFrame(columns=list(MODEL_DESCRIPTIONS.keys())), ""),
|
|
|
|
| 366 |
outputs=[image_input, image_url_input, model_choice, confidence_slider, output_image, objects_output, unique_objects_output, properties_output, error_output],
|
| 367 |
)
|
| 368 |
# JSON tab for API-like output
|
|
|
|
| 395 |
url_output = gr.JSON(label="API Response")
|
| 396 |
# Process image and return JSON when Process button is clicked
|
| 397 |
url_submit_btn.click(
|
| 398 |
+
fn=lambda img, url, model, conf: process_image(img, url, model, confidence_threshold=conf, for_json=True),
|
| 399 |
inputs=[image_input_json, image_url_input_json, url_model_choice, confidence_slider_json],
|
| 400 |
outputs=[url_output],
|
| 401 |
)
|
| 402 |
# Clear inputs and output
|
| 403 |
url_clear_btn.click(
|
| 404 |
+
fn=lambda: (None, "", VALID_MODELS[0], 0.5, {}),
|
|
|
|
| 405 |
outputs=[image_input_json, image_url_input_json, url_model_choice, confidence_slider_json, url_output],
|
| 406 |
)
|
| 407 |
# Help tab with usage instructions
|