Khalida1w commited on
Commit
713635a
1 Parent(s): cde5d08

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +83 -51
app.py CHANGED
@@ -21,62 +21,94 @@ def check_ffmpeg():
21
  if shutil.which("ffmpeg") is None:
22
  raise EnvironmentError("ffmpeg is not installed or not found in the system PATH. Please install ffmpeg to proceed.")
23
 
 
 
 
 
 
 
 
24
  def process_video(video_path, output_option):
25
  # Check if ffmpeg is installed
26
  check_ffmpeg()
27
 
28
- # Run the YOLO model on the video, specifying the tracker configuration
29
- results = model.track(video_path, save=True, tracker="bytetrack.yaml", persist=True)
30
-
31
- # Get the video file name without extension and directory
32
- video_name = os.path.splitext(os.path.basename(video_path))[0]
33
-
34
- # Find the latest directory created in 'runs/detect/'
35
- output_dir = max(glob.glob('./runs/detect/*'), key=os.path.getmtime)
36
-
37
- # Find the saved video file in the latest directory with the specific video name
38
- video_files = glob.glob(os.path.join(output_dir, f'{video_name}*.avi'))
39
-
40
- if not video_files:
41
- raise Exception(f"No .avi video files found in directory {output_dir} for {video_name}")
42
-
43
- # Convert the video to mp4
44
- mp4_files = []
45
- for file in video_files:
46
- mp4_file = f"{file[:-4]}.mp4"
47
- # Quote the file paths to handle spaces and overwrite without prompt
48
- os.system(f"ffmpeg -y -i \"{file}\" -vcodec libx264 \"{mp4_file}\"")
49
- os.remove(file) # Remove the original .avi file after conversion
50
- mp4_files.append(mp4_file)
51
-
52
- # Check again for the converted .mp4 video files specifically for the processed video
53
- matched_mp4_files = [file for file in mp4_files if video_name in file]
54
-
55
- if not matched_mp4_files:
56
- raise Exception(f"No .mp4 video files found in directory {output_dir} after conversion for {video_name}.")
57
-
58
- # Initialize object count dictionary based on colors
59
- color_counts = {color: 0 for color in ClassToColorMapping.values()}
60
-
61
- # Calculate object count based on results and map to colors
62
  for result in results:
63
- if hasattr(result, 'boxes'):
64
- for box in result.boxes:
65
- class_id = int(box.cls) # Assuming `cls` is the class index
66
- color = ClassToColorMapping.get(class_id, "unknown")
67
- if color in color_counts:
68
- color_counts[color] += 1
 
69
 
70
- # Set default outputs
71
- video_output = matched_mp4_files[0] if matched_mp4_files else None
 
 
 
 
72
 
73
- # Determine the output based on user's choice
 
 
 
74
  if output_option == "Count":
75
- return color_counts, None
76
- elif output_option == "Video":
77
- return None, video_output
78
- elif output_option == "Both":
79
- return color_counts, video_output
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
80
 
81
  # Define Gradio inputs
82
  video_input = gr.Video()
@@ -92,12 +124,12 @@ video_interface = gr.Interface(
92
  inputs=[video_input, output_option_input],
93
  outputs=[gr.JSON(label="Color Counts"), "video"], # Ensure two outputs are defined, using JSON for color counts
94
  title="YOLO Video Tracking Application with Color Counting",
95
- description="A simple application to track objects in a video using YOLO model and count objects by color. Upload your own video, or click one of the examples to load them.",
96
  article="""<div>
97
- <p style="text-align: center">Upload a video file and select the type of output you want: object color counts, processed video, or both. Then, hit submit to process the video.</p>
98
  </div>""",
99
  examples=examples,
100
- cache_examples=False # Disable caching to speed up launch
101
  )
102
 
103
  # Deploy the interface with share enabled
 
21
  if shutil.which("ffmpeg") is None:
22
  raise EnvironmentError("ffmpeg is not installed or not found in the system PATH. Please install ffmpeg to proceed.")
23
 
24
+ def convert_to_mp4(file):
25
+ """Convert a .avi video file to .mp4 format."""
26
+ mp4_file = f"{file[:-4]}.mp4"
27
+ os.system(f"ffmpeg -y -i \"{file}\" -vcodec libx264 \"{mp4_file}\"")
28
+ os.remove(file) # Remove the original .avi file after conversion
29
+ return mp4_file
30
+
31
  def process_video(video_path, output_option):
