Spaces:
Sleeping
Sleeping
| # app/services/segmenter.py | |
| import os | |
| import io | |
| import numpy as np | |
| import tensorflow as tf | |
| from PIL import Image | |
| from typing import Dict, Any | |
| os.environ["TF_ENABLE_ONEDNN_OPTS"] = "0" | |
| from app.configs import get_segmentation_model, SEGMENTS_DIR | |
| from app.core.preprocessing import preprocess_image | |
| def segment_image(image_bytes: bytes, image_id: str = None) -> Dict[str, Any]: | |
| """ | |
| Run segmentation and save mask as PNG image. | |
| Returns: | |
| Dict with: status, masks_shape, max_confidence, mask_path, error | |
| """ | |
| model = get_segmentation_model() | |
| if model is None: | |
| return { | |
| "status": "failed", | |
| "error": "Segmentation model not loaded", | |
| } | |
| try: | |
| # Preprocess | |
| img_array = preprocess_image(image_bytes, target_size=(256, 256)) | |
| # Get original size for resizing mask | |
| original_image = Image.open(io.BytesIO(image_bytes)) | |
| original_size = original_image.size | |
| # Run model | |
| result = model(tf.constant(img_array)) | |
| if isinstance(result, dict): | |
| masks = list(result.values())[0].numpy() | |
| else: | |
| masks = result.numpy() | |
| # Post-process mask | |
| mask = masks[0] # Remove batch dimension | |
| if mask.ndim == 3: | |
| mask = mask[:, :, 0] # Take first channel | |
| # Normalize to 0-255 | |
| mask = (mask * 255).astype(np.uint8) | |
| # Create PIL image and resize to original size | |
| mask_image = Image.fromarray(mask) | |
| mask_image = mask_image.resize(original_size) | |
| # 🔥 Save mask as PNG | |
| mask_path = None | |
| if image_id: | |
| mask_filename = f"{image_id}_mask.png" | |
| mask_path = str(SEGMENTS_DIR / mask_filename) | |
| mask_image.save(mask_path, format='PNG') | |
| print(f"💾 Mask saved to: {mask_path}") | |
| return { | |
| "status": "completed", | |
| "masks_shape": list(masks.shape), | |
| "max_confidence": float(np.max(masks)), | |
| "mask_path": mask_path, | |
| } | |
| except Exception as e: | |
| print(f"❌ SEGMENTATION FAILED: {e}") | |
| return { | |
| "status": "failed", | |
| "error": str(e), | |
| } |