Ferdinann commited on
Commit
63cc014
·
verified ·
1 Parent(s): ce1ca74

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +46 -44
app.py CHANGED
@@ -4,10 +4,10 @@ import numpy as np
4
  from PIL import Image
5
 
6
  # --- KONFIGURASI ---
7
- IMG_SIZE = (224, 224) # Sesuaikan dengan input shape model Anda
8
- MODEL_PATH = "best_model.h5" # Pastikan nama file sesuai
9
 
10
- # Definisi Kelas (Sesuai urutan training model Anda)
11
  class_names = [
12
  'Abrasions', 'Bruises', 'Burns', 'Cut', 'Diabetic Wounds',
13
  'Laceration', 'Normal', 'Pressure Wounds', 'Surgical Wounds', 'Venous Wounds'
@@ -97,86 +97,88 @@ def get_first_aid_recommendation(wound_class):
97
  }
98
  return rekomendasi.get(wound_class, "Rekomendasi belum tersedia. Silakan konsultasi dengan petugas medis.")
99
 
100
- # --- FUNGSI PREDIKSI ---
101
- def predict_image(image_input):
102
- if best_model is None:
103
- return {}, "⚠️ Model tidak ditemukan. Harap upload file model (.h5)."
 
 
 
 
 
 
 
 
 
 
 
104
 
 
 
 
105
  if image_input is None:
106
- return {}, "Silakan upload gambar."
107
 
108
- # Preprocessing
 
 
 
109
  img = image_input.resize(IMG_SIZE)
110
- img_array = tf.keras.utils.img_to_array(img)
111
  img_array = tf.expand_dims(img_array, 0)
112
- img_array = img_array / 255.0
113
-
114
- # Prediksi
115
  predictions = best_model.predict(img_array)
116
  scores = tf.nn.softmax(predictions[0]).numpy()
117
 
118
- # Mapping hasil untuk UI (Bahasa Indonesia)
119
  translated_output_dict = {
120
  translation_map.get(class_names[i], class_names[i]): float(scores[i])
121
  for i in range(len(class_names))
122
  }
123
 
124
- # Ambil label tertinggi
125
  top_idx = np.argmax(scores)
126
  top_label_en = class_names[top_idx]
127
  top_confidence = scores[top_idx]
128
 
129
- # --- LOGIKA THRESHOLD ---
130
  THRESHOLD = 0.20
131
-
132
  if top_confidence < THRESHOLD:
133
  top_label_id = "Normal (Tidak Terdeteksi)"
134
- rekomendasi_teks = (
135
- "**Mohon Maaf:** Model kurang akurat dalam menganalisis foto ini.\n\n"
136
- "**Saran:**\n"
137
- "1. Pastikan area luka terlihat jelas dan tidak blur.\n"
138
- "2. Gunakan pencahayaan yang cukup (terang).\n"
139
- "3. Ambil foto dari sudut tegak lurus ke arah luka.\n\n"
140
- "Jika Anda merasa luka ini serius, segera hubungi tenaga medis meskipun hasil analisis tidak muncul."
141
- )
142
  else:
143
  top_label_id = translation_map.get(top_label_en, top_label_en)
144
  rekomendasi_teks = get_first_aid_recommendation(top_label_en)
145
 
146
- # Format Markdown untuk Gradio
147
  formatted_output = (
148
  f"### Analisis: **{top_label_id}**\n\n"
149
  f"**Langkah Pertolongan:**\n{rekomendasi_teks}\n\n"
150
  f"--- \n*Tingkat Keyakinan AI: {top_confidence:.2%}*"
151
  )
152
-
153
- return translated_output_dict, formatted_output
154
 
155
  # --- UI INTERFACE ---
156
  with gr.Blocks(theme=gr.themes.Soft(primary_hue="red", secondary_hue="slate")) as demo:
157
  gr.Markdown("# 🚨 FirstAidLens")
158
- gr.Markdown("Deteksi jenis luka secara instan dan dapatkan panduan pertolongan pertama yang tepat.")
159
-
 
 
160
  with gr.Row():
161
  with gr.Column(scale=1):
162
- input_img = gr.Image(
163
- sources=["upload", "webcam"],
164
- type="pil",
165
- label="Ambil Foto Luka"
166
- )
167
- gr.Markdown("> **Penting:** Hasil AI ini hanya referensi awal. Jika luka parah atau pendarahan tidak berhenti, segera hubungi **112**.")
168
-
169
  with gr.Column(scale=1):
170
- output_label = gr.Label(num_top_classes=3, label="Hasil Analisis Jenis Luka")
171
- output_markdown = gr.Markdown("### Panduan Pertolongan Pertama\n_Upload atau ambil foto untuk melihat rekomendasi._")
 
172
 
173
- # Trigger otomatis saat gambar diupload/diambil
174
- input_img.change(
175
  fn=predict_image,
176
- inputs=input_img,
177
- outputs=[output_label, output_markdown]
 
178
  )
