rafhiromadoni commited on
Commit
c4d33b3
ยท
verified ยท
1 Parent(s): d40d404

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +84 -77
app.py CHANGED
@@ -3,119 +3,126 @@ from ultralytics import YOLO
3
  import pandas as pd
4
  import datetime
5
  import os
6
- import cv2
7
- from PIL import Image
8
 
9
- # 1. KONFIGURASI MODEL & DATABASE
10
  MODEL_PATH = 'yolov8n.pt'
11
  DB_FILE = 'inventory_log.csv'
12
-
13
- # Inisialisasi Model
14
  model = YOLO(MODEL_PATH)
15
 
16
- # 2. FUNGSI DATABASE
17
- def save_to_database(df_results):
18
- """Menyimpan hasil deteksi ke file CSV lokal di server Hugging Face"""
19
- if df_results.empty:
20
- return "Tidak ada data untuk disimpan."
 
 
 
 
 
 
 
 
 
 
21
 
22
- file_exists = os.path.isfile(DB_FILE)
23
 
24
- # Tambahkan Timestamp untuk setiap baris data
25
- df_results['Timestamp'] = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
 
27
- # Simpan/Append ke CSV
28
- df_results.to_csv(DB_FILE, mode='a', index=False, header=not file_exists)
29
- return f"โœ… Database diperbarui: {datetime.datetime.now().strftime('%H:%M:%S')}"
30
 
31
- # 3. FUNGSI UTAMA (DETEKSI & PROSES)
32
  def process_inventory(img):
33
  if img is None:
34
- return None, None, "โš ๏ธ Silakan unggah foto.", None
35
 
36
- # --- Tahap 1: Deteksi AI ---
37
  results = model(img)
38
- res_plotted = results[0].plot() # Gambar hasil deteksi
39
 
40
- # --- Tahap 2: Ekstraksi Data ---
41
  detections = results[0].boxes.cls.tolist()
42
  names = model.names
43
  counts = {}
44
-
45
  for class_id in detections:
46
  name = names[int(class_id)]
47
  counts[name] = counts.get(name, 0) + 1
48
 
49
- # --- Tahap 3: Persiapan Tabel & Logika Bisnis ---
50
  inventory_list = []
51
- if counts:
52
- for item, count in counts.items():
53
- # Simulasi Threshold: Jika di bawah 5, tandai sebagai Low Stock
54
- status = "โœ… STOK AMAN" if count >= 5 else "๐Ÿšจ LOW STOCK"
55
- inventory_list.append({
56
- "Barang": item.upper(),
57
- "Jumlah": count,
58
- "Status": status
59
- })
60
 
61
  df_inventory = pd.DataFrame(inventory_list)
62
 
63
- # --- Tahap 4: Update Database ---
64
- db_status = save_to_database(df_inventory.copy())
 
 
65
 
66
- # Jika tabel kosong
67
- if df_inventory.empty:
68
- return res_plotted, None, "โ„น๏ธ Tidak ada objek logistik terdeteksi.", None
69
-
70
- # Return: Gambar, Tabel, Pesan Status, dan Path File CSV untuk diunduh
71
- return res_plotted, df_inventory, db_status, DB_FILE
72
 
73
- # 4. ANTARMUKA GRADIO (DASHBOARD UI)
74
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
75
- gr.Markdown("""
76
- <div style="text-align: center;">
77
- <h1>๐Ÿ™๏ธ IntelliStock AI: Warehouse Management System</h1>
78
- <p>Solusi <b>Computer Vision</b> untuk otomasi inventarisasi dan monitoring stok real-time.</p>
79
- </div>
80
- """)
81
 
