kazakiakayami/Weed-Detection-Computer-Vision-GC7
0
1import os2os.environ["TF_USE_LEGACY_KERAS"] = "1" # ← HARUS sebelum import tensorflow3 4import streamlit as st5import numpy as np6import tensorflow as tf7import cv28from PIL import Image9from tensorflow.keras.models import load_model10from tensorflow.keras.models import Model11from huggingface_hub import hf_hub_download12 13 14# ── Page Config ───────────────────────────────────────────────────15st.set_page_config(16 page_title="Weed Detector",17 page_icon="🌿",18 layout="centered"19)20 21# ── Load Model ────────────────────────────────────────────────────22@st.cache_resource # ← cache supaya model tidak reload tiap interaksi23def load_inference_model():24 from keras.applications.vgg16 import VGG1625 26 # Rebuild arsitektur persis sama seperti di notebook27 pretrained_model_vgg16 = VGG16(28 weights=None, # tidak load weights imagenet29 include_top=False,30 input_shape=(224, 224, 3)31 )32 pretrained_model_vgg16.trainable = False33 34 model = tf.keras.Sequential([35 pretrained_model_vgg16,36 tf.keras.layers.Flatten(),37 tf.keras.layers.Dense(512, activation='relu'),38 tf.keras.layers.Dense(1, activation='sigmoid')39 ])40 41 model.compile(42 loss='binary_crossentropy',43 optimizer='adam',44 metrics=['accuracy']45 )46 47 # Load weights saja dari file .h548 model_path = hf_hub_download(49 repo_id="kazakiakayami/Computer-Vision-GC7",50 filename="best_model_weights.weights.h5"51 )52 model.load_weights(model_path)53 54 return model55 56# ── Helper Functions ──────────────────────────────────────────────57def preprocess_image(img, img_size=(224, 224)):58 img = img.convert('RGB')59 img = img.resize(img_size)60 img_array = np.array(img) / 255.061 img_array = np.expand_dims(img_array, axis=0)62 return img_array63 64def predict_flower(img, model, low_threshold=0.25, high_threshold=0.75):65 img_array = preprocess_image(img)66 prob = model.predict(img_array)[0][0]67 68 if prob <= low_threshold:69 class_name = 'Daisy'70 confidence = 1 - prob71 weed_status = 'Weed'72 elif prob >= high_threshold:73 class_name = 'Dandelion'74 confidence = prob75 weed_status = 'Weed'76 else:77 class_name = 'Unknown'78 confidence = None79 weed_status = 'Not a Weed'80 81 return class_name, round(float(confidence), 4) if confidence else None, weed_status82 83def make_gradcam(img, model):84 vgg16_layer = model.get_layer('vgg16')85 dense_layer = model.get_layer('dense')86 dense1_layer = model.get_layer('dense_1')87 88 grad_model = Model(89 inputs=vgg16_layer.input,90 outputs=[91 vgg16_layer.get_layer('block5_conv3').output,92 vgg16_layer.output93 ]94 )95 96 img_array = preprocess_image(img)97 img_tensor = tf.cast(img_array, tf.float32)98 99 with tf.GradientTape() as tape:100 conv_outputs, vgg_out = grad_model(img_tensor)101 tape.watch(conv_outputs)102 x = tf.reshape(vgg_out, [tf.shape(vgg_out)[0], -1])103 x = dense_layer(x)104 predictions = dense1_layer(x)105 pred_index = tf.argmax(predictions[0])106 class_channel = predictions[:, pred_index]107 108 grads = tape.gradient(class_channel, conv_outputs)109 pooled_grads = tf.reduce_mean(grads, axis=(0, 1, 2))110 conv_out = conv_outputs[0]111 heatmap = conv_out @ pooled_grads[..., tf.newaxis]112 heatmap = tf.squeeze(heatmap)113 heatmap = tf.maximum(heatmap, 0)114 heatmap = heatmap / (tf.math.reduce_max(heatmap) + 1e-8)115 heatmap = heatmap.numpy()116 117 # Overlay ke gambar asli118 img_cv = cv2.cvtColor(np.array(img), cv2.COLOR_RGB2BGR)119 heatmap_resized = cv2.resize(heatmap, (img_cv.shape[1], img_cv.shape[0]))120 heatmap_colored = cv2.applyColorMap(np.uint8(255 * heatmap_resized), cv2.COLORMAP_JET)121 superimposed = cv2.addWeighted(img_cv, 0.6, heatmap_colored, 0.4, 0)122 superimposed = cv2.cvtColor(superimposed, cv2.COLOR_BGR2RGB)123 124 return superimposed125 126# ── UI ────────────────────────────────────────────────────────────127st.title("🌿 Weed Detector")128st.write("Upload a flower image to detect whether it is a weed or not.")129st.markdown("---")130 131model = load_inference_model()132uploaded_file = st.file_uploader(133 "Choose a flower image",134 type=["jpg", "jpeg", "png"]135)136 137if uploaded_file is not None:138 img = Image.open(uploaded_file)139 140 with st.spinner("Analyzing image..."):141 class_name, confidence, weed_status = predict_flower(img, model)142 gradcam_img = make_gradcam(img, model)143 144 # ── Result ────────────────────────────────────────────────────145 st.markdown("---")146 147 col1, col2 = st.columns(2)148 with col1:149 st.subheader("Original Image")150 st.image(img, use_container_width=True)151 with col2:152 st.subheader("Grad-CAM Attention")153 st.image(gradcam_img, use_container_width=True)154 155 st.markdown("---")156 157 # Prediction result158 conf_text = f"{confidence * 100:.2f}%" if confidence else "N/A"159 160 if weed_status == 'Not a Weed ✅':161 st.success(f"**Predicted:** {class_name} | **Confidence:** {conf_text} | **Status:** {weed_status}")162 else:163 st.error(f"**Predicted:** {class_name} | **Confidence:** {conf_text} | **Status:** {weed_status}")