iamsuman commited on
Commit
4c1b1bb
Β·
1 Parent(s): 6e700f4

show total and current frame count

Browse files
Files changed (1) hide show
  1. app.py +65 -21
app.py CHANGED
@@ -92,48 +92,93 @@ interface_image = gr.Interface(
92
  examples=path,
93
  cache_examples=False,
94
  )
95
- def show_preds_video_batch(video_path, batch_size=16):
 
96
  cap = cv2.VideoCapture(video_path)
97
  if not cap.isOpened():
98
  print("Error: Could not open video.")
99
  return
100
 
101
  frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
102
- ripe_ids, unripe_ids = set(), set()
 
 
 
 
 
 
103
  frame_buffer = deque()
104
- names = model.model.names # cache model class names
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
105
 
106
  def process_batch(frames, results):
107
- nonlocal ripe_ids, unripe_ids
108
  for frame, output in zip(frames, results):
109
- if output.boxes and output.boxes.id is not None:
 
 
110
  boxes = output.boxes
111
- ids = boxes.id.cpu().numpy().astype(int)
112
- classes = boxes.cls.cpu().numpy().astype(int)
113
 
114
- for box, cls, track_id in zip(boxes.xyxy, classes, ids):
115
  x1, y1, x2, y2 = map(int, box)
116
- class_name = names[cls]
117
- color = (0, 0, 255) if class_name.lower() == "ripe" else (0, 255, 0)
 
118
 
119
  if class_name.lower() == "ripe":
120
- ripe_ids.add(track_id)
 
121
  else:
122
- unripe_ids.add(track_id)
 
123
 
124
  cv2.rectangle(frame, (x1, y1), (x2, y2), color, 2)
