diahretnoutami
Initial project commit for insect classifier
62d3e16
from fastapi import FastAPI, File, UploadFile, Form
from fastapi.responses import JSONResponse, FileResponse
from fastapi.middleware.cors import CORSMiddleware
import os
from tensorflow.keras.models import load_model
from PIL import Image
import numpy as np
from fastapi.staticfiles import StaticFiles
import io
import sys # <-- TAMBAH INI
# 1. Inisialisasi Aplikasi FastAPI di awal (PINDAHKAN KE SINI)
app = FastAPI()
# 2. Mounting Static Files
app.mount("/static", StaticFiles(directory="static"), name="static")
# 3. Konfigurasi CORS
origins = [
"http://localhost:8000", # <-- Sesuaikan dengan port lokal yang kamu gunakan
"http://127.0.0.1:8000", # <-- Sesuaikan dengan port lokal yang kamu gunakan
# Di Hugging Face, ini akan dihandle oleh domain space itu sendiri.
# Kamu bisa menambahkan domain HF Space kamu di sini jika ada masalah CORS setelah deploy.
# Contoh: "https://<nama-user-kamu>.hf.space/<nama-space-kamu>"
]
app.add_middleware(
CORSMiddleware,
allow_origins=origins,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# 4. Memuat 2 Model
try:
cnn_model = load_model('ProyekCV_model.h5')
mobilenet_model = load_model('ProyekCV_model_v2.h5')
print("Kedua model (CNN dan MobileNet) berhasil dimuat!")
except Exception as e:
print(f"Gagal memuat model: {e}")
sys.exit(1) # <-- TAMBAH INI UNTUK MENGHENTIKAN APLIKASI JIKA MODEL GAGAL DIMUAT
class_names = ['Butterfly', 'Dragonfly', 'Grasshopper', 'Ladybird', 'Mosquito']
descriptions = {
'Grasshopper': "Grasshopper adalah serangga herbivora yang dikenal dengan kemampuan melompat jauh berkat kaki belakangnya yang kuat. Mereka biasanya ditemukan di padang rumput atau lahan terbuka. Suara khas yang dihasilkan oleh grasshopper berasal dari gesekan sayap mereka. Hewan ini memegang peran penting dalam rantai makanan sebagai mangsa bagi berbagai predator. Dalam jumlah besar, beberapa spesies grasshopper dapat menjadi hama tanaman pertanian.",
'Butterfly': "Butterfly adalah serangga cantik dengan sayap berwarna-warni yang hidup di berbagai habitat. Mereka mengalami metamorfosis lengkap dari larva menjadi dewasa. Butterfly sering dikaitkan dengan penyerbukan tanaman. Kehadiran mereka menandakan ekosistem yang sehat. Beberapa spesies butterfly terancam punah karena kerusakan habitat.",
'Dragonfly': "Dragonfly adalah serangga pemangsa yang hidup di dekat air. Mereka terbang sangat cepat dan lincah, memakan serangga lain seperti nyamuk. Dragonfly memiliki mata besar yang memberikan penglihatan hampir 360 derajat. Mereka berperan penting dalam mengontrol populasi serangga hama. Larvanya hidup di air sebelum bermetamorfosis menjadi dewasa.",
'Ladybird': "Ladybird, atau kepik, adalah serangga kecil berwarna cerah dengan bintik-bintik di punggungnya. Mereka dikenal sebagai predator alami kutu daun. Ladybird dianggap menguntungkan bagi petani karena membantu mengendalikan hama. Terdapat berbagai spesies ladybird dengan pola warna yang berbeda. Beberapa budaya menganggap ladybird sebagai pembawa keberuntungan.",
'Mosquito': "Mosquito adalah serangga kecil yang dikenal sebagai penghisap darah. Beberapa spesies dapat menularkan penyakit seperti malaria dan dengue. Hanya nyamuk betina yang menggigit manusia untuk mendapatkan protein dari darah. Mereka berkembang biak di air tergenang. Pengendalian populasi nyamuk penting untuk kesehatan masyarakat."
}
def preprocess_image(image):
img = image.resize((150, 150))
img = np.array(img) / 255.0
img = np.expand_dims(img, axis=0)
return img
@app.post("/predict/")
async def predict(file: UploadFile = File(...)):
image = Image.open(io.BytesIO(await file.read())).convert("RGB")
img = preprocess_image(image)
# CNN
cnn_pred = cnn_model.predict(img)
cnn_class = int(np.argmax(cnn_pred[0]))
cnn_conf = float(np.max(cnn_pred[0]))
if cnn_conf < 0.5:
cnn_label = "Tidak Dikenali"
cnn_desc = "Gambar tidak dapat dikenali dengan tingkat kepercayaan yang memadai oleh model CNN."
else:
cnn_label = class_names[cnn_class]
cnn_desc = descriptions.get(cnn_label, "Deskripsi tidak tersedia.")
# MobileNet
mobile_pred = mobilenet_model.predict(img)
mobile_class = int(np.argmax(mobile_pred[0]))
mobile_conf = float(np.max(mobile_pred[0]))
if mobile_conf < 0.5:
mobile_label = "Tidak Dikenali"
mobile_desc = "Gambar tidak dapat dikenali dengan tingkat kepercayaan yang memadai oleh model MobileNet."
else:
mobile_label = class_names[mobile_class]
mobile_desc = descriptions.get(mobile_label, "Deskripsi tidak tersedia.")
final_desc = cnn_desc # Default to CNN desc
if cnn_label == "Tidak Dikenali": # If CNN doesn't recognize
final_desc = mobile_desc # Try MobileNet's desc
if mobile_label == "Tidak Dikenali": # If both don't recognize
final_desc = "Gambar tidak dapat dikenali oleh kedua model."
return JSONResponse(content={
"cnn": {
"predicted_class": cnn_label,
"confidence": cnn_conf,
"description": cnn_desc
},
"mobilenet": {
"predicted_class": mobile_label,
"confidence": mobile_conf,
"description": mobile_desc
},
"overall_description": final_desc
})
@app.get("/")
async def get_home():
return FileResponse("static/home.html")
@app.get("/frontend.html")
async def get_frontend():
return FileResponse("static/frontend.html")
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000)