React_native_app / main.py
Charuka66's picture
Update main.py
3a67dd1 verified
from fastapi import FastAPI, File, UploadFile, Form
from fastapi.middleware.cors import CORSMiddleware
from typing import Optional
from ultralytics import YOLO
import uvicorn
import shutil
import os
app = FastAPI()
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# ==========================================
# LOAD MODELS (Dual-Architecture)
# ==========================================
print("⏳ Loading Models...")
try:
disease_model = YOLO('best.pt')
print("βœ… Goyam Disease Classifier loaded!")
except Exception as e:
print(f"❌ Error loading Disease Model: {e}")
try:
gatekeeper_model = YOLO('yolov8n-cls.pt')
print("βœ… Plant Gatekeeper loaded!")
except Exception as e:
print(f"❌ Error loading Gatekeeper: {e}")
# ==========================================
# πŸ›‘οΈ THE SMART GATEKEEPER
# ==========================================
def is_likely_plant(image_path):
try:
results = gatekeeper_model(image_path, verbose=False)
top5_indices = results[0].probs.top5
top5_names = [results[0].names[i].lower() for i in top5_indices]
print(f"Gatekeeper sees: {top5_names}")
# ALLOW LIST: Botanical terms AND known macro-photography hallucinations
allowed_keywords = [
# True Botanical
'plant', 'leaf', 'grass', 'flower', 'tree', 'fern', 'moss', 'weed',
'crop', 'agriculture', 'field', 'greenhouse', 'pot', 'earth', 'soil',
'vegetation', 'forest', 'valley', 'daisy', 'corn', 'acorn', 'paddy', 'cardoon', 'reed',
# Common ImageNet Hallucinations for extreme close-up leaf textures
'damselfly', 'chameleon', 'lizard', 'ear', 'lacewing', 'spider', 'insect',
'bug', 'mantis', 'paintbrush', 'broom', 'bow', 'nematode', 'slug', 'snail', 'snake'
]
for predicted_item in top5_names:
for good_word in allowed_keywords:
if good_word in predicted_item:
print(f"βœ… Passed: Gatekeeper authorized based on '{predicted_item}'")
return True
print(f" Blocked: No natural or agricultural features detected.")
return False
except Exception as e:
print(f" Gatekeeper Error: {e}")
return True
def get_recommendation(disease_name):
recommendations = {
"Leaf Blast": "Use Tricyclazole 75 WP. Avoid applying excess nitrogen fertilizer.",
"Sheath Blight": "Drain the field immediately. Apply validamycin or carbendazim.",
"Brown Spot": "Improve soil fertility. Apply potassium and phosphorus.",
"Healthy Rice Leaf": "No disease detected. Keep maintaining optimal water levels!"
}
for key, value in recommendations.items():
if key.lower() in disease_name.lower():
return value
return "Consult your local agricultural extension officer for treatment."
@app.post("/predict")
async def predict(
file: UploadFile = File(...),
latitude: Optional[str] = Form(None),
longitude: Optional[str] = Form(None)
):
print(f" Receiving image: {file.filename}")
temp_filename = f"temp_{file.filename}"
try:
with open(temp_filename, "wb") as buffer:
shutil.copyfileobj(file.file, buffer)
# πŸ›‘ STEP 1: RUN THE SMART GATEKEEPER
if not is_likely_plant(temp_filename):
return {
"filename": file.filename,
"disease": "Invalid Image",
"confidence": "0%",
"recommendation": "This image does not appear to be a plant or paddy field. Please upload a clear photo of a rice leaf.",
"latitude": float(latitude) if latitude else None,
"longitude": float(longitude) if longitude else None
}
# STEP 2: RUN DISEASE CLASSIFICATION
results = disease_model(temp_filename, verbose=False)
top_idx = results[0].probs.top1
confidence_score = float(results[0].probs.top1conf)
detected_name = results[0].names[top_idx]
response_data = {
"filename": file.filename,
"disease": detected_name,
"confidence": f"{int(confidence_score * 100)}%",
"recommendation": get_recommendation(detected_name),
"latitude": float(latitude) if latitude else None,
"longitude": float(longitude) if longitude else None
}
return response_data
except Exception as e:
print(f" API Error: {e}")
return {"error": str(e)}
finally:
if os.path.exists(temp_filename):
os.remove(temp_filename)
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=7860)