lokesh341 commited on
Commit
9123abc
·
verified ·
1 Parent(s): e2e6263

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +8 -23
app.py CHANGED
@@ -8,10 +8,11 @@ import cv2
8
  import os
9
  import torch.serialization
10
  from ultralytics.nn.tasks import DetectionModel
 
11
  import numpy as np
12
 
13
- # Allowlist the DetectionModel class to fix UnpicklingError
14
- torch.serialization.add_safe_globals([DetectionModel])
15
 
16
  # Load the pre-trained YOLOv8n model
17
  model = YOLO('model/yolov8n.pt')
@@ -21,22 +22,19 @@ model.overrides['agnostic_nms'] = False
21
  model.overrides['max_det'] = 1000
22
 
23
  def detect_empty_spots(img_width, img_height, bottle_bboxes, min_gap=50):
24
- """Simple logic to infer empty spots based on gaps between bottles"""
25
  empty_bboxes = []
26
- # Assume shelf spans full image width; split into horizontal segments
27
  x_coords = sorted([bbox[0] for bbox in bottle_bboxes] + [bbox[2] for bbox in bottle_bboxes])
28
  x_coords = [0] + x_coords + [img_width]
29
 
30
  for i in range(len(x_coords) - 1):
31
  gap_start = x_coords[i]
32
  gap_end = x_coords[i + 1]
33
- if gap_end - gap_start > min_gap: # If gap is large enough, consider it an empty spot
34
- empty_bboxes.append([gap_start, 0, gap_end, img_height]) # Full height for simplicity
35
 
36
  return empty_bboxes
37
 
38
  def process_input(input_file):
39
- # Handle video: Extract middle frame
40
  if input_file.lower().endswith(('.mp4', '.avi', '.mov')):
41
  cap = cv2.VideoCapture(input_file)
42
  total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
@@ -51,12 +49,10 @@ def process_input(input_file):
51
  else:
52
  process_img_path = input_file
53
 
54
- # Run model inference
55
  results = model(process_img_path)
56
  boxes = results[0].boxes
57
  class_names = results[0].names
58
 
59
- # Count bottles and collect their bounding boxes
60
  num_present = 0
61
  bottle_bboxes = []
62
  for box in boxes:
@@ -64,24 +60,20 @@ def process_input(input_file):
64
  cls_name = class_names[cls_id]
65
  if cls_name == 'bottle':
66
  num_present += 1
67
- bottle_bboxes.append(box.xyxy[0].cpu().numpy()) # [x1, y1, x2, y2]
68
 
69
- # Load image for annotation
70
  img = Image.open(process_img_path)
71
  img_width, img_height = img.size
72
  draw = ImageDraw.Draw(img)
73
 
74
- # Draw bottle bounding boxes
75
  for bbox in bottle_bboxes:
76
  draw.rectangle(((bbox[0], bbox[1]), (bbox[2], bbox[3])), outline="green", width=3)
77
 
78
- # Infer empty spots
79
  empty_bboxes = detect_empty_spots(img_width, img_height, bottle_bboxes)
80
  num_empty = len(empty_bboxes)
81
  for bbox in empty_bboxes:
82
  draw.rectangle(((bbox[0], bbox[1]), (bbox[2], bbox[3])), outline="red", width=3)
83
 
84
- # Generate PDF
85
  pdf = FPDF()
86
  pdf.add_page()
87
  pdf.set_font("Arial", size=12)
@@ -91,23 +83,20 @@ def process_input(input_file):
91
  pdf.cell(200, 10, txt=f"Number of empty spots (inferred): {num_empty}", ln=1)
92
  pdf.ln(10)
93
 
94
- # Add annotated full image
95
  with tempfile.NamedTemporaryFile(suffix='.png') as tmp_annotated:
96
  img.save(tmp_annotated.name)
97
- pdf.image(tmp_annotated.name, x=10, y=pdf.get_y(), w=180) # Full width for readability
98
 
99
- # Add screenshots of bottles and empty spots
100
  pdf.add_page()
101
  pdf.cell(200, 10, txt="Detected Bottles and Empty Spots", ln=1, align='C')
102
  pdf.ln(5)
103
  y_pos = pdf.get_y()
104
 
105
- # Bottles
106
  for i, bbox in enumerate(bottle_bboxes):
107
  cropped_img = img.crop((bbox[0], bbox[1], bbox[2], bbox[3]))
108
  with tempfile.NamedTemporaryFile(suffix='.png') as tmp_crop:
109
  cropped_img.save(tmp_crop.name)
110
- pdf.image(tmp_crop.name, x=10, y=y_pos, w=90) # Medium size for clear view
111
  y_pos += 100
112
  pdf.cell(200, 10, txt=f"Bottle {i+1} (Location: x1={int(bbox[0])}, y1={int(bbox[1])}, x2={int(bbox[2])}, y2={int(bbox[3])})", ln=1)
113
  pdf.ln(5)
@@ -115,7 +104,6 @@ def process_input(input_file):
115
  pdf.add_page()
116
  y_pos = 10
117
 
118
- # Empty spots
119
  for i, bbox in enumerate(empty_bboxes):
120
  cropped_img = img.crop((bbox[0], bbox[1], bbox[2], bbox[3]))
121
  with tempfile.NamedTemporaryFile(suffix='.png') as tmp_crop:
@@ -128,18 +116,15 @@ def process_input(input_file):
128
  pdf.add_page()
129
  y_pos = 10
130
 
