Automated Action ab0e9b973a Implement tomato severity segmentation model API
- Set up FastAPI project structure with SQLite database
- Create database models for tomato images and severity classifications
- Implement image upload and processing endpoints
- Develop a segmentation model for tomato disease severity detection
- Add API endpoints for analysis and results retrieval
- Implement health check endpoint
- Set up Alembic for database migrations
- Update project documentation
2025-05-27 06:22:15 +00:00

88 lines
2.4 KiB
Python

import cv2
import numpy as np
from pathlib import Path
import uuid
import os
from datetime import datetime
from typing import Tuple, Dict, Any, Optional
from app.core.config import settings
def save_uploaded_image(file_data: bytes, filename: str) -> Dict[str, Any]:
"""
Save an uploaded image to the storage directory and return metadata.
Args:
file_data: The binary content of the uploaded file
filename: Original filename of the uploaded file
Returns:
Dict with image metadata including path, size, etc.
"""
# Generate a unique filename to avoid conflicts
extension = Path(filename).suffix.lower()
date_prefix = datetime.now().strftime("%Y%m%d")
unique_id = str(uuid.uuid4())
safe_filename = f"{date_prefix}_{unique_id}{extension}"
# Create full path
file_path = settings.IMAGE_DIR / safe_filename
# Write file to disk
with open(file_path, "wb") as f:
f.write(file_data)
# Get image dimensions if it's an image file
width, height = None, None
try:
img = cv2.imread(str(file_path))
if img is not None:
height, width, _ = img.shape
except Exception:
pass
return {
"file_path": str(file_path),
"filename": filename,
"file_size": len(file_data),
"width": width,
"height": height,
"mime_type": get_mime_type(extension)
}
def get_mime_type(extension: str) -> str:
"""Map file extension to MIME type."""
mime_types = {
".jpg": "image/jpeg",
".jpeg": "image/jpeg",
".png": "image/png",
".gif": "image/gif",
".bmp": "image/bmp",
".tiff": "image/tiff",
".tif": "image/tiff",
}
return mime_types.get(extension.lower(), "application/octet-stream")
def load_image(file_path: str) -> Optional[np.ndarray]:
"""Load an image from file path."""
if not os.path.exists(file_path):
return None
img = cv2.imread(file_path)
if img is None:
return None
return cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # Convert to RGB
def resize_image(image: np.ndarray, target_size: Tuple[int, int]) -> np.ndarray:
"""Resize image to target size."""
return cv2.resize(image, target_size, interpolation=cv2.INTER_AREA)
def normalize_image(image: np.ndarray) -> np.ndarray:
"""Normalize image pixel values to [0, 1]."""
return image.astype(np.float32) / 255.0