Spaces:
Sleeping
Sleeping
| 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 | |
| def index(): | |
| try: | |
| return render_template('index.html') | |
| except Exception: | |
| return send_from_directory(BASE_DIR, 'index.html') | |
| 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) |