hmmm ya gt deh
This commit is contained in:
commit
e7b0d53770
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Prediction extends Model
|
||||
{
|
||||
//
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('predictions', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('predictions');
|
||||
}
|
||||
};
|
||||
116
python_ai/app.py
116
python_ai/app.py
|
|
@ -1,4 +1,5 @@
|
|||
from flask import Flask, request, jsonify
|
||||
from flask_cors import CORS
|
||||
import os
|
||||
from datetime import datetime
|
||||
import numpy as np
|
||||
|
|
@ -6,12 +7,15 @@ from PIL import Image
|
|||
from tensorflow.keras.models import load_model
|
||||
|
||||
app = Flask(__name__)
|
||||
CORS(app)
|
||||
|
||||
UPLOAD_FOLDER = os.path.join(os.path.dirname(__file__), 'uploads')
|
||||
os.makedirs(UPLOAD_FOLDER, exist_ok=True)
|
||||
|
||||
# 1. Sesuaikan nama file model!
|
||||
MODEL_PATH = os.path.join(os.path.dirname(__file__), 'model_padi.h5')
|
||||
|
||||
# 2. Sesuaikan dengan urutan class di Colab kamu (4 class)
|
||||
CLASS_NAMES = [
|
||||
'Healthy',
|
||||
'Blast',
|
||||
|
|
@ -19,23 +23,34 @@ CLASS_NAMES = [
|
|||
'Tungro'
|
||||
]
|
||||
|
||||
DESCRIPTIONS = {
|
||||
'Healthy': {
|
||||
'deskripsi': 'Kondisi tanaman sehat.',
|
||||
'solusi': 'Lanjutkan perawatan normal dan pemantauan rutin.'
|
||||
},
|
||||
'Blast': {
|
||||
'deskripsi': 'Blast adalah penyakit daun padi akibat jamur Pyricularia oryzae.',
|
||||
'solusi': 'Lakukan pengendalian jamur dan semprot fungisida sesuai anjuran.'
|
||||
},
|
||||
'Blight': {
|
||||
'deskripsi': 'Blight merupakan hawar daun bakteri.',
|
||||
'solusi': 'Gunakan varietas tahan dan sanitasi lahan yang baik.'
|
||||
},
|
||||
'Tungro': {
|
||||
'deskripsi': 'Tungro adalah penyakit virus yang ditularkan oleh wereng.',
|
||||
'solusi': 'Lakukan pengendalian hama wereng dan gunakan benih sehat.'
|
||||
}
|
||||
}
|
||||
|
||||
# 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))
|
||||
|
||||
print('Model berhasil dimuat dari', MODEL_PATH)
|
||||
except Exception as e:
|
||||
print("Gagal load model:", e)
|
||||
|
||||
|
||||
# Preprocessing gambar
|
||||
def preprocess_image(path):
|
||||
|
||||
image = Image.open(path).convert('RGB')
|
||||
|
|
@ -48,10 +63,9 @@ def preprocess_image(path):
|
|||
|
||||
return image_array
|
||||
|
||||
|
||||
@app.route('/prediksi', methods=['POST'])
|
||||
def prediksi():
|
||||
|
||||
# 3. Menerima request dengan key 'gambar'
|
||||
if 'gambar' not in request.files:
|
||||
return jsonify({
|
||||
'error': 'Tidak ada gambar'
|
||||
|
|
@ -74,80 +88,33 @@ def prediksi():
|
|||
print("Gambar diterima:", filename)
|
||||
|
||||
if model is None:
|
||||
return jsonify({
|
||||
'error': 'Model gagal dimuat'
|
||||
}), 500
|
||||
return jsonify({'error': 'Model tidak tersedia. Pastikan file .h5 ada.'}), 500
|
||||
|
||||
try:
|
||||
|
||||
# Preprocessing
|
||||
image_array = preprocess_image(filepath)
|
||||
predictions = model.predict(image_array, verbose=0)
|
||||
predicted_index = int(np.argmax(predictions, axis=1)[0])
|
||||
confidence = float(np.max(predictions, axis=1)[0]) * 100.0
|
||||
label = CLASS_NAMES[predicted_index] if predicted_index < len(CLASS_NAMES) else f'Kelas {predicted_index + 1}'
|
||||
|
||||
# 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.'
|
||||
}
|
||||
confidence_display = f'{confidence:.2f}%'
|
||||
all_predictions = {
|
||||
CLASS_NAMES[i]: float(predictions[0][i] * 100.0)
|
||||
for i in range(len(CLASS_NAMES))
|
||||
}
|
||||
description_data = DESCRIPTIONS.get(label, {
|
||||
'deskripsi': 'Tidak ada deskripsi tersedia.',
|
||||
'solusi': 'Tidak ada solusi tersedia.'
|
||||
})
|
||||
|
||||
return jsonify({
|
||||
|
||||
'penyakit': label,
|
||||
|
||||
'confidence': confidence_display,
|
||||
|
||||
'all_predictions': all_predictions,
|
||||
|
||||
'deskripsi': deskripsi[label]['deskripsi'],
|
||||
|
||||
'solusi': deskripsi[label]['solusi']
|
||||
|
||||
'deskripsi': description_data['deskripsi'],
|
||||
'solusi': description_data['solusi']
|
||||
})
|
||||
|
||||
except Exception as e:
|
||||
|
|
@ -160,4 +127,7 @@ def prediksi():
|
|||
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(debug=True)
|
||||
print('=' * 50)
|
||||
print('Klasifikasi Penyakit Daun Padi')
|
||||
print('=' * 50)
|
||||
app.run(host='127.0.0.1', port=5000, debug=False)
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
flask
|
||||
flask-cors
|
||||
tensorflow
|
||||
pillow
|
||||
numpy
|
||||
|
|
|
|||
Loading…
Reference in New Issue