RafidMehda commited on
Commit
ae8ca5c
·
verified ·
1 Parent(s): c4729d8

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +61 -54
app.py CHANGED
@@ -6,17 +6,18 @@ from PIL import Image, ImageDraw
6
  import io
7
  import random
8
 
9
- # Attempt to import YOLOv10 from the ultralytics package provided by THU-MIG/yolov10
 
 
10
  try:
11
  from ultralytics import YOLOv10
12
  except ImportError:
13
- st.error("Could not import YOLOv10. Please confirm the THU-MIG/yolov10 installation in requirements.txt.")
14
  st.stop()
15
 
16
- # -----------------------------------------------------------------------------
17
- # 1. Chaotic Logistic Map Encryption Functions
18
- # -----------------------------------------------------------------------------
19
-
20
  def logistic_map(r, x):
21
  return r * x * (1 - x)
22
 
@@ -25,7 +26,7 @@ def generate_key(seed, n):
25
  x = seed
26
  for _ in range(n):
27
  x = logistic_map(3.9, x)
28
- key.append(int(x * 255) % 256) # map float to [0..255]
29
  return np.array(key, dtype=np.uint8)
30
 
31
  def shuffle_pixels(img_array, seed):
@@ -64,66 +65,72 @@ def encrypt_image(img_array, seed):
64
 
65
  return doubly_encrypted_array
66
 
67
- # -----------------------------------------------------------------------------
68
- # 2. YOLOv10 License Plate Detection
69
- # -----------------------------------------------------------------------------
70
-
71
  @st.cache_data(show_spinner=False)
72
  def load_model(weights_path: str):
73
  """
74
- Loads the YOLOv10 model from local .pt weights.
75
  """
76
- model = YOLOv10(weights_path)
77
  return model
78
 
79
  def detect_license_plates(model, pil_image):
80
  """
81
- Runs YOLOv10 detection on the PIL image.
 
 
82
 
83
- After calling model.predict(), we log the raw output for debugging:
84
- - This helps see how bounding boxes or classes are returned.
85
  """
86
  np_image = np.array(pil_image)
87
- # Perform detection
88
  results = model.predict(np_image)
89
 
90
- # *** DEBUG: Print the raw model output ***
91
- print("Raw model output:", results)
 
 
 
 
 
92
 
93
- # If the model output is expected to be a list of bounding boxes
94
- # for a single image, typically we'd do something like:
95
- if len(results) > 0:
96
- detections = results[0]
97
- else:
98
- detections = []
99
 
 
 
 
 
 
 
100
  bboxes = []
101
  draw = ImageDraw.Draw(pil_image)
102
 
103
- # Example of how you'd parse each detection if it's [x1, y1, x2, y2, conf, cls_id]
104
- for det in detections:
105
- # If the model returns more or fewer elements, you'll need to adjust this line
106
- # e.g., if len(det) == 6, then you can unpack:
107
- # x1, y1, x2, y2, conf, cls_id = det
108
- # Otherwise, print(det) or log it to see how to parse properly
109
- if len(det) == 6:
110
- x1, y1, x2, y2, conf, cls_id = det
111
- cls_id = int(cls_id)
112
- # If your model’s license plate class is 0:
113
- if cls_id == 0:
114
- x1, y1, x2, y2 = map(int, (x1, y1, x2, y2))
115
- bboxes.append((x1, y1, x2, y2))
116
- draw.rectangle([x1, y1, x2, y2], outline="red", width=2)
117
- else:
118
- # Debug print if you run into mismatch
119
- print("Unexpected detection format:", det)
 
120
 
121
  return pil_image, bboxes
122
 
123
- # -----------------------------------------------------------------------------
124
- # 3. Streamlit App
125
- # -----------------------------------------------------------------------------
126
-
127
  def main():
128
  st.title("YOLOv10 + Chaotic Encryption Demo")