131
- # Output PDF
132
  pdf_bytes = io.BytesIO()
133
  pdf.output(pdf_bytes)
134
  pdf_bytes.seek(0)
135
 
136
- # Clean up temp files
137
  if 'temp_frame_path' in locals():
138
  os.remove(temp_frame_path)
139
 
140
  return pdf_bytes.getvalue()
141
 
142
- # Gradio interface
143
  with gr.Blocks() as demo:
144
  gr.Markdown("# Wine Shop CCTV Analyzer")
145
  gr.Markdown("Upload a CCTV image or video to analyze stock and generate a PDF report.")
 
8
  import os
9
  import torch.serialization
10
  from ultralytics.nn.tasks import DetectionModel
11
+ from torch.nn.modules.container import Sequential
12
  import numpy as np
13
 
14
+ # Allowlist required classes to fix UnpicklingError
15
+ torch.serialization.add_safe_globals([DetectionModel, Sequential])
16
 
17
  # Load the pre-trained YOLOv8n model
18
  model = YOLO('model/yolov8n.pt')
 
22
  model.overrides['max_det'] = 1000
23
 
24
  def detect_empty_spots(img_width, img_height, bottle_bboxes, min_gap=50):
 
25
  empty_bboxes = []
 
26
  x_coords = sorted([bbox[0] for bbox in bottle_bboxes] + [bbox[2] for bbox in bottle_bboxes])
27
  x_coords = [0] + x_coords + [img_width]
28
 
29
  for i in range(len(x_coords) - 1):
30
  gap_start = x_coords[i]
31
  gap_end = x_coords[i + 1]
32
+ if gap_end - gap_start > min_gap:
33
+ empty_bboxes.append([gap_start, 0, gap_end, img_height])
34
 
35
  return empty_bboxes
36
 
37
  def process_input(input_file):
 
38
  if input_file.lower().endswith(('.mp4', '.avi', '.mov')):
39
  cap = cv2.VideoCapture(input_file)
40
  total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
 
49
  else:
50
  process_img_path = input_file
51
 
 
52
  results = model(process_img_path)
53
  boxes = results[0].boxes
54
  class_names = results[0].names
55
 
 
56
  num_present = 0
57
  bottle_bboxes = []
58
  for box in boxes:
 
60
  cls_name = class_names[cls_id]
61
  if cls_name == 'bottle':
62
  num_present += 1
63
+ bottle_bboxes.append(box.xyxy[0].cpu().numpy())
64
 
 
65
  img = Image.open(process_img_path)
66
  img_width, img_height = img.size
67
  draw = ImageDraw.Draw(img)
68
 
 
69
  for bbox in bottle_bboxes:
70
  draw.rectangle(((bbox[0], bbox[1]), (bbox[2], bbox[3])), outline="green", width=3)
71
 
 
72
  empty_bboxes = detect_empty_spots(img_width, img_height, bottle_bboxes)
73
  num_empty = len(empty_bboxes)
74
  for bbox in empty_bboxes:
75
  draw.rectangle(((bbox[0], bbox[1]), (bbox[2], bbox[3])), outline="red", width=3)
76
 
 
77
  pdf = FPDF()
78
  pdf.add_page()
79
  pdf.set_font("Arial", size=12)
 
83
  pdf.cell(200, 10, txt=f"Number of empty spots (inferred): {num_empty}", ln=1)
84
  pdf.ln(10)
85
 
 
86
  with tempfile.NamedTemporaryFile(suffix='.png') as tmp_annotated:
87
  img.save(tmp_annotated.name)
88
+ pdf.image(tmp_annotated.name, x=10, y=pdf.get_y(), w=180)
89
 
 
90
  pdf.add_page()
91
  pdf.cell(200, 10, txt="Detected Bottles and Empty Spots", ln=1, align='C')
92
  pdf.ln(5)
93
  y_pos = pdf.get_y()
94
 
 
95
  for i, bbox in enumerate(bottle_bboxes):
96
  cropped_img = img.crop((bbox[0], bbox[1], bbox[2], bbox[3]))
97
  with tempfile.NamedTemporaryFile(suffix='.png') as tmp_crop:
98
  cropped_img.save(tmp_crop.name)
99
+ pdf.image(tmp_crop.name, x=10, y=y_pos, w=90)
100
  y_pos += 100
101
  pdf.cell(200, 10, txt=f"Bottle {i+1} (Location: x1={int(bbox[0])}, y1={int(bbox[1])}, x2={int(bbox[2])}, y2={int(bbox[3])})", ln=1)
102
  pdf.ln(5)
 
104
  pdf.add_page()
105
  y_pos = 10
106
 
 
107
  for i, bbox in enumerate(empty_bboxes):
108
  cropped_img = img.crop((bbox[0], bbox[1], bbox[2], bbox[3]))
109
  with tempfile.NamedTemporaryFile(suffix='.png') as tmp_crop:
 
116
  pdf.add_page()
117
  y_pos = 10
118
 
 
119
  pdf_bytes = io.BytesIO()
120
  pdf.output(pdf_bytes)
121
  pdf_bytes.seek(0)
122
 
 
123
  if 'temp_frame_path' in locals():
124
  os.remove(temp_frame_path)
125
 
126
  return pdf_bytes.getvalue()
127
 
 
128
  with gr.Blocks() as demo:
129
  gr.Markdown("# Wine Shop CCTV Analyzer")
130
  gr.Markdown("Upload a CCTV image or video to analyze stock and generate a PDF report.")