82
- with gr.Row():
83
- # Kolom Kiri: Kontrol & Input
84
- with gr.Column(scale=1):
85
- gr.Markdown("### ๐Ÿ“ธ Input Visual")
86
- input_img = gr.Image(type="numpy", label="Upload Foto Gudang/Rak")
87
-
88
- with gr.Row():
89
- clear_btn = gr.Button("๐Ÿ—‘๏ธ Clear", variant="secondary")
90
- scan_btn = gr.Button("๐Ÿ” Run AI Scan", variant="primary")
91
-
92
- gr.Markdown("---")
93
- gr.Markdown("### ๐Ÿ“ฅ Laporan Database")
94
- db_msg = gr.Markdown("*Belum ada aktivitas scan*")
95
- output_file = gr.File(label="Download Full Inventory Log (CSV)")
96
 
97
- # Kolom Kanan: Hasil AI
98
- with gr.Column(scale=2):
99
- gr.Markdown("### ๐Ÿ•ต๏ธ AI Detection Result")
100
- output_img = gr.Image(label="Annotated Warehouse View")
101
-
102
- gr.Markdown("### ๐Ÿ“ˆ Tabel Inventaris Terdeteksi")
103
- output_table = gr.Dataframe(
104
- headers=["Barang", "Jumlah", "Status"],
105
- label="Current Scan Report",
106
- interactive=False
107
- )
108
 
109
- # Definisi Interaksi
110
  scan_btn.click(
111
  fn=process_inventory,
112
  inputs=input_img,
113
- outputs=[output_img, output_table, db_msg, output_file]
114
  )
115
 
116
- clear_btn.click(lambda: (None, None, "*Aktivitas dibersihkan*", None),
117
- outputs=[input_img, output_img, db_msg, output_file])
118
 
119
- # 5. RUN APP
120
  if __name__ == "__main__":
121
  demo.launch()
 
3
  import pandas as pd
4
  import datetime
5
  import os
6
+ import numpy as np
7
+ import matplotlib.pyplot as plt
8
 
9
+ # 1. KONFIGURASI
10
  MODEL_PATH = 'yolov8n.pt'
11
  DB_FILE = 'inventory_log.csv'
 
 
12
  model = YOLO(MODEL_PATH)
13
 
14
+ # 2. FUNGSI FORECASTING (PREDIKSI)
15
+ def predict_demand():
16
+ if not os.path.isfile(DB_FILE):
17
+ return "โš ๏ธ Data histori belum cukup untuk prediksi.", None
18
+
19
+ df = pd.read_csv(DB_FILE)
20
+ if len(df) < 3: # Butuh minimal 3 data point untuk melihat tren
21
+ return "โš ๏ธ Butuh minimal 3 kali scan untuk menghitung tren prediksi.", None
22
+
23
+ # Kelompokkan data berdasarkan barang dan hitung rata-rata jumlah per hari
24
+ df['Timestamp'] = pd.to_datetime(df['Timestamp'])
25
+ df['Date_Ordinal'] = df['Timestamp'].apply(lambda x: x.toordinal())
26
+
27
+ forecast_results = "### ๐Ÿ”ฎ Prediksi Ketersediaan Stok:\n"
28
+ items = df['Barang'].unique()
29
 
30
+ fig, ax = plt.subplots(figsize=(8, 4))
31
 
32
+ for item in items:
33
+ item_df = df[df['Barang'] == item].sort_values('Timestamp')
34
+ X = item_df['Date_Ordinal'].values.reshape(-1, 1)
35
+ y = item_df['Jumlah'].values
36
+
37
+ # Linear Regression Sederhana (Slope & Intercept)
38
+ if len(y) > 1:
39
+ slope, intercept = np.polyfit(X.flatten(), y, 1)
40
+
41
+ # Jika tren menurun (slope negatif)
42
+ if slope < 0:
43
+ days_left = int(-intercept / slope) - datetime.date.today().toordinal()
44
+ days_left = max(0, days_left)
45
+ forecast_results += f"- **{item}**: Diperkirakan habis dalam **{days_left} hari**.\n"
46
+ else:
47
+ forecast_results += f"- **{item}**: Stok cenderung stabil/meningkat.\n"
48
+
49
+ # Plotting histori
50
+ ax.plot(item_df['Timestamp'], item_df['Jumlah'], marker='o', label=f"Tren {item}")
51
+
52
+ ax.set_title("Grafik Perubahan Stok Barang")
53
+ ax.set_ylabel("Jumlah Unit")
54
+ ax.legend()
55
+ plt.xticks(rotation=45)
56
+ plt.tight_layout()
57
 
58
+ return forecast_results, fig
 
 
59
 
60
+ # 3. FUNGSI UTAMA (INTEGRASI SCAN)
61
  def process_inventory(img):
62
  if img is None:
63
+ return None, None, "โš ๏ธ Unggah foto.", None, "Silakan scan dulu.", None
64
 
 
65
  results = model(img)
66
+ res_plotted = results[0].plot()
67
 
 
68
  detections = results[0].boxes.cls.tolist()
69
  names = model.names
70
  counts = {}
 
71
  for class_id in detections:
72
  name = names[int(class_id)]
73
  counts[name] = counts.get(name, 0) + 1
74
 
 
75
  inventory_list = []
76
+ for item, count in counts.items():
77
+ status = "โœ… AMAN" if count >= 5 else "๐Ÿšจ LOW STOCK"
78
+ inventory_list.append({"Barang": item.upper(), "Jumlah": count, "Status": status, "Timestamp": datetime.datetime.now()})
 
 
 
 
 
 
79
 
80
  df_inventory = pd.DataFrame(inventory_list)
81
 
82
+ # Save to Database
83
+ if not df_inventory.empty:
84
+ file_exists = os.path.isfile(DB_FILE)
85
+ df_inventory.to_csv(DB_FILE, mode='a', index=False, header=not file_exists)
86
 
87
+ # Jalankan Forecasting setelah scan
88
+ forecast_text, forecast_plot = predict_demand()
89
+
90
+ return res_plotted, df_inventory, "โœ… Database Updated!", DB_FILE, forecast_text, forecast_plot
 
 
91
 
92
+ # 4. UI GRADIO (TABBED INTERFACE)
93
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
94
+ gr.Markdown("# ๐Ÿ™๏ธ IntelliStock AI: End-to-End Warehouse Intelligence")
 
 
 
 
 
95
 
96
+ with gr.Tab("๐Ÿ“ธ Scan & Monitoring"):
97
+ with gr.Row():
98
+ with gr.Column():
99
+ input_img = gr.Image(type="numpy", label="Input Camera/Upload")
100
+ scan_btn = gr.Button("๐Ÿ” Run AI Scan & Update", variant="primary")
101
+ with gr.Column():
102
+ output_img = gr.Image(label="Visual Detection")
103
+ output_table = gr.Dataframe(label="Current Inventory")
104
+
105
+ with gr.Row():
106
+ output_file = gr.File(label="๐Ÿ“ฅ Download Database (CSV)")
107
+ db_status = gr.Markdown()
 
 
108
 
109
+ with gr.Tab("๐Ÿ”ฎ Demand Forecasting"):
110
+ gr.Markdown("### Analisis Prediksi Stok Berdasarkan Histori")
111
+ with gr.Row():
112
+ with gr.Column():
113
+ forecast_output_text = gr.Markdown("Lakukan minimal 3x scan untuk melihat prediksi.")
114
+ with gr.Column():
115
+ forecast_output_plot = gr.Plot(label="Grafik Tren Stok")
116
+ refresh_btn = gr.Button("๐Ÿ”„ Refresh Analisis Prediksi")
 
 
 
117
 
118
+ # Click Events
119
  scan_btn.click(
120
  fn=process_inventory,
121
  inputs=input_img,
122
+ outputs=[output_img, output_table, db_status, output_file, forecast_output_text, forecast_output_plot]
123
  )
124
 
125
+ refresh_btn.click(fn=predict_demand, outputs=[forecast_output_text, forecast_output_plot])
 
126
 
 
127
  if __name__ == "__main__":
128
  demo.launch()