129
  st.write(
@@ -135,8 +142,8 @@ def main():
135
  """
136
  )
137
 
138
- # Model weights path
139
- default_model_path = "best.pt" # Adjust if your model file is named differently
140
  model_path = st.sidebar.text_input("YOLOv10 Weights (.pt)", value=default_model_path)
141
 
142
  if not os.path.isfile(model_path):
@@ -147,16 +154,16 @@ def main():
147
  model = load_model(model_path)
148
  st.success("Model loaded successfully!")
149
 
150
- # Image input
151
  st.subheader("Image Input")
152
  image_url = st.text_input("Image URL (optional)")
153
  uploaded_file = st.file_uploader("Or upload an image file", type=["jpg", "jpeg", "png"])
154
 
155
- # Encryption seed slider
156
  key_seed = st.slider("Encryption Key Seed (0 < seed < 1)", 0.001, 0.999, 0.5, step=0.001)
157
 
158
  if st.button("Detect & Encrypt"):
159
- # 1. Load the image from URL or file
160
  if image_url and not uploaded_file:
161
  try:
162
  response = requests.get(image_url, timeout=10)
@@ -173,7 +180,7 @@ def main():
173
 
174
  st.image(pil_image, caption="Original Image", use_container_width=True)
175
 
176
- # 2. Detect plates (includes debug print to logs)
177
  with st.spinner("Detecting license plates..."):
178
  image_with_boxes, bboxes = detect_license_plates(model, pil_image.copy())
179
 
@@ -182,7 +189,7 @@ def main():
182
  st.warning("No license plates detected.")
183
  return
184
 
185
- # 3. Encrypt bounding box regions
186
  with st.spinner("Encrypting license plates..."):
187
  np_img = np.array(pil_image)
188
  encrypted_np = np_img.copy()
@@ -195,7 +202,7 @@ def main():
195
 
196
  st.image(encrypted_image, caption="Encrypted Image", use_container_width=True)
197
 
198
- # 4. Download link
199
  buf = io.BytesIO()
200
  encrypted_image.save(buf, format="PNG")
201
  buf.seek(0)
 
6
  import io
7
  import random
8
 
9
+ ##############################################################################
10
+ # 1. Attempt to import YOLOv10 from the ultralytics package (THU-MIG/yolov10)
11
+ ##############################################################################
12
  try:
13
  from ultralytics import YOLOv10
14
  except ImportError:
15
+ st.error("Could not import YOLOv10. Please confirm THU-MIG/yolov10 installation in requirements.txt.")
16
  st.stop()
17
 
18
+ ##############################################################################
19
+ # 2. Chaotic Logistic Map Encryption Functions
20
+ ##############################################################################
 
21
  def logistic_map(r, x):
22
  return r * x * (1 - x)
23
 
 
26
  x = seed
27
  for _ in range(n):
28
  x = logistic_map(3.9, x)
29
+ key.append(int(x * 255) % 256)
30
  return np.array(key, dtype=np.uint8)
31
 
32
  def shuffle_pixels(img_array, seed):
 
65
 
66
  return doubly_encrypted_array
67
 
68
+ ##############################################################################
69
+ # 3. YOLOv10 License Plate Detection
70
+ ##############################################################################
 
71
  @st.cache_data(show_spinner=False)
72
  def load_model(weights_path: str):
73
  """
74
+ Loads the YOLOv10 model from local .pt weights (Ultralytics style).
75
  """
76
+ model = YOLOv10(weights_path) # e.g., 'best.pt'
77
  return model
78
 
79
  def detect_license_plates(model, pil_image):
80
  """
81
+ Runs YOLOv10 detection on the PIL image using ultralytics-style output:
82
+ results -> list of ultralytics.engine.results.Results
83
+ each Results has .boxes, .masks, .names, etc.
84
 
85
+ We'll handle only the first Results object (single image).
 
86
  """
87
  np_image = np.array(pil_image)
 
88
  results = model.predict(np_image)
89
 
90
+ # 1) Check how many Results objects we have
91
+ if not results:
92
+ print("No results returned by model.")
93
+ return pil_image, []
94
+
95
+ # 2) Take the first Results object
96
+ r = results[0]
97
 
98
+ # Debug: print the entire Results object
99
+ print("Raw model output (first Results object):", r)
 
 
 
 
100
 
101
+ # 3) If r.boxes is None or empty, we have no detections
102
+ if not hasattr(r, 'boxes') or r.boxes is None or len(r.boxes) == 0:
103
+ print("No boxes found in results[0].")
104
+ return pil_image, []
105
+
106
+ # 4) Parse bounding boxes
107
  bboxes = []
108
  draw = ImageDraw.Draw(pil_image)
109
 
110
+ # r.boxes is an ultralytics.engine.results.Boxes object
111
+ # We can iterate over each box in r.boxes:
112
+ for box in r.boxes:
113
+ # box has .xyxy, .conf, .cls as 1D tensors
114
+ # e.g. box.xyxy[0] is [x1, y1, x2, y2]
115
+ # box.conf[0] is confidence
116
+ # box.cls[0] is class ID
117
+ coords = box.xyxy[0].tolist() # [x1, y1, x2, y2]
118
+ conf = float(box.conf[0])
119
+ cls_id = int(box.cls[0])
120
+
121
+ # If your license plate class is 0:
122
+ if cls_id == 0:
123
+ x1, y1, x2, y2 = map(int, coords)
124
+ bboxes.append((x1, y1, x2, y2))
125
+
126
+ # Optional: draw bounding box for visualization
127
+ draw.rectangle([x1, y1, x2, y2], outline="red", width=2)
128
 
129
  return pil_image, bboxes
130
 
131
+ ##############################################################################
132
+ # 4. Streamlit App
133
+ ##############################################################################
 
134
  def main():
135
  st.title("YOLOv10 + Chaotic Encryption Demo")
136
  st.write(
 
142
  """
143
  )
144
 
145
+ # A. Model weights path
146
+ default_model_path = "best.pt"
147
  model_path = st.sidebar.text_input("YOLOv10 Weights (.pt)", value=default_model_path)
148
 
149
  if not os.path.isfile(model_path):
 
154
  model = load_model(model_path)
155
  st.success("Model loaded successfully!")
156
 
157
+ # B. Image input
158
  st.subheader("Image Input")
159
  image_url = st.text_input("Image URL (optional)")
160
  uploaded_file = st.file_uploader("Or upload an image file", type=["jpg", "jpeg", "png"])
161
 
162
+ # C. Encryption seed slider
163
  key_seed = st.slider("Encryption Key Seed (0 < seed < 1)", 0.001, 0.999, 0.5, step=0.001)
164
 
165
  if st.button("Detect & Encrypt"):
166
+ # 1) Load the image from URL or file
167
  if image_url and not uploaded_file:
168
  try:
169
  response = requests.get(image_url, timeout=10)
 
180
 
181
  st.image(pil_image, caption="Original Image", use_container_width=True)
182
 
183
+ # 2) Detect plates
184
  with st.spinner("Detecting license plates..."):
185
  image_with_boxes, bboxes = detect_license_plates(model, pil_image.copy())
186
 
 
189
  st.warning("No license plates detected.")
190
  return
191
 
192
+ # 3) Encrypt bounding box regions
193
  with st.spinner("Encrypting license plates..."):
194
  np_img = np.array(pil_image)
195
  encrypted_np = np_img.copy()
 
202
 
203
  st.image(encrypted_image, caption="Encrypted Image", use_container_width=True)
204
 
205
+ # 4) Download link
206
  buf = io.BytesIO()
207
  encrypted_image.save(buf, format="PNG")
208
  buf.seek(0)