163 lines
3.7 KiB
Python
163 lines
3.7 KiB
Python
from flask import Flask, request, jsonify
|
|
import os
|
|
from datetime import datetime
|
|
import numpy as np
|
|
from PIL import Image
|
|
from tensorflow.keras.models import load_model
|
|
|
|
app = Flask(__name__)
|
|
|
|
UPLOAD_FOLDER = os.path.join(os.path.dirname(__file__), 'uploads')
|
|
os.makedirs(UPLOAD_FOLDER, exist_ok=True)
|
|
|
|
MODEL_PATH = os.path.join(os.path.dirname(__file__), 'model_padi.h5')
|
|
|
|
CLASS_NAMES = [
|
|
'Healthy',
|
|
'Blast',
|
|
'Blight',
|
|
'Tungro'
|
|
]
|
|
|
|
|
|
# Load model
|
|
model = None
|
|
|
|
try:
|
|
model = load_model(MODEL_PATH)
|
|
|
|
print("Model berhasil dimuat")
|
|
print("Input Shape :", model.input_shape)
|
|
print("Output Shape:", model.output_shape)
|
|
print("Model Type :", type(model))
|
|
|
|
except Exception as e:
|
|
print("Gagal load model:", e)
|
|
|
|
|
|
# Preprocessing gambar
|
|
def preprocess_image(path):
|
|
|
|
image = Image.open(path).convert('RGB')
|
|
|
|
image = image.resize((224, 224))
|
|
|
|
image_array = np.array(image).astype('float32') / 255.0
|
|
|
|
image_array = np.expand_dims(image_array, axis=0)
|
|
|
|
return image_array
|
|
|
|
|
|
@app.route('/prediksi', methods=['POST'])
|
|
def prediksi():
|
|
|
|
if 'gambar' not in request.files:
|
|
return jsonify({
|
|
'error': 'Tidak ada gambar'
|
|
}), 400
|
|
|
|
file = request.files['gambar']
|
|
|
|
if file.filename == '':
|
|
return jsonify({
|
|
'error': 'File kosong'
|
|
}), 400
|
|
|
|
# Simpan gambar
|
|
filename = datetime.now().strftime('%Y%m%d%H%M%S_') + file.filename
|
|
|
|
filepath = os.path.join(UPLOAD_FOLDER, filename)
|
|
|
|
file.save(filepath)
|
|
|
|
print("Gambar diterima:", filename)
|
|
|
|
if model is None:
|
|
return jsonify({
|
|
'error': 'Model gagal dimuat'
|
|
}), 500
|
|
|
|
try:
|
|
|
|
# Preprocessing
|
|
image_array = preprocess_image(filepath)
|
|
|
|
# Prediksi
|
|
predictions = model.predict(image_array)
|
|
|
|
print("\n===== HASIL PREDIKSI =====")
|
|
|
|
for i, nama in enumerate(CLASS_NAMES):
|
|
print(f"{nama}: {predictions[0][i] * 100:.2f}%")
|
|
|
|
predicted_index = int(np.argmax(predictions[0]))
|
|
|
|
label = CLASS_NAMES[predicted_index]
|
|
|
|
confidence_display = round(
|
|
float(predictions[0][predicted_index]) * 100,
|
|
2
|
|
)
|
|
|
|
print(f"HASIL AKHIR: {label}")
|
|
print(f"CONFIDENCE: {confidence_display}%")
|
|
|
|
# Semua probabilitas
|
|
all_predictions = {}
|
|
|
|
for i, nama in enumerate(CLASS_NAMES):
|
|
|
|
all_predictions[nama] = round(
|
|
float(predictions[0][i]) * 100,
|
|
2
|
|
)
|
|
|
|
# Deskripsi penyakit
|
|
deskripsi = {
|
|
'Blast': {
|
|
'deskripsi': 'Penyakit jamur yang menyebabkan bercak pada daun.',
|
|
'solusi': 'Gunakan fungisida dan varietas tahan penyakit.'
|
|
},
|
|
|
|
'Blight': {
|
|
'deskripsi': 'Hawar daun akibat bakteri.',
|
|
'solusi': 'Gunakan benih sehat dan kurangi kelembapan.'
|
|
},
|
|
|
|
'Healthy': {
|
|
'deskripsi': 'Daun padi sehat tanpa gejala penyakit.',
|
|
'solusi': 'Pertahankan perawatan tanaman.'
|
|
},
|
|
|
|
'Tungro': {
|
|
'deskripsi': 'Penyakit virus yang ditularkan wereng.',
|
|
'solusi': 'Kendalikan wereng dan gunakan varietas tahan.'
|
|
}
|
|
}
|
|
|
|
return jsonify({
|
|
|
|
'penyakit': label,
|
|
|
|
'confidence': confidence_display,
|
|
|
|
'all_predictions': all_predictions,
|
|
|
|
'deskripsi': deskripsi[label]['deskripsi'],
|
|
|
|
'solusi': deskripsi[label]['solusi']
|
|
|
|
})
|
|
|
|
except Exception as e:
|
|
|
|
print("ERROR:", e)
|
|
|
|
return jsonify({
|
|
'error': str(e)
|
|
}), 500
|
|
|
|
|
|
if __name__ == '__main__':
|
|
app.run(debug=True) |