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

166 lines
5.4 KiB
Python

from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.orm import Session
from typing import List, Dict, Any
import json
from pathlib import Path
from app.db.session import get_db
from app.db.crud_tomato import tomato_image, analysis_result
from app.schemas.tomato import (
AnalysisResponse,
AnalysisResultCreate,
SeverityDetailCreate
)
from app.services.model import segmentation_model
router = APIRouter()
@router.post("/analyze/{image_id}", response_model=AnalysisResponse)
def analyze_tomato_image(
image_id: str,
db: Session = Depends(get_db)
):
"""
Analyze a tomato image to detect disease severity.
This endpoint processes the image using the segmentation model
and returns detailed analysis results, including disease severity
classification and segmentation masks.
"""
# Get the image from database
db_image = tomato_image.get(db=db, id=image_id)
if db_image is None:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Image not found"
)
# Check if image file exists
image_path = db_image.file_path
if not Path(image_path).exists():
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Image file not found on server"
)
# Analyze the image
analysis_results = segmentation_model.analyze_image(image_path)
if not analysis_results.get("success", False):
raise HTTPException(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
detail=analysis_results.get("error", "Failed to analyze image")
)
# Store analysis results in database
analysis_data = {
"image_id": db_image.id,
"model_name": analysis_results["model_name"],
"model_version": analysis_results["model_version"],
"primary_severity": analysis_results["primary_severity"],
"severity_confidence": analysis_results["severity_confidence"],
"segmentation_data": json.dumps(analysis_results["segmentation_data"]),
"processing_time_ms": analysis_results["processing_time_ms"]
}
analysis_in = AnalysisResultCreate(**analysis_data)
# Create severity details
severity_details_data = []
for detail in analysis_results["severity_details"]:
severity_details_data.append(
SeverityDetailCreate(
severity_class=detail["severity_class"],
confidence=detail["confidence"],
affected_area_percentage=detail["affected_area_percentage"],
analysis_id="" # Will be set after analysis is created
)
)
# Create analysis result with details
db_analysis = analysis_result.create_with_details(
db=db,
analysis_in=analysis_in,
details_in=severity_details_data
)
# Get fresh data with relationships loaded
db_analysis = analysis_result.get(db=db, id=db_analysis.id)
# Prepare response
response = AnalysisResponse(
id=db_analysis.id,
image=db_image,
primary_severity=db_analysis.primary_severity,
severity_confidence=db_analysis.severity_confidence,
severity_details=db_analysis.severity_details,
segmentation_data=db_analysis.segmentation_data,
processed_at=db_analysis.processed_at,
model_name=db_analysis.model_name,
model_version=db_analysis.model_version
)
return response
@router.get("/results/{image_id}", response_model=List[AnalysisResponse])
def get_analysis_results(
image_id: str,
db: Session = Depends(get_db)
):
"""
Get all analysis results for a specific tomato image.
"""
# Check if image exists
db_image = tomato_image.get(db=db, id=image_id)
if db_image is None:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Image not found"
)
# Get analysis results
analyses = analysis_result.get_for_image(db=db, image_id=image_id)
# Prepare response
responses = []
for db_analysis in analyses:
responses.append(
AnalysisResponse(
id=db_analysis.id,
image=db_image,
primary_severity=db_analysis.primary_severity,
severity_confidence=db_analysis.severity_confidence,
severity_details=db_analysis.severity_details,
segmentation_data=db_analysis.segmentation_data,
processed_at=db_analysis.processed_at,
model_name=db_analysis.model_name,
model_version=db_analysis.model_version
)
)
return responses
@router.get("/info", response_model=Dict[str, Any])
def get_model_info():
"""
Get information about the tomato severity segmentation model.
"""
return {
"name": segmentation_model.model_name,
"version": segmentation_model.model_version,
"description": "Tomato disease severity segmentation model",
"input_format": {
"type": "image",
"size": segmentation_model.input_size,
"supported_formats": ["JPEG", "PNG"]
},
"severity_classes": segmentation_model.severity_classes,
"capabilities": [
"disease classification",
"severity assessment",
"leaf segmentation"
]
}