179
 
180
- # Launch (Server Name 0.0.0.0 wajib untuk Docker)
181
  if __name__ == "__main__":
182
  demo.launch(server_name="0.0.0.0", server_port=7860)
 
4
  from PIL import Image
5
 
6
  # --- KONFIGURASI ---
7
+ IMG_SIZE = (224, 224)
8
+ MODEL_PATH = "best_model.h5"
9
 
10
+ # Definisi Kelas (Sesuai urutan training model)
11
  class_names = [
12
  'Abrasions', 'Bruises', 'Burns', 'Cut', 'Diabetic Wounds',
13
  'Laceration', 'Normal', 'Pressure Wounds', 'Surgical Wounds', 'Venous Wounds'
 
97
  }
98
  return rekomendasi.get(wound_class, "Rekomendasi belum tersedia. Silakan konsultasi dengan petugas medis.")
99
 
100
+ # --- SCRIPT JAVASCRIPT UNTUK GPS ---
101
+ get_location_js = """
102
+ function getGeoLocation() {
103
+ return new Promise((resolve, reject) => {
104
+ navigator.geolocation.getCurrentPosition(
105
+ (position) => {
106
+ resolve(`${position.coords.latitude},${position.coords.longitude}`);
107
+ },
108
+ (error) => {
109
+ resolve("Lokasi tidak diizinkan");
110
+ }
111
+ );
112
+ });
113
+ }
114
+ """
115
 
116
+ def predict_image(image_input, location_data):
117
+ if best_model is None:
118
+ return {}, "⚠️ Model tidak ditemukan.", ""
119
  if image_input is None:
120
+ return {}, "Silakan upload gambar.", ""
121
 
122
+ # Info Lokasi
123
+ info_lokasi = f"📍 **Koordinat Pengunggahan:** {location_data}" if location_data else "📍 Lokasi tidak terdeteksi."
124
+
125
+ # Preprocessing & Prediksi
126
  img = image_input.resize(IMG_SIZE)
127
+ img_array = tf.keras.utils.img_to_array(img) / 255.0
128
  img_array = tf.expand_dims(img_array, 0)
129
+
 
 
130
  predictions = best_model.predict(img_array)
131
  scores = tf.nn.softmax(predictions[0]).numpy()
132
 
 
133
  translated_output_dict = {
134
  translation_map.get(class_names[i], class_names[i]): float(scores[i])
135
  for i in range(len(class_names))
136
  }
137
 
 
138
  top_idx = np.argmax(scores)
139
  top_label_en = class_names[top_idx]
140
  top_confidence = scores[top_idx]
141
 
 
142
  THRESHOLD = 0.20
 
143
  if top_confidence < THRESHOLD:
144
  top_label_id = "Normal (Tidak Terdeteksi)"
145
+ rekomendasi_teks = "Model kurang akurat. Pastikan foto jelas."
 
 
 
 
 
 
 
146
  else:
147
  top_label_id = translation_map.get(top_label_en, top_label_en)
148
  rekomendasi_teks = get_first_aid_recommendation(top_label_en)
149
 
 
150
  formatted_output = (
151
  f"### Analisis: **{top_label_id}**\n\n"
152
  f"**Langkah Pertolongan:**\n{rekomendasi_teks}\n\n"
153
  f"--- \n*Tingkat Keyakinan AI: {top_confidence:.2%}*"
154
  )
155
+
156
+ return translated_output_dict, formatted_output, info_lokasi
157
 
158
  # --- UI INTERFACE ---
159
  with gr.Blocks(theme=gr.themes.Soft(primary_hue="red", secondary_hue="slate")) as demo:
160
  gr.Markdown("# 🚨 FirstAidLens")
161
+
162
+ # Input tersembunyi untuk menampung data dari JS
163
+ location_hidden = gr.Textbox(visible=False)
164
+
165
  with gr.Row():
166
  with gr.Column(scale=1):
167
+ input_img = gr.Image(sources=["upload", "webcam"], type="pil", label="Ambil Foto Luka")
168
+ btn_predict = gr.Button("Analisis Luka & Ambil Lokasi", variant="primary")
169
+
 
 
 
 
170
  with gr.Column(scale=1):
171
+ output_label = gr.Label(num_top_classes=3, label="Hasil Analisis")
172
+ output_markdown = gr.Markdown("### Panduan Pertolongan Pertama")
173
+ output_location = gr.Markdown("") # Menampilkan lokasi di sini
174
 
175
+ # Alur Klik: Jalankan JS dulu untuk isi location_hidden, lalu jalankan predict_image
176
+ btn_predict.click(
177
  fn=predict_image,
178
+ inputs=[input_img, location_hidden],
179
+ outputs=[output_label, output_markdown, output_location],
180
+ js=get_location_js
181
  )
182
 
 
183
  if __name__ == "__main__":
184
  demo.launch(server_name="0.0.0.0", server_port=7860)