Update MobileNetV2 4 kelas
This commit is contained in:
parent
87c699fd11
commit
511e08d204
|
|
@ -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');
|
||||||
|
}
|
||||||
|
};
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 106 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 100 KiB |
Binary file not shown.
|
|
@ -1,4 +1,5 @@
|
||||||
from flask import Flask, request, jsonify
|
from flask import Flask, request, jsonify
|
||||||
|
from flask_cors import CORS
|
||||||
import os
|
import os
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
@ -6,30 +7,33 @@ from PIL import Image
|
||||||
from tensorflow.keras.models import load_model
|
from tensorflow.keras.models import load_model
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
|
CORS(app)
|
||||||
|
|
||||||
UPLOAD_FOLDER = os.path.join(os.path.dirname(__file__), 'uploads')
|
UPLOAD_FOLDER = os.path.join(os.path.dirname(__file__), 'uploads')
|
||||||
os.makedirs(UPLOAD_FOLDER, exist_ok=True)
|
os.makedirs(UPLOAD_FOLDER, exist_ok=True)
|
||||||
|
|
||||||
MODEL_PATH = os.path.join(os.path.dirname(__file__), 'model_padi.h5')
|
# 1. Sesuaikan nama file model!
|
||||||
CLASS_NAMES = ['Blast', 'Blight', 'Tungro']
|
MODEL_PATH = os.path.join(os.path.dirname(__file__), 'model_padi_blast.h5')
|
||||||
|
|
||||||
|
# 2. Sesuaikan dengan urutan class di Colab kamu (4 class)
|
||||||
|
CLASS_NAMES = ['Healthy', 'Blast', 'Blight', 'Tungro']
|
||||||
|
|
||||||
model = None
|
model = None
|
||||||
try:
|
try:
|
||||||
model = load_model(MODEL_PATH)
|
model = load_model(MODEL_PATH)
|
||||||
print('Model dimuat dari', MODEL_PATH)
|
print('Model berhasil dimuat dari', MODEL_PATH)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print('Gagal memuat model:', e)
|
print('Gagal memuat model:', e)
|
||||||
|
|
||||||
|
|
||||||
def preprocess_image(path):
|
def preprocess_image(path):
|
||||||
image = Image.open(path).convert('RGB')
|
image = Image.open(path).convert('RGB')
|
||||||
image = image.resize((150, 150))
|
image = image.resize((150, 150))
|
||||||
image_array = np.array(image).astype('float32') / 255.0
|
image_array = np.array(image).astype('float32') / 255.0
|
||||||
return np.expand_dims(image_array, axis=0)
|
return np.expand_dims(image_array, axis=0)
|
||||||
|
|
||||||
|
|
||||||
@app.route('/prediksi', methods=['POST'])
|
@app.route('/prediksi', methods=['POST'])
|
||||||
def prediksi():
|
def prediksi():
|
||||||
|
# 3. Menerima request dengan key 'gambar'
|
||||||
if 'gambar' not in request.files:
|
if 'gambar' not in request.files:
|
||||||
return jsonify({'error': 'Tidak ada file gambar'}), 400
|
return jsonify({'error': 'Tidak ada file gambar'}), 400
|
||||||
|
|
||||||
|
|
@ -45,11 +49,11 @@ def prediksi():
|
||||||
print('GAMBAR DITERIMA:', filename)
|
print('GAMBAR DITERIMA:', filename)
|
||||||
|
|
||||||
if model is None:
|
if model is None:
|
||||||
return jsonify({'error': 'Model tidak tersedia. Pastikan model_padi.h5 ada dan Flask dapat memuatnya.'}), 500
|
return jsonify({'error': 'Model tidak tersedia. Pastikan file .h5 ada.'}), 500
|
||||||
|
|
||||||
try:
|
try:
|
||||||
image_array = preprocess_image(filepath)
|
image_array = preprocess_image(filepath)
|
||||||
predictions = model.predict(image_array)
|
predictions = model.predict(image_array, verbose=0)
|
||||||
predicted_index = int(np.argmax(predictions, axis=1)[0])
|
predicted_index = int(np.argmax(predictions, axis=1)[0])
|
||||||
confidence = float(np.max(predictions, axis=1)[0]) * 100.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}'
|
label = CLASS_NAMES[predicted_index] if predicted_index < len(CLASS_NAMES) else f'Kelas {predicted_index + 1}'
|
||||||
|
|
@ -63,4 +67,7 @@ def prediksi():
|
||||||
return jsonify({'error': 'Terjadi kesalahan saat memprediksi gambar.'}), 500
|
return jsonify({'error': 'Terjadi kesalahan saat memprediksi gambar.'}), 500
|
||||||
|
|
||||||
if __name__ == '__main__':
|
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
|
||||||
|
flask-cors
|
||||||
tensorflow
|
tensorflow
|
||||||
pillow
|
pillow
|
||||||
numpy
|
numpy
|
||||||
|
|
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 106 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 100 KiB |
Loading…
Reference in New Issue