thanhhiepvos commited on
Commit
28037b0
·
verified ·
1 Parent(s): 384beeb

Upload 10 files

Browse files
app.py ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import os
3
+
4
+ from core.ui import show_choosing_pic_bar, show_right_sidebar
5
+ from core.model import load_model, run_yolo_inference
6
+ from core.helpers import get_image_list, show_note_for_classes, show_hyperparameters
7
+
8
+ def main():
9
+ st.set_page_config(layout="wide")
10
+ st.title("Vietnam Traffic Sign Deployment")
11
+
12
+ model = load_model()
13
+ st.success("Model load successfully!")
14
+
15
+ # Left sidebar for image selection
16
+ images = get_image_list()
17
+ img_folder = "test_dataset/images"
18
+ show_choosing_pic_bar(images, img_folder)
19
+
20
+ if "selected_image" in st.session_state:
21
+ selected_image = os.path.join(img_folder, st.session_state.selected_image)
22
+
23
+ st.subheader("🖼️ Selected Image")
24
+ st.image(selected_image, caption=f"Original Image {st.session_state.selected_image}", use_container_width=True)
25
+
26
+ # Now create 2 columns below the Selected Image
27
+ middle_part, right_bar = st.columns([4, 1], gap="large")
28
+
29
+ # Right sidebar for thresholds
30
+ conf_threshold, iou_threshold, conf_show = show_right_sidebar(right_bar)
31
+
32
+ with middle_part:
33
+ st.subheader("🔍 Detection Result")
34
+ detected_img, classes_with_conf = run_yolo_inference(model, selected_image, conf_threshold, iou_threshold, conf_show)
35
+ st.image(detected_img, caption="Detected Objects", use_container_width=True)
36
+
37
+ show_hyperparameters(conf_threshold, iou_threshold)
38
+ show_note_for_classes(classes_with_conf)
39
+
40
+ if __name__ == "__main__":
41
+ main()
classes/classes.txt ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ W.224
2
+ W.205c
3
+ P.102
4
+ R.302a
5
+ W.205a
6
+ W.207
7
+ W.201a
8
+ P.123a
9
+ I.434a
10
+ R.303
11
+ P.130
12
+ I.409
13
+ R.415a
14
+ W.245a
15
+ P.106a*Xe tải
16
+ W.203c
17
+ P.117*
18
+ P.124a*
19
+ P.107
20
+ P.124d
21
+ P.103a
22
+ W.203b
23
+ W.221b
24
+ P.111
25
+ P.129
26
+ S.505a*Xe máy
27
+ W.246a
28
+ W.225
29
+ S.505a*Xe tải và công
30
+ P.104
31
+ S.505a*Xe tải
32
+ Camera
33
+ P.123b
34
+ W.202b
35
+ B.8a
36
+ P.137
37
+ P.139
38
+ W.205b
39
+ P.127*50
40
+ P.127*60
41
+ P.127*80
42
+ P.127*40
43
+ R.301e
44
+ W.239b*
45
+ W.233
46
+ I.407a
47
+ P.131a
48
+ P.124b1
49
+ W.210
50
+ P.124c
51
+ W.201b
52
+ W.246c
classes/classes_vie.txt ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Đường người đi bộ cắt ngang
2
+ Đường giao nhau (ngã ba bên phải)
3
+ Cấm đi ngược chiều
4
+ Phải đi vòng sang bên phải
5
+ Giao nhau với đường đồng cấp
6
+ Giao nhau với đường không ưu tiên
7
+ Chỗ ngoặt nguy hiểm vòng bên trái
8
+ Cấm rẽ trái
9
+ Bến xe buýt
10
+ Nơi giao nhau chạy theo vòng xuyến
11
+ Cấm dừng và đỗ xe
12
+ Chỗ quay xe
13
+ Biển gộp làn đường theo phương tiện
14
+ Đi chậm
15
+ Cấm xe tải
16
+ Đường bị thu hẹp về phía phải
17
+ Giới hạn chiều cao
18
+ Cấm quay đầu
19
+ Cấm ô tô khách và ô tô tải
20
+ Cấm rẽ phải và quay đầu
21
+ Cấm ô tô
22
+ Đường bị thu hẹp về phía trái
23
+ Gồ giảm tốc phía trước
24
+ Cấm xe hai và ba bánh
25
+ Kiểm tra
26
+ Chỉ dành cho xe máy*
27
+ Chướng ngoại vật phía trước
28
+ Trẻ em
29
+ Xe tải và xe công*
30
+ Cấm mô tô và xe máy
31
+ Chỉ dành cho xe tải*
32
+ Đường có camera giám sát
33
+ Cấm rẽ phải
34
+ Nhiều chỗ ngoặt nguy hiểm liên tiếp, chỗ đầu tiên sang phải
35
+ Cấm xe sơ-mi rơ-moóc
36
+ Cấm rẽ trái và phải
37
+ Cấm đi thẳng và rẽ phải
38
+ Đường giao nhau (ngã ba bên trái)
39
+ Giới hạn tốc độ (50km/h)
40
+ Giới hạn tốc độ (60km/h)
41
+ Giới hạn tốc độ (80km/h)
42
+ Giới hạn tốc độ (40km/h)
43
+ Các xe chỉ được rẽ trái
44
+ Chiều cao tĩnh không thực tế
45
+ Nguy hiểm khác
46
+ Đường một chiều
47
+ Cấm đỗ xe
48
+ Cấm ô tô quay đầu xe (được rẽ trái)
49
+ Giao nhau với đường sắt có rào chắn
50
+ Cấm rẽ trái và quay đầu xe
51
+ Chỗ ngoặt nguy hiểm vòng bên phải
52
+ Chú ý chướng ngại vật – vòng tránh sang bên phải
core/__pycache__/helpers.cpython-311.pyc ADDED
Binary file (3.01 kB). View file
 