125
- cv2.putText(frame, f"{class_name.capitalize()} ID:{track_id}",
126
  (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 2)
127
 
128
- # Draw total counts
129
- full_text = f"Ripe: {len(ripe_ids)} | Unripe: {len(unripe_ids)}"
130
- (text_width, _), _ = cv2.getTextSize(full_text, cv2.FONT_HERSHEY_SIMPLEX, 1, 2)
131
- text_x = (frame_width - text_width) // 2
132
- cv2.putText(frame, full_text, (text_x, 40),
133
  cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2)
134
 
 
 
 
 
 
 
 
135
  yield cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
136
 
 
137
  while True:
138
  ret, frame = cap.read()
139
  if not ret:
@@ -145,13 +190,12 @@ def show_preds_video_batch(video_path, batch_size=16):
145
  yield from process_batch(frame_buffer, results)
146
  frame_buffer.clear()
147
 
148
- # process remaining frames
149
  if frame_buffer:
150
  results = model.track(source=list(frame_buffer), persist=True, tracker="bytetrack.yaml", verbose=False)
151
  yield from process_batch(frame_buffer, results)
152
 
153
  cap.release()
154
- print(f"Final Counts β†’ Ripe: {len(ripe_ids)}, Unripe: {len(unripe_ids)}")
155
 
156
  # def show_preds_video(video_path):
157
  # results = model.track(source=video_path, persist=True, tracker="bytetrack.yaml", verbose=False, stream=True)
@@ -225,7 +269,7 @@ outputs_video = [
225
  gr.components.Image(type="numpy", label="Output Image"),
226
  ]
227
  interface_video = gr.Interface(
228
- fn=show_preds_video_batch,
229
  inputs=inputs_video,
230
  outputs=outputs_video,
231
  title="Ripe And Unripe Tomatoes Detection",
 
92
  examples=path,
93
  cache_examples=False,
94
  )
95
+
96
+ def show_preds_video_batch_centered(video_path, batch_size=16, iou_threshold=0.5):
97
  cap = cv2.VideoCapture(video_path)
98
  if not cap.isOpened():
99
  print("Error: Could not open video.")
100
  return
101
 
102
  frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
103
+ names = model.model.names # cache class names
104
+
105
+ # For IoU-based tracking of unique tomatoes
106
+ unique_objects = {} # id -> (class_name, last_box)
107
+ next_id = 0
108
+ total_ripe, total_unripe = 0, 0
109
+
110
  frame_buffer = deque()
111
+
112
+ def compute_iou(box1, box2):
113
+ xA = max(box1[0], box2[0])
114
+ yA = max(box1[1], box2[1])
115
+ xB = min(box1[2], box2[2])
116
+ yB = min(box1[3], box2[3])
117
+
118
+ inter_area = max(0, xB - xA) * max(0, yB - yA)
119
+ box1_area = (box1[2] - box1[0]) * (box1[3] - box1[1])
120
+ box2_area = (box2[2] - box2[0]) * (box2[3] - box2[1])
121
+ union_area = box1_area + box2_area - inter_area
122
+ return inter_area / union_area if union_area > 0 else 0
123
+
124
+ def match_or_register_object(cls_name, box):
125
+ nonlocal next_id, total_ripe, total_unripe
126
+ # Try to match existing object by IoU
127
+ for obj_id, (existing_cls, existing_box) in unique_objects.items():
128
+ if compute_iou(existing_box, box) > iou_threshold:
129
+ unique_objects[obj_id] = (cls_name, box)
130
+ return obj_id
131
+ # Register as new object
132
+ unique_objects[next_id] = (cls_name, box)
133
+ if cls_name.lower() == "ripe":
134
+ total_ripe += 1
135
+ else:
136
+ total_unripe += 1
137
+ next_id += 1
138
+ return next_id - 1
139
 
140
  def process_batch(frames, results):
 
141
  for frame, output in zip(frames, results):
142
+ current_ripe, current_unripe = set(), set()
143
+
144
+ if output.boxes:
145
  boxes = output.boxes
146
+ cls_ids = boxes.cls.cpu().numpy().astype(int)
 
147
 
148
+ for box, cls_id in zip(boxes.xyxy, cls_ids):
149
  x1, y1, x2, y2 = map(int, box)
150
+ class_name = names[cls_id]
151
+
152
+ obj_id = match_or_register_object(class_name, (x1, y1, x2, y2))
153
 
154
  if class_name.lower() == "ripe":
155
+ current_ripe.add(obj_id)
156
+ color = (0, 0, 255)
157
  else:
158
+ current_unripe.add(obj_id)
159
+ color = (0, 255, 0)
160
 
161
  cv2.rectangle(frame, (x1, y1), (x2, y2), color, 2)
162
+ cv2.putText(frame, f"{class_name.capitalize()} ID:{obj_id}",
163
  (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 2)
164
 
165
+ # --- Centered current counts ---
166
+ current_text = f"Current β†’ Ripe: {len(current_ripe)} | Unripe: {len(current_unripe)}"
167
+ (text_w, _), _ = cv2.getTextSize(current_text, cv2.FONT_HERSHEY_SIMPLEX, 1, 2)
168
+ text_x = (frame_width - text_w) // 2
169
+ cv2.putText(frame, current_text, (text_x, 40),
170
  cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2)
171
 
172
+ # --- Centered total counts ---
173
+ total_text = f"Total Seen β†’ Ripe: {total_ripe} | Unripe: {total_unripe}"
174
+ (text_w, _), _ = cv2.getTextSize(total_text, cv2.FONT_HERSHEY_SIMPLEX, 1, 2)
175
+ text_x = (frame_width - text_w) // 2
176
+ cv2.putText(frame, total_text, (text_x, 80),
177
+ cv2.FONT_HERSHEY_SIMPLEX, 1, (200, 200, 0), 2)
178
+
179
  yield cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
180
 
181
+ # --- Read and process in batches ---
182
  while True:
183
  ret, frame = cap.read()
184
  if not ret:
 
190
  yield from process_batch(frame_buffer, results)
191
  frame_buffer.clear()
192
 
 
193
  if frame_buffer:
194
  results = model.track(source=list(frame_buffer), persist=True, tracker="bytetrack.yaml", verbose=False)
195
  yield from process_batch(frame_buffer, results)
196
 
197
  cap.release()
198
+ print(f"Final Totals β†’ Ripe: {total_ripe}, Unripe: {total_unripe}")
199
 
200
  # def show_preds_video(video_path):
201
  # results = model.track(source=video_path, persist=True, tracker="bytetrack.yaml", verbose=False, stream=True)
 
269
  gr.components.Image(type="numpy", label="Output Image"),
270
  ]
271
  interface_video = gr.Interface(
272
+ fn=show_preds_video_batch_centered,
273
  inputs=inputs_video,
274
  outputs=outputs_video,
275
  title="Ripe And Unripe Tomatoes Detection",