32
  # Check if ffmpeg is installed
33
  check_ffmpeg()
34
 
35
+ # Determine if the video needs to be saved
36
+ save_video = output_option in ["Video", "Both"]
37
+
38
+ # Run the YOLO model on the video, specifying the tracker configuration and save option
39
+ results = model.track(
40
+ video_path,
41
+ save=save_video,
42
+ tracker="bytetrack.yaml",
43
+ half=False,
44
+ vid_stride=1,
45
+ iou=0.75,
46
+ conf=0.25
47
+ )
48
+
49
+ # Initialize a dictionary to store unique IDs for each color
50
+ chip_ids = {color: set() for color in ClassToColorMapping.values()}
51
+
52
+ # Check if results are None or if there are no results
53
+ if results is None or len(results) == 0:
54
+ raise Exception("No detections were found in the video.")
55
+
56
+ # Track the unique IDs for each color
 
 
 
 
 
 
 
 
 
 
 
 
57
  for result in results:
58
+ # Check if result.boxes exists and has valid id and cls attributes
59
+ if result.boxes is None or result.boxes.id is None or result.boxes.cls is None:
60
+ continue # Skip if no boxes or if ids or classes are None
61
+
62
+ # Check if the id and cls tensors are not empty
63
+ if result.boxes.id.numel() == 0 or result.boxes.cls.numel() == 0:
64
+ continue # Skip if ids or classes are empty tensors
65
 
66
+ for cls, id_ in zip(result.boxes.cls, result.boxes.id):
67
+ if cls is None or id_ is None:
68
+ continue # Skip if class or id is None
69
+ color = ClassToColorMapping.get(int(cls.item()), None) # Map class label to color
70
+ if color:
71
+ chip_ids[color].add(int(id_.item())) # Add the unique ID to the set
72
 
73
+ # Convert sets to counts of unique IDs
74
+ chip_counts_by_color = {color: len(ids) for color, ids in chip_ids.items()}
75
+
76
+ # If the user only wants the count, return it immediately
77
  if output_option == "Count":
78
+ return chip_counts_by_color, None
79
+
80
+ # Process video saving if required
81
+ if save_video:
82
+ video_name = os.path.splitext(os.path.basename(video_path))[0]
83
+
84
+ # Find the latest directory created in 'runs/detect/'
85
+ output_dir = max(glob.glob('./runs/detect/*'), key=os.path.getmtime)
86
+
87
+ # Find the saved video file in the latest directory with the specific video name
88
+ video_files = glob.glob(os.path.join(output_dir, f'{video_name}*.avi'))
89
+
90
+ if not video_files:
91
+ raise Exception(f"No .avi video files found in directory {output_dir} for {video_name}")
92
+
93
+ # Convert each .avi video to .mp4
94
+ mp4_files = []
95
+ for file in video_files:
96
+ mp4_file = convert_to_mp4(file)
97
+ mp4_files.append(mp4_file)
98
+
99
+ matched_mp4_files = [file for file in mp4_files if video_name in file]
100
+
101
+ if not matched_mp4_files:
102
+ raise Exception(f"No .mp4 video files found in directory {output_dir} after conversion for {video_name}.")
103
+
104
+ # Return video path and chip counts if both are requested
105
+ if output_option == "Both":
106
+ return chip_counts_by_color, matched_mp4_files[0]
107
+ else:
108
+ return None, matched_mp4_files[0]
109
+ else:
110
+ # Return only chip counts if no video is needed
111
+ return chip_counts_by_color, None
112
 
113
  # Define Gradio inputs
114
  video_input = gr.Video()
 
124
  inputs=[video_input, output_option_input],
125
  outputs=[gr.JSON(label="Color Counts"), "video"], # Ensure two outputs are defined, using JSON for color counts
126
  title="YOLO Video Tracking Application with Color Counting",
127
+ description="A simple application to track objects in a video using YOLO model and count unique objects by color. Upload your own video, or click one of the examples to load them.",
128
  article="""<div>
129
+ <p style="text-align: center">Upload a video file and select the type of output you want: unique object counts by color, processed video, or both. Then, hit submit to process the video.</p>
130
  </div>""",
131
  examples=examples,
132
+ cache_examples=True # Disable caching to speed up launch
133
  )
134
 
135
  # Deploy the interface with share enabled