Thanh6624 commited on
Commit
ce2a8be
·
verified ·
1 Parent(s): 05cfb14

Create App.py

Browse files
Files changed (1) hide show
  1. App.py +118 -0
App.py ADDED
@@ -0,0 +1,118 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import cv2
3
+ from ultralytics import YOLO
4
+ import subprocess
5
+ import os
6
+
7
+ # Tải mô hình YOLOv8
8
+ model = YOLO('yolov8n.pt')
9
+
10
+ def process_video(video_path):
11
+ if not video_path:
12
+ return None
13
+
14
+ # Cấu hình đếm
15
+ vehicle_classes = ['car', 'motorcycle', 'bus', 'truck']
16
+ vehicle_class_ids = [2, 3, 5, 7]
17
+ vehicle_count = {cls: 0 for cls in vehicle_classes}
18
+ track_history = {}
19
+ counted_ids = set()
20
+
21
+ cap = cv2.VideoCapture(video_path)
22
+ fps = cap.get(cv2.CAP_PROP_FPS)
23
+ width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
24
+ height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
25
+
26
+ # Vạch đếm ở 60% màn hình
27
+ line_y = int(height * 0.6)
28
+
29
+ # Xuất ra file tạm bằng OpenCV (mp4v)
30
+ temp_output = 'temp_output.mp4'
31
+ fourcc = cv2.VideoWriter_fourcc(*'mp4v')
32
+ out = cv2.VideoWriter(temp_output, fourcc, fps, (width, height))
33
+
34
+ while cap.isOpened():
35
+ ret, frame = cap.read()
36
+ if not ret:
37
+ break
38
+
39
+ results = model.track(frame, classes=vehicle_class_ids, persist=True, verbose=False)
40
+
41
+ cv2.line(frame, (0, line_y), (width, line_y), (0, 0, 255), 3)
42
+ cv2.putText(frame, "Counting Line", (10, line_y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
43
+
44
+ if results[0].boxes.id is not None:
45
+ boxes = results[0].boxes
46
+ ids = boxes.id.cpu().numpy().astype(int)
47
+ classes = boxes.cls.cpu().numpy().astype(int)
48
+ confs = boxes.conf.cpu().numpy()
49
+
50
+ for (x1, y1, x2, y2, obj_id, cls_id, conf) in zip(
51
+ boxes.xyxy[:,0], boxes.xyxy[:,1], boxes.xyxy[:,2], boxes.xyxy[:,3],
52
+ ids, classes, confs
53
+ ):
54
+ label = model.names[cls_id]
55
+ cx = int((x1 + x2) / 2)
56
+ cy = int((y1 + y2) / 2)
57
+
58
+ cv2.rectangle(frame, (int(x1), int(y1)), (int(x2), int(y2)), (255, 255, 0), 2)
59
+ cv2.circle(frame, (cx, cy), 5, (0, 255, 0), -1)
60
+ cv2.putText(frame, f"ID:{obj_id} {label}", (int(x1), int(y1) - 10),
61
+ cv2.FONT_HERSHEY_SIMPLEX, 0.6, (255, 255, 0), 2)
62
+
63
+ # Logic đếm qua vạch
64
+ if obj_id in track_history and obj_id not in counted_ids:
65
+ prev_cy = track_history[obj_id]
66
+ if (prev_cy < line_y and cy >= line_y) or (prev_cy > line_y and cy <= line_y):
67
+ vehicle_count[label] += 1
68
+ counted_ids.add(obj_id)
69
+ cv2.line(frame, (0, line_y), (width, line_y), (0, 255, 0), 5)
70
+
71
+ track_history[obj_id] = cy
72
+
73
+ # Hiển thị kết quả
74
+ total = sum(vehicle_count.values())
75
+ overlay = frame.copy()
76
+ box_w, box_h = 250, 160
77
+ x0, y0 = width - box_w - 20, 20
78
+ cv2.rectangle(overlay, (x0, y0), (x0 + box_w, y0 + box_h), (0, 0, 0), -1)
79
+ frame = cv2.addWeighted(overlay, 0.6, frame, 0.4, 0)
80
+
81
+ cv2.putText(frame, f'Total Objects: {total}', (x0 + 10, y0 + 30),
82
+ cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 255, 0), 2)
83
+
84
+ for i, (cls, cnt) in enumerate(vehicle_count.items()):
85
+ cv2.putText(frame, f'{cls.capitalize()}: {cnt}',
86
+ (x0 + 10, y0 + 60 + i * 25),
87
+ cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 255, 255), 2)
88
+
89
+ out.write(frame)
90
+
91
+ cap.release()
92
+ out.release()
93
+
94
+ # CHUYỂN ĐỔI VIDEO SANG CHUẨN H.264 ĐỂ HIỂN THỊ TRÊN WEB (Rất quan trọng)
95
+ final_output = 'result_video.mp4'
96
+ if os.path.exists(final_output):
97
+ os.remove(final_output)
98
+
99
+ subprocess.run(
100
+ ['ffmpeg', '-i', temp_output, '-vcodec', 'libx264', '-crf', '28', final_output],
101
+ check=True
102
+ )
103
+
104
+ return final_output
105
+
106
+ # Xây dựng giao diện Web với Gradio
107
+ interface = gr.Interface(
108
+ fn=process_video,
109
+ inputs=gr.Video(label="Tải video của bạn lên đây"),
110
+ outputs=gr.Video(label="Video kết quả đếm xe"),
111
+ title="Hệ thống đếm xe tự động (YOLOv8)",
112
+ description="Tải lên một video giao thông để hệ thống tự động nhận diện và đếm số lượng xe cộ qua vạch kẻ ngang.",
113
+ allow_flagging="never"
114
+ )
115
+
116
+ # Chạy ứng dụng
117
+ if __name__ == "__main__":
118
+ interface.launch()