Upload project Klasifikasi Penyakit - AdindaCintya
This commit is contained in:
parent
dfa11b62da
commit
9f7349294d
|
|
@ -40,7 +40,7 @@ public function prediksi(Request $request)
|
|||
|
||||
if (!$response->successful()) {
|
||||
Log::error('Server prediksi gagal', ['body' => $response->body()]);
|
||||
return back()->with('error', 'Tidak dapat memproses prediksi.');
|
||||
return back()->with('error', 'Sistem tidak dapat melakukan klasifikasi, Pastikan gambar yang diunggah merupakan citra daun padi..');
|
||||
}
|
||||
|
||||
$hasil = $response->json();
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 5.6 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 8.6 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1024 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 106 KiB |
578
python_ai/app.py
578
python_ai/app.py
|
|
@ -6,128 +6,576 @@ import numpy as np
|
|||
from PIL import Image
|
||||
from tensorflow.keras.models import load_model
|
||||
|
||||
|
||||
# ==========================================
|
||||
# FLASK CONFIG
|
||||
# ==========================================
|
||||
|
||||
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')
|
||||
# ==========================================
|
||||
# FOLDER & MODEL
|
||||
# ==========================================
|
||||
|
||||
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 SESUAI TRAINING MODEL
|
||||
# ==========================================
|
||||
|
||||
# 2. Sesuaikan dengan urutan class di Colab kamu (4 class)
|
||||
CLASS_NAMES = [
|
||||
|
||||
'Healthy',
|
||||
'Blast',
|
||||
'Blight',
|
||||
'Non-Padi',
|
||||
'Tungro'
|
||||
|
||||
]
|
||||
|
||||
|
||||
|
||||
# ==========================================
|
||||
# DESKRIPSI HASIL
|
||||
# ==========================================
|
||||
|
||||
DESCRIPTIONS = {
|
||||
|
||||
|
||||
'Healthy': {
|
||||
'deskripsi': 'Kondisi tanaman sehat.',
|
||||
'solusi': 'Lanjutkan perawatan normal dan pemantauan rutin.'
|
||||
|
||||
'deskripsi':
|
||||
'Daun padi dalam kondisi sehat.',
|
||||
|
||||
'solusi':
|
||||
'Pertahankan pemupukan, pengairan, dan perawatan tanaman secara rutin.'
|
||||
|
||||
},
|
||||
|
||||
|
||||
'Blast': {
|
||||
'deskripsi': 'Blast adalah penyakit daun padi akibat jamur Pyricularia oryzae.',
|
||||
'solusi': 'Lakukan pengendalian jamur dan semprot fungisida sesuai anjuran.'
|
||||
|
||||
'deskripsi':
|
||||
'Blast merupakan penyakit daun padi yang disebabkan oleh jamur Pyricularia oryzae.',
|
||||
|
||||
'solusi':
|
||||
'Gunakan fungisida dan varietas padi yang tahan terhadap penyakit blast.'
|
||||
|
||||
},
|
||||
|
||||
|
||||
'Blight': {
|
||||
'deskripsi': 'Blight merupakan hawar daun bakteri.',
|
||||
'solusi': 'Gunakan varietas tahan dan sanitasi lahan yang baik.'
|
||||
|
||||
'deskripsi':
|
||||
'Blight merupakan penyakit hawar daun yang disebabkan oleh bakteri.',
|
||||
|
||||
'solusi':
|
||||
'Gunakan benih sehat dan lakukan sanitasi lahan.'
|
||||
|
||||
},
|
||||
|
||||
|
||||
'Tungro': {
|
||||
'deskripsi': 'Tungro adalah penyakit virus yang ditularkan oleh wereng.',
|
||||
'solusi': 'Lakukan pengendalian hama wereng dan gunakan benih sehat.'
|
||||
}
|
||||
|
||||
'deskripsi':
|
||||
'Tungro merupakan penyakit virus yang ditularkan oleh wereng hijau.',
|
||||
|
||||
'solusi':
|
||||
'Lakukan pengendalian wereng dan gunakan varietas tahan tungro.'
|
||||
|
||||
},
|
||||
|
||||
|
||||
'Non-Padi': {
|
||||
|
||||
'deskripsi':
|
||||
'Gambar yang diunggah bukan daun padi.',
|
||||
|
||||
'solusi':
|
||||
'Silakan upload gambar daun padi yang jelas.'
|
||||
|
||||
}
|
||||
|
||||
# Load model
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
# ==========================================
|
||||
# LOAD MODEL
|
||||
# ==========================================
|
||||
|
||||
model = None
|
||||
|
||||
|
||||
try:
|
||||
|
||||
model = load_model(MODEL_PATH)
|
||||
print('Model berhasil dimuat dari', MODEL_PATH)
|
||||
|
||||
print("Model berhasil dimuat")
|
||||
|
||||
print(
|
||||
"Input Shape :",
|
||||
model.input_shape
|
||||
)
|
||||
|
||||
print(
|
||||
"Output Shape:",
|
||||
model.output_shape
|
||||
)
|
||||
|
||||
|
||||
except Exception as e:
|
||||
print("Gagal load model:", e)
|
||||
|
||||
print(
|
||||
"Gagal load model:",
|
||||
e
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
# ==========================================
|
||||
# PREPROCESS IMAGE
|
||||
# ==========================================
|
||||
|
||||
|
||||
def preprocess_image(path):
|
||||
|
||||
image = Image.open(path).convert('RGB')
|
||||
image = Image.open(path)
|
||||
|
||||
image = image.resize((224, 224))
|
||||
image = image.convert('RGB')
|
||||
|
||||
image_array = np.array(image).astype('float32') / 255.0
|
||||
|
||||
image_array = np.expand_dims(image_array, axis=0)
|
||||
image = image.resize(
|
||||
(224,224)
|
||||
)
|
||||
|
||||
|
||||
image_array = np.array(image)
|
||||
|
||||
|
||||
image_array = (
|
||||
image_array.astype('float32')
|
||||
/
|
||||
255.0
|
||||
)
|
||||
|
||||
|
||||
image_array = np.expand_dims(
|
||||
image_array,
|
||||
axis=0
|
||||
)
|
||||
|
||||
|
||||
return image_array
|
||||
|
||||
@app.route('/prediksi', methods=['POST'])
|
||||
def prediksi():
|
||||
# 3. Menerima request dengan key 'gambar'
|
||||
if 'gambar' not in request.files:
|
||||
|
||||
|
||||
|
||||
|
||||
# ==========================================
|
||||
# TEST API
|
||||
# ==========================================
|
||||
|
||||
|
||||
@app.route('/')
|
||||
|
||||
|
||||
def home():
|
||||
|
||||
return jsonify({
|
||||
'error': 'Tidak ada gambar'
|
||||
|
||||
"status":
|
||||
"API Klasifikasi Penyakit Daun Padi Aktif"
|
||||
|
||||
})
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# ==========================================
|
||||
# PREDIKSI
|
||||
# ==========================================
|
||||
|
||||
|
||||
@app.route(
|
||||
'/prediksi',
|
||||
methods=['POST']
|
||||
)
|
||||
|
||||
|
||||
def prediksi():
|
||||
|
||||
|
||||
if 'gambar' not in request.files:
|
||||
|
||||
|
||||
return jsonify({
|
||||
|
||||
"error":
|
||||
"Tidak ada gambar dikirim"
|
||||
|
||||
}),400
|
||||
|
||||
|
||||
|
||||
|
||||
file = request.files['gambar']
|
||||
|
||||
|
||||
|
||||
if file.filename == '':
|
||||
|
||||
|
||||
return jsonify({
|
||||
'error': 'File kosong'
|
||||
|
||||
"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)
|
||||
|
||||
|
||||
|
||||
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)
|
||||
|
||||
|
||||
print("\n====================")
|
||||
|
||||
print(
|
||||
"Gambar diterima:",
|
||||
filename
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if model is None:
|
||||
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}'
|
||||
|
||||
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': description_data['deskripsi'],
|
||||
'solusi': description_data['solusi']
|
||||
})
|
||||
|
||||
except Exception as e:
|
||||
"error":
|
||||
"Model tidak tersedia"
|
||||
|
||||
print("ERROR:", e)
|
||||
|
||||
return jsonify({
|
||||
'error': str(e)
|
||||
}),500
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
try:
|
||||
|
||||
|
||||
|
||||
# preprocessing
|
||||
|
||||
image_array = preprocess_image(filepath)
|
||||
|
||||
|
||||
|
||||
|
||||
# prediksi
|
||||
|
||||
predictions = model.predict(
|
||||
|
||||
image_array,
|
||||
|
||||
verbose=0
|
||||
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
predicted_index = int(
|
||||
|
||||
np.argmax(predictions[0])
|
||||
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
confidence = float(
|
||||
|
||||
np.max(predictions[0])
|
||||
|
||||
)
|
||||
|
||||
confidence_percent = confidence * 100
|
||||
|
||||
|
||||
|
||||
|
||||
label = CLASS_NAMES[
|
||||
|
||||
predicted_index
|
||||
|
||||
]
|
||||
|
||||
|
||||
|
||||
|
||||
print("\nHASIL PREDIKSI")
|
||||
|
||||
|
||||
for i,nama in enumerate(CLASS_NAMES):
|
||||
|
||||
|
||||
print(
|
||||
|
||||
nama,
|
||||
|
||||
":",
|
||||
|
||||
round(
|
||||
|
||||
predictions[0][i]*100,
|
||||
|
||||
2
|
||||
|
||||
),
|
||||
|
||||
"%"
|
||||
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
print(
|
||||
|
||||
"HASIL AKHIR:",
|
||||
|
||||
label
|
||||
|
||||
)
|
||||
|
||||
|
||||
|
||||
print(
|
||||
|
||||
"CONFIDENCE:",
|
||||
|
||||
confidence_percent
|
||||
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# ==============================
|
||||
# FILTER GAMBAR TIDAK JELAS
|
||||
# ==============================
|
||||
|
||||
|
||||
if confidence_percent < 60:
|
||||
|
||||
|
||||
return jsonify({
|
||||
|
||||
"error":
|
||||
|
||||
"Gambar tidak dikenali. Pastikan gambar daun padi."
|
||||
|
||||
}),400
|
||||
|
||||
|
||||
|
||||
|
||||
# ==============================
|
||||
# TOLAK NON PADI
|
||||
# ==============================
|
||||
|
||||
|
||||
if label == "Non-Padi":
|
||||
|
||||
|
||||
return jsonify({
|
||||
|
||||
"error":
|
||||
|
||||
"Gambar bukan daun padi. Silakan upload daun padi."
|
||||
|
||||
}),400
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
all_predictions = {}
|
||||
|
||||
|
||||
|
||||
for i in range(len(CLASS_NAMES)):
|
||||
|
||||
|
||||
all_predictions[
|
||||
|
||||
CLASS_NAMES[i]
|
||||
|
||||
] = round(
|
||||
|
||||
float(
|
||||
|
||||
predictions[0][i]*100
|
||||
|
||||
),
|
||||
|
||||
2
|
||||
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
detail = DESCRIPTIONS[label]
|
||||
|
||||
|
||||
|
||||
|
||||
return jsonify({
|
||||
|
||||
|
||||
|
||||
"penyakit":
|
||||
|
||||
label,
|
||||
|
||||
|
||||
|
||||
"confidence":
|
||||
|
||||
f"{confidence_percent:.2f}%",
|
||||
|
||||
|
||||
|
||||
|
||||
"all_predictions":
|
||||
|
||||
all_predictions,
|
||||
|
||||
|
||||
|
||||
|
||||
"deskripsi":
|
||||
|
||||
detail['deskripsi'],
|
||||
|
||||
|
||||
|
||||
|
||||
"solusi":
|
||||
|
||||
detail['solusi']
|
||||
|
||||
|
||||
})
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
except Exception as e:
|
||||
|
||||
|
||||
print(
|
||||
|
||||
"ERROR:",
|
||||
|
||||
e
|
||||
|
||||
)
|
||||
|
||||
|
||||
return jsonify({
|
||||
|
||||
"error":
|
||||
|
||||
str(e)
|
||||
|
||||
}),500
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# ==========================================
|
||||
# RUN FLASK
|
||||
# ==========================================
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print('=' * 50)
|
||||
print('Klasifikasi Penyakit Daun Padi')
|
||||
print('=' * 50)
|
||||
app.run(host='127.0.0.1', port=5000, debug=False)
|
||||
|
||||
|
||||
print("="*50)
|
||||
|
||||
print(
|
||||
"Klasifikasi Penyakit Daun Padi"
|
||||
)
|
||||
|
||||
print("="*50)
|
||||
|
||||
|
||||
|
||||
app.run(
|
||||
|
||||
host='127.0.0.1',
|
||||
|
||||
port=5000,
|
||||
|
||||
debug=False
|
||||
|
||||
)
|
||||
|
|
@ -25,13 +25,6 @@
|
|||
<h2 class="text-xl font-bold text-gray-800 mb-6">Statistik Penyakit</h2>
|
||||
<div class="h-64"><canvas id="chartPenyakit"></canvas></div>
|
||||
</div>
|
||||
<div class="bg-white p-8 rounded-3xl shadow-sm border border-gray-100">
|
||||
<h2 class="text-xl font-bold text-gray-800 mb-6">Confusion Matrix</h2>
|
||||
<div class="bg-gray-50 p-4 rounded-2xl border border-dashed border-gray-200">
|
||||
<img src="https://miro.medium.com/v2/resize:fit:1200/1*Z54JgbS4DUwWSknhDCvNTQ.png" class="rounded-xl w-full">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-10">
|
||||
<div class="flex justify-between items-center mb-6">
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
<div class="group bg-white rounded-[2rem] shadow-lg hover:shadow-2xl border border-gray-100 overflow-hidden hover:-translate-y-2 transition-all duration-500 flex flex-col">
|
||||
<div class="relative overflow-hidden h-64 shrink-0">
|
||||
<img src="https://www.irri.org/sites/default/files/styles/large/public/blast-rice.jpg"
|
||||
<img src="{{ asset('images/blast.jpg') }}"
|
||||
class="w-full h-full object-cover group-hover:scale-110 transition-transform duration-700">
|
||||
<div class="absolute inset-0 bg-gradient-to-t from-black/50 to-transparent"></div>
|
||||
<div class="absolute bottom-6 left-6">
|
||||
|
|
@ -73,7 +73,7 @@ class="w-full h-full object-cover group-hover:scale-110 transition-transform dur
|
|||
|
||||
<div class="group bg-white rounded-[2rem] shadow-lg hover:shadow-2xl border border-gray-100 overflow-hidden hover:-translate-y-2 transition-all duration-500 flex flex-col">
|
||||
<div class="relative overflow-hidden h-64 shrink-0">
|
||||
<img src="https://www.knowledgebank.irri.org/images/stories/xbacterial-blight.jpg.pagespeed.ic.y.jpg"
|
||||
<img src="{{ asset('images/blight.jpg') }}"
|
||||
class="w-full h-full object-cover group-hover:scale-110 transition-transform duration-700">
|
||||
<div class="absolute inset-0 bg-gradient-to-t from-black/50 to-transparent"></div>
|
||||
<div class="absolute bottom-6 left-6">
|
||||
|
|
@ -125,7 +125,7 @@ class="w-full h-full object-cover group-hover:scale-110 transition-transform dur
|
|||
|
||||
<div class="group bg-white rounded-[2rem] shadow-lg hover:shadow-2xl border border-gray-100 overflow-hidden hover:-translate-y-2 transition-all duration-500 flex flex-col">
|
||||
<div class="relative overflow-hidden h-64 shrink-0">
|
||||
<img src="https://www.knowledgebank.irri.org/images/stories/tungro-rice.jpg"
|
||||
<img src="{{ asset('images/tungro.jpg') }}"
|
||||
class="w-full h-full object-cover group-hover:scale-110 transition-transform duration-700">
|
||||
<div class="absolute inset-0 bg-gradient-to-t from-black/50 to-transparent"></div>
|
||||
<div class="absolute bottom-6 left-6">
|
||||
|
|
@ -182,7 +182,7 @@ class="w-full h-full object-cover group-hover:scale-110 transition-transform dur
|
|||
</div>
|
||||
|
||||
<div class="relative overflow-hidden h-64 shrink-0">
|
||||
<img src="https://www.knowledgebank.irri.org/images/stories/healthy-rice.jpg"
|
||||
<img src="{{ asset('images/healthy.jpg') }}"
|
||||
class="w-full h-full object-cover group-hover:scale-110 transition-transform duration-700">
|
||||
<div class="absolute inset-0 bg-gradient-to-t from-black/50 to-transparent"></div>
|
||||
<div class="absolute bottom-6 left-6">
|
||||
|
|
|
|||
|
|
@ -127,7 +127,7 @@ class="relative rounded-3xl shadow-2xl border-4 border-white transform hover:sca
|
|||
<div class="absolute top-0 left-0 w-2 h-full bg-green-500"></div>
|
||||
|
||||
<h2 class="text-3xl font-extrabold text-gray-800 mb-8 text-center">
|
||||
Hasil Analisis AI
|
||||
Hasil Analisis
|
||||
</h2>
|
||||
|
||||
<img src="{{ asset('uploads/' . session('gambar')) }}" class="w-72 rounded-2xl shadow-xl mb-10 mx-auto border-4 border-white transform hover:scale-105 transition-transform duration-500">
|
||||
|
|
@ -198,57 +198,263 @@ class="relative rounded-3xl shadow-2xl border-4 border-white transform hover:sca
|
|||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ================= GALERI PENYAKIT ================= -->
|
||||
|
||||
<section class="max-w-7xl mx-auto px-6 pb-24">
|
||||
|
||||
<div class="text-center mb-16">
|
||||
<h2 class="text-4xl font-extrabold text-gray-800 mb-4">Galeri Penyakit Padi</h2>
|
||||
<p class="text-gray-500 max-w-2xl mx-auto">Kenali berbagai jenis penyakit yang sering menyerang daun padi beserta gejalanya secara visual.</p>
|
||||
|
||||
<h2 class="text-4xl font-extrabold text-gray-800 mb-4">
|
||||
Galeri Penyakit Padi
|
||||
</h2>
|
||||
|
||||
<p class="text-gray-500 max-w-2xl mx-auto">
|
||||
Kenali berbagai jenis penyakit yang sering menyerang daun padi beserta gejalanya secara visual.
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="grid md:grid-cols-2 lg:grid-cols-4 gap-8">
|
||||
<div class="group bg-white rounded-3xl shadow-lg hover:shadow-2xl hover:-translate-y-2 transition-all duration-300 overflow-hidden border border-gray-100">
|
||||
|
||||
|
||||
|
||||
<!-- BLAST -->
|
||||
|
||||
<div class="group bg-white rounded-3xl shadow-lg hover:shadow-2xl hover:-translate-y-2 transition-all duration-300 overflow-hidden border">
|
||||
|
||||
|
||||
<div class="relative overflow-hidden">
|
||||
<img src="https://images.unsplash.com/photo-1592982537447-6f2a6a0f4d4d?q=80&w=1200&auto=format&fit=crop" class="h-56 w-full object-cover group-hover:scale-110 transition-transform duration-700">
|
||||
<div class="absolute top-4 right-4 bg-white/90 backdrop-blur-sm px-3 py-1 rounded-full text-xs font-bold text-red-600 shadow-sm">Bahaya</div>
|
||||
</div>
|
||||
<div class="p-6">
|
||||
<h3 class="text-2xl font-bold text-gray-800 mb-3 group-hover:text-red-600 transition-colors">Blast</h3>
|
||||
<p class="text-gray-500 text-sm leading-relaxed">Penyakit akibat jamur yang menyerang daun padi, ditandai dengan bercak belah ketupat.</p>
|
||||
</div>
|
||||
|
||||
|
||||
<img
|
||||
src="{{ asset('images/blast.jpg') }}"
|
||||
class="h-56 w-full object-cover group-hover:scale-110 transition-transform duration-700"
|
||||
>
|
||||
|
||||
|
||||
<div class="absolute top-4 right-4 bg-white/90 px-3 py-1 rounded-full text-xs font-bold text-red-600">
|
||||
|
||||
Bahaya
|
||||
|
||||
</div>
|
||||
|
||||
<div class="group bg-white rounded-3xl shadow-lg hover:shadow-2xl hover:-translate-y-2 transition-all duration-300 overflow-hidden border border-gray-100">
|
||||
<div class="relative overflow-hidden">
|
||||
<img src="https://images.unsplash.com/photo-1500382017468-9049fed747ef?q=80&w=1200&auto=format&fit=crop" class="h-56 w-full object-cover group-hover:scale-110 transition-transform duration-700">
|
||||
<div class="absolute top-4 right-4 bg-white/90 backdrop-blur-sm px-3 py-1 rounded-full text-xs font-bold text-yellow-600 shadow-sm">Waspada</div>
|
||||
</div>
|
||||
<div class="p-6">
|
||||
<h3 class="text-2xl font-bold text-gray-800 mb-3 group-hover:text-yellow-600 transition-colors">Blight</h3>
|
||||
<p class="text-gray-500 text-sm leading-relaxed">Hawar daun bakteri yang menyebabkan daun menguning, mengering, dan mati dari ujungnya.</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="group bg-white rounded-3xl shadow-lg hover:shadow-2xl hover:-translate-y-2 transition-all duration-300 overflow-hidden border border-gray-100">
|
||||
<div class="relative overflow-hidden">
|
||||
<img src="https://images.unsplash.com/photo-1464226184884-fa280b87c399?q=80&w=1200&auto=format&fit=crop" class="h-56 w-full object-cover group-hover:scale-110 transition-transform duration-700">
|
||||
<div class="absolute top-4 right-4 bg-white/90 backdrop-blur-sm px-3 py-1 rounded-full text-xs font-bold text-orange-500 shadow-sm">Virus</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="p-6">
|
||||
<h3 class="text-2xl font-bold text-gray-800 mb-3 group-hover:text-orange-500 transition-colors">Tungro</h3>
|
||||
<p class="text-gray-500 text-sm leading-relaxed">Penyakit virus yang ditularkan wereng hijau, menyebabkan tanaman kerdil dan daun kuning-oranye.</p>
|
||||
</div>
|
||||
|
||||
|
||||
<h3 class="text-2xl font-bold text-gray-800 mb-3">
|
||||
|
||||
Blast
|
||||
|
||||
</h3>
|
||||
|
||||
|
||||
|
||||
<p class="text-gray-500 text-sm leading-relaxed">
|
||||
|
||||
Penyakit daun padi yang disebabkan oleh jamur
|
||||
<b>Pyricularia oryzae</b> dengan gejala bercak berbentuk belah ketupat.
|
||||
|
||||
</p>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="group bg-white rounded-3xl shadow-lg hover:shadow-2xl hover:-translate-y-2 transition-all duration-300 overflow-hidden border border-gray-100">
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- BLIGHT -->
|
||||
|
||||
|
||||
<div class="group bg-white rounded-3xl shadow-lg hover:shadow-2xl hover:-translate-y-2 transition-all duration-300 overflow-hidden border">
|
||||
|
||||
|
||||
<div class="relative overflow-hidden">
|
||||
<img src="https://images.unsplash.com/photo-1472396961693-142e6e269027?q=80&w=1200&auto=format&fit=crop" class="h-56 w-full object-cover group-hover:scale-110 transition-transform duration-700">
|
||||
<div class="absolute top-4 right-4 bg-white/90 backdrop-blur-sm px-3 py-1 rounded-full text-xs font-bold text-green-600 shadow-sm">Aman</div>
|
||||
|
||||
|
||||
<img
|
||||
src="{{ asset('images/blight.jpg') }}"
|
||||
class="h-56 w-full object-cover group-hover:scale-110 transition-transform duration-700"
|
||||
>
|
||||
|
||||
|
||||
|
||||
<div class="absolute top-4 right-4 bg-white/90 px-3 py-1 rounded-full text-xs font-bold text-yellow-600">
|
||||
|
||||
Waspada
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="p-6">
|
||||
<h3 class="text-2xl font-bold text-gray-800 mb-3 group-hover:text-green-600 transition-colors">Healthy</h3>
|
||||
<p class="text-gray-500 text-sm leading-relaxed">Daun padi sehat tanpa gejala penyakit. Memiliki warna hijau merata dan tekstur normal.</p>
|
||||
|
||||
|
||||
<h3 class="text-2xl font-bold text-gray-800 mb-3">
|
||||
|
||||
Blight
|
||||
|
||||
</h3>
|
||||
|
||||
|
||||
|
||||
<p class="text-gray-500 text-sm leading-relaxed">
|
||||
|
||||
Penyakit hawar daun bakteri yang menyebabkan daun padi
|
||||
menguning, layu, dan mengalami kerusakan.
|
||||
|
||||
</p>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- TUNGRO -->
|
||||
|
||||
|
||||
<div class="group bg-white rounded-3xl shadow-lg hover:shadow-2xl hover:-translate-y-2 transition-all duration-300 overflow-hidden border">
|
||||
|
||||
|
||||
<div class="relative overflow-hidden">
|
||||
|
||||
|
||||
<img
|
||||
src="{{ asset('images/tungro.jpg') }}"
|
||||
class="h-56 w-full object-cover group-hover:scale-110 transition-transform duration-700"
|
||||
>
|
||||
|
||||
|
||||
|
||||
<div class="absolute top-4 right-4 bg-white/90 px-3 py-1 rounded-full text-xs font-bold text-orange-500">
|
||||
|
||||
Virus
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="p-6">
|
||||
|
||||
|
||||
<h3 class="text-2xl font-bold text-gray-800 mb-3">
|
||||
|
||||
Tungro
|
||||
|
||||
</h3>
|
||||
|
||||
|
||||
|
||||
|
||||
<p class="text-gray-500 text-sm leading-relaxed">
|
||||
|
||||
Penyakit yang disebabkan oleh virus dan ditularkan oleh wereng hijau.
|
||||
Gejalanya berupa daun menguning dan pertumbuhan tanaman terhambat.
|
||||
|
||||
</p>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- HEALTHY -->
|
||||
|
||||
|
||||
<div class="group bg-white rounded-3xl shadow-lg hover:shadow-2xl hover:-translate-y-2 transition-all duration-300 overflow-hidden border">
|
||||
|
||||
|
||||
|
||||
<div class="relative overflow-hidden">
|
||||
|
||||
|
||||
<img
|
||||
src="{{ asset('images/healthy.jpg') }}"
|
||||
class="h-56 w-full object-cover group-hover:scale-110 transition-transform duration-700"
|
||||
>
|
||||
|
||||
|
||||
|
||||
<div class="absolute top-4 right-4 bg-white/90 px-3 py-1 rounded-full text-xs font-bold text-green-600">
|
||||
|
||||
Aman
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="p-6">
|
||||
|
||||
|
||||
<h3 class="text-2xl font-bold text-gray-800 mb-3">
|
||||
|
||||
Healthy
|
||||
|
||||
</h3>
|
||||
|
||||
|
||||
|
||||
|
||||
<p class="text-gray-500 text-sm leading-relaxed">
|
||||
|
||||
Kondisi daun padi sehat dengan warna hijau normal,
|
||||
tidak ditemukan tanda penyakit.
|
||||
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
</div>
|
||||
|
|
@ -261,7 +467,7 @@ class="relative rounded-3xl shadow-2xl border-4 border-white transform hover:sca
|
|||
<div class="absolute inset-4 rounded-full border-b-4 border-yellow-400 animate-spin"></div>
|
||||
</div>
|
||||
<h2 class="text-2xl font-extrabold text-gray-800 mb-2">Menganalisis...</h2>
|
||||
<p class="text-gray-500 font-medium">AI sedang memproses gambar Anda.</p>
|
||||
<p class="text-gray-500 font-medium">sedang memproses gambar Anda.</p>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
|
|
|||
Loading…
Reference in New Issue