File size: 4,107 Bytes
1a572c9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
edc6096
1a572c9
 
 
 
 
 
 
 
 
 
 
fccf0b8
1a572c9
 
 
 
 
 
 
 
 
 
 
 
 
 
8668cea
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
import io
import os
from dotenv import load_dotenv
import numpy as np
from flask import Flask, jsonify, render_template, request, send_from_directory
from PIL import Image
import tensorflow as tf
from tensorflow.keras.preprocessing import image
from model import Conv2DBatchNMaxP, Conv2DModel
from google import genai

# Cara membuat file .env:
# 1. Buat file bernama ".env" di folder proyek (sama dengan app.py).
# 2. Tambahkan baris: GENAI_API_KEY=your_api_key_here
# 3. Jangan commit .env ke repositori (tambahkan ke .gitignore).
load_dotenv()

GENAI_API_KEY = os.getenv('GENAI_API_KEY')
if not GENAI_API_KEY:
    print('Peringatan: GENAI_API_KEY tidak ditemukan di environment')

client = genai.Client(api_key=GENAI_API_KEY)

CLASS_NAMES = [
    'Apple___Apple_scab', 'Apple___Black_rot', 'Apple___Cedar_apple_rust', 'Apple___healthy',
    'Blueberry___healthy', 'Cherry_(including_sour)___Powdery_mildew', 'Cherry_(including_sour)___healthy',
    'Corn_(maize)___Cercospora_leaf_spot Gray_leaf_spot', 'Corn_(maize)___Common_rust_',
    'Corn_(maize)___Northern_Leaf_Blight', 'Corn_(maize)___healthy', 'Grape___Black_rot',
    'Grape___Esca_(Black_Measles)', 'Grape___Leaf_blight_(Isariopsis_Leaf_Spot)', 'Grape___healthy',
    'Orange___Haunglongbing_(Citrus_greening)', 'Peach___Bacterial_spot', 'Peach___healthy',
    'Pepper,_bell___Bacterial_spot', 'Pepper,_bell___healthy', 'Potato___Early_blight',
    'Potato___Late_blight', 'Potato___healthy', 'Raspberry___healthy', 'Soybean___healthy',
    'Squash___Powdery_mildew', 'Strawberry___Leaf_scorch', 'Strawberry___healthy',
    'Tomato___Bacterial_spot', 'Tomato___Early_blight', 'Tomato___Late_blight',
    'Tomato___Leaf_Mold', 'Tomato___Septoria_leaf_spot',
    'Tomato___Spider_mites Two-spotted_spider_mite', 'Tomato___Target_Spot',
    'Tomato___Tomato_Yellow_Leaf_Curl_Virus', 'Tomato___Tomato_mosaic_virus',
    'Tomato___healthy', 'test'
]

BASE_DIR = os.path.dirname(os.path.abspath(__file__))
MODEL_PATH = os.path.join(BASE_DIR, 'model.keras')

model = None
try:
    model = tf.keras.models.load_model(
        MODEL_PATH,
        custom_objects={'Conv2DBatchNMaxP': Conv2DBatchNMaxP, 'Conv2DModel': Conv2DModel},
        compile=False
    )
    model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
    print(f"Model loaded: {MODEL_PATH}")
except Exception as e:
    print(f"Failed to load model: {e}")

app = Flask(__name__)


def preprocess_image(image_file, target_size=(150, 150)):
    img = Image.open(io.BytesIO(image_file.read())).convert('L').resize(target_size)
    img_array = image.img_to_array(img)
    img_array = np.expand_dims(img_array, axis=0) / 255.0
    return img_array


@app.route('/', methods=['GET'])
def index():
    try:
        return render_template('index.html')
    except Exception:
        return send_from_directory(BASE_DIR, 'index.html')


@app.route('/predict', methods=['POST'])
def predict():
    if model is None:
        print(f"Model = {model}")
        return jsonify({'error': 'Model belum dimuat'}), 500

    if 'file' not in request.files or request.files['file'].filename == '':
        return jsonify({'error': 'Tidak ada file gambar yang diunggah'}), 400

    try:
        processed_image = preprocess_image(request.files['file'])
        predictions = model.predict(processed_image)
        idx = np.argmax(predictions, axis=1)[0]
        prompt = f"Tolong berikan penjelasan tentang penyakit tanaman {CLASS_NAMES[idx]}. Dan berikan solusinya"
        response = client.models.generate_content(
            model="gemini-2.5-flash",
            contents=prompt
        )
        print(response.text)
        return jsonify({
            'predicted_class': CLASS_NAMES[idx],
            'confidence': f"{predictions[0][idx] * 100:.2f}%",
            '':response.text
        })
    except Exception as e:
        print(f"Error: {e}")
        return jsonify({'error': f'Gagal memproses gambar: {str(e)}'}), 500


if __name__ == '__main__':
    # Wajib host 0.0.0.0 dan port 7860 untuk Hugging Face Space
    app.run(host='0.0.0.0', port=7860, debug=False)