core/__pycache__/model.cpython-311.pyc ADDED
Binary file (2.72 kB). View file
 
core/__pycache__/ui.cpython-311.pyc ADDED
Binary file (3.45 kB). View file
 
core/helpers.py ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import streamlit as st
3
+
4
+ def get_image_list():
5
+ folder_path = "test_dataset/images"
6
+ images = [f for f in os.listdir(folder_path) if f.lower().endswith('jpg')]
7
+ return images
8
+
9
+ def show_hyperparameters(conf_threshold, iou_threshold):
10
+ st.subheader("Respect to hyperparameters:")
11
+ st.markdown(f"- Confidence threshold: {conf_threshold}")
12
+ st.markdown(f"- IOU threshold for Non-Maximum Suppression (NMS): {iou_threshold}")
13
+
14
+ def show_note_for_classes(classes_with_conf):
15
+ with open("classes/classes.txt", "r", encoding="utf-8") as f:
16
+ classes = [line.strip() for line in f.readlines()]
17
+
18
+ with open("classes/classes_vie.txt", "r", encoding="utf-8") as f:
19
+ classes_vie = [line.strip() for line in f.readlines()]
20
+
21
+ if not classes_with_conf:
22
+ st.info("No detections found.")
23
+ return
24
+
25
+ st.subheader("📝 Detected Classes")
26
+ for cls, conf in classes_with_conf:
27
+ label = classes[cls]
28
+ label_vie = classes_vie[cls]
29
+ st.markdown(f"- **{label}** (`{label_vie}`) — Confidence: **{conf:.2f}**")
core/model.py ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from ultralytics import YOLO
2
+ import streamlit as st
3
+ import cv2
4
+ from huggingface_hub import hf_hub_download
5
+
6
+ @st.cache_resource
7
+ def load_model():
8
+ model_path = hf_hub_download(
9
+ repo_id="thanhhiepvos/Fine_tuned_Vietnam_Traffic_Sign_Detection",
10
+ filename="YOLO12X.pt",
11
+ repo_type="model"
12
+ )
13
+ return YOLO(model_path)
14
+
15
+ def run_yolo_inference(model, image_path, conf_threshold=0.25, iou_threshold=0.7, conf_show=False):
16
+ # Read image with OpenCV (BGR)
17
+ img = cv2.imread(image_path)
18
+ results = model(img,
19
+ conf=conf_threshold,
20
+ iou=iou_threshold
21
+ )[0]
22
+
23
+ classes_with_conf = []
24
+
25
+ for i, box in enumerate(results.boxes):
26
+ x1, y1, x2, y2 = box.xyxy[0].int().tolist()
27
+ conf = float(box.conf[0])
28
+ cls = int(box.cls[0])
29
+ if conf_show:
30
+ label = f"{model.names[cls]} {conf:.2f}"
31
+ else:
32
+ label = f"{model.names[cls]}"
33
+ classes_with_conf.append([cls, conf])
34
+
35
+ # Draw bounding box
36
+ cv2.rectangle(img, (x1, y1), (x2, y2), (0, 0, 255), 2)
37
+
38
+ # Get text size
39
+ (text_w, text_h), baseline = cv2.getTextSize(label, cv2.FONT_HERSHEY_SIMPLEX, 0.6, 1)
40
+
41
+ # New Y position: just below the bounding box, plus spacing
42
+ label_y = y2 + (i * (text_h + 6)) + 10
43
+
44
+ # Background rectangle for the label
45
+ cv2.rectangle(img, (x1, label_y), (x1 + text_w, label_y + text_h + 4), (255, 255, 255), -1)
46
+
47
+ # Red text over white background
48
+ cv2.putText(img, label, (x1, label_y + text_h + 2), cv2.FONT_HERSHEY_SIMPLEX,
49
+ 0.6, (0, 0, 255), 1, cv2.LINE_AA)
50
+
51
+ return cv2.cvtColor(img, cv2.COLOR_BGR2RGB), classes_with_conf
core/ui.py ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from PIL import Image
3
+ import os
4
+
5
+
6
+ def show_choosing_pic_bar(images, img_folder):
7
+ st.sidebar.header("📂 Select an Image")
8
+ col1, col2 = st.sidebar.columns(2)
9
+ selected_img = None
10
+
11
+ for i, img_name in enumerate(images):
12
+ img_path = os.path.join(img_folder, img_name)
13
+ image = Image.open(img_path).resize((100, 100))
14
+
15
+ col = col1 if i % 2 == 0 else col2
16
+ if col.button("Select", key=img_name):
17
+ st.session_state.selected_image = img_name
18
+
19
+ col.image(image, use_container_width = True)
20
+ #st.sidebar.image(image)
21
+ col.caption(img_name)
22
+
23
+ def show_right_sidebar(col):
24
+ # Set defaults if not present
25
+ if "confidence" not in st.session_state:
26
+ st.session_state.confidence = 0.25
27
+ if "iou" not in st.session_state:
28
+ st.session_state.iou = 0.7
29
+ if "show_confidence" not in st.session_state:
30
+ st.session_state.show_confidence = False # Set default to False
31
+
32
+ with col:
33
+ st.markdown("### ⚙️ Hyperparameters", unsafe_allow_html=True)
34
+
35
+ # --- Confidence ---
36
+ st.session_state.confidence = st.number_input(
37
+ "Confidence Threshold", min_value=0.0, max_value=1.0,
38
+ step=0.01, value=st.session_state.confidence,
39
+ format="%.2f"
40
+ )
41
+ st.caption("Confidence score for label in predicted bounding box.")
42
+
43
+ st.divider()
44
+
45
+ # --- IOU ---
46
+ st.session_state.iou = st.number_input(
47
+ "IOU Threshold", min_value=0.0, max_value=1.0,
48
+ step=0.01, value=st.session_state.iou,
49
+ format="%.2f"
50
+ )
51
+ st.caption("Lower values result in fewer detections by eliminating overlapping boxes, useful for reducing duplicates.")
52
+
53
+ st.markdown("---")
54
+ st.header("📊 Display Options")
55
+
56
+ # --- Show Confidence Checkbox ---
57
+ st.session_state.show_confidence = st.checkbox(
58
+ "Show Confidence", value=st.session_state.show_confidence
59
+ )
60
+
61
+ return st.session_state.confidence, st.session_state.iou, st.session_state.show_confidence
requirements.txt ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ streamlit
2
+ opencv-python
3
+ numpy
4
+ Pillow
5
+ ultralytics
6
+ base64
7
+ io
8
+ huggingface