Manvikk commited on
Commit
3b80c35
·
verified ·
1 Parent(s): b16a09b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +49 -49
app.py CHANGED
@@ -75,7 +75,7 @@ def custom_nms(preds, iou_threshold=0.3):
75
  return filtered_preds
76
 
77
  #########################################
78
- # 3. Processing Function with Homography Measurement
79
  #########################################
80
 
81
  def process_image(job_id, image_path, object_type):
@@ -109,12 +109,12 @@ def process_image(job_id, image_path, object_type):
109
  for prediction in predictions:
110
  try:
111
  x, y, width, height = prediction["x"], prediction["y"], prediction["width"], prediction["height"]
112
- # Convert center x,y and width, height to top-left and bottom-right coordinates
113
  x1 = int(round(x - width / 2))
114
  y1 = int(round(y - height / 2))
115
  x2 = int(round(x + width / 2))
116
  y2 = int(round(y + height / 2))
117
- # Clamp coordinates to the image dimensions
118
  x1 = max(0, min(x1, img_width - 1))
119
  y1 = max(0, min(y1, img_height - 1))
120
  x2 = max(0, min(x2, img_width - 1))
@@ -128,74 +128,74 @@ def process_image(job_id, image_path, object_type):
128
  continue
129
 
130
  box_detections = custom_nms(processed_preds, iou_threshold=0.3)
131
- jobs[job_id]['progress'] = 60
132
 
133
  # -------------------------------
134
- # Improved ArUco marker detection and homography computation
 
 
 
135
  # -------------------------------
136
- # Since your marker is 10 cm, we set:
137
- marker_real_width_cm = 10.0
138
- homography = None
139
- conversion_factor = None
140
  try:
141
  gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
142
  aruco_dict = cv2.aruco.getPredefinedDictionary(cv2.aruco.DICT_6X6_250)
143
- # Use DetectorParameters_create if available (for newer OpenCV versions)
144
  if hasattr(cv2.aruco, 'DetectorParameters_create'):
145
  aruco_params = cv2.aruco.DetectorParameters_create()
146
  else:
147
  aruco_params = cv2.aruco.DetectorParameters()
148
  corners, ids, _ = cv2.aruco.detectMarkers(gray, aruco_dict, parameters=aruco_params)
149
  if ids is not None and len(corners) > 0:
150
- # Use the first detected marker as reference
151
- marker_corners = corners[0].reshape((4, 2))
152
- cv2.aruco.drawDetectedMarkers(image, corners, ids)
153
- # Define destination points for a perfect square (e.g., 1000 x 1000 pixels)
154
- dest_size = 1000.0
155
- dst_pts = np.array([[0, 0],
156
- [dest_size, 0],
157
- [dest_size, dest_size],
158
- [0, dest_size]], dtype=np.float32)
159
- src_pts = marker_corners.astype(np.float32)
160
- homography = cv2.getPerspectiveTransform(src_pts, dst_pts)
161
- # In the warped image, the marker side is dest_size pixels,
162
- # which corresponds to 10 cm in real life.
163
- conversion_factor = marker_real_width_cm / dest_size # 10 cm / 1000 pixels = 0.01 cm per pixel
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
164
  else:
165
- homography = None
166
- conversion_factor = None
167
  except Exception as e:
168
- homography = None
169
- conversion_factor = None
 
170
 
171
- # Process each detected box
172
  for pred in box_detections:
173
  x1, y1, x2, y2 = pred["box"]
174
  label = pred["class"]
175
  confidence = pred["confidence"]
176
  cv2.rectangle(image, (x1, y1), (x2, y2), (0, 255, 0), 2)
177
-
178
- if homography is not None and conversion_factor is not None:
179
- # Warp the four corners of the bounding box using the homography
180
- pts = np.array([[x1, y1],
181
- [x2, y1],
182
- [x2, y2],
183
- [x1, y2]], dtype=np.float32).reshape(-1, 1, 2)
184
- warped_pts = cv2.perspectiveTransform(pts, homography).reshape(-1, 2)
185
- new_x1, new_y1 = np.min(warped_pts, axis=0)
186
- new_x2, new_y2 = np.max(warped_pts, axis=0)
187
- box_width_pixels = new_x2 - new_x1
188
- box_height_pixels = new_y2 - new_y1
189
- box_width_cm = box_width_pixels * conversion_factor
190
- box_height_cm = box_height_pixels * conversion_factor
191
- width_str = f"{box_width_cm:.1f}"
192
- height_str = f"{box_height_cm:.1f}"
193
- elif conversion_factor is not None:
194
- # Fallback: use direct pixel measurements
195
  box_width_pixels = x2 - x1
196
  box_height_pixels = y2 - y1
197
- box_width_cm = box_width_pixels * conversion_factor
198
- box_height_cm = box_height_pixels * conversion_factor
199
  width_str = f"{box_width_cm:.1f}"
200
  height_str = f"{box_height_cm:.1f}"
201
  else:
 
75
  return filtered_preds
76
 
77
  #########################################
78
+ # 3. Processing Function with Pose-based Measurement
79
  #########################################
80
 
81
  def process_image(job_id, image_path, object_type):
 
109
  for prediction in predictions:
110
  try:
111
  x, y, width, height = prediction["x"], prediction["y"], prediction["width"], prediction["height"]
112
+ # Convert from center (x, y) and width, height to top-left & bottom-right
113
  x1 = int(round(x - width / 2))
114
  y1 = int(round(y - height / 2))
115
  x2 = int(round(x + width / 2))
116
  y2 = int(round(y + height / 2))
117
+ # Clamp coordinates to image boundaries
118
  x1 = max(0, min(x1, img_width - 1))
119
  y1 = max(0, min(y1, img_height - 1))
120
  x2 = max(0, min(x2, img_width - 1))
 
128
  continue
129
 
130
  box_detections = custom_nms(processed_preds, iou_threshold=0.3)
131
+ jobs[job_id]['progress'] = 40
132
 
133
  # -------------------------------
134
+ # Use ArUco pose estimation to compute a conversion factor.
135
+ # IMPORTANT: For accurate measurement you need proper camera calibration.
136
+ # Replace the cameraMatrix and distCoeffs below with your calibrated parameters.
137
+ # Here we use an approximate calibration.
138
  # -------------------------------
139
+ marker_conversion_factor = None
 
 
 
140
  try:
141
  gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
142
  aruco_dict = cv2.aruco.getPredefinedDictionary(cv2.aruco.DICT_6X6_250)
 
143
  if hasattr(cv2.aruco, 'DetectorParameters_create'):
144
  aruco_params = cv2.aruco.DetectorParameters_create()
145
  else:
146
  aruco_params = cv2.aruco.DetectorParameters()
147
  corners, ids, _ = cv2.aruco.detectMarkers(gray, aruco_dict, parameters=aruco_params)
148
  if ids is not None and len(corners) > 0:
149
+ # Use the first detected marker
150
+ # --- IMPORTANT ---
151
+ # Define your camera calibration parameters below. These are only approximate.
152
+ fx = 1.2 * img_width
153
+ fy = 1.2 * img_height
154
+ cx = img_width / 2
155
+ cy = img_height / 2
156
+ cameraMatrix = np.array([[fx, 0, cx],
157
+ [0, fy, cy],
158
+ [0, 0, 1]], dtype=np.float32)
159
+ distCoeffs = np.zeros((5, 1), dtype=np.float32)
160
+ # Marker length in meters (10 cm = 0.10 m)
161
+ marker_length = 0.10
162
+ rvecs, tvecs, _ = cv2.aruco.estimatePoseSingleMarkers(corners, marker_length, cameraMatrix, distCoeffs)
163
+ # For the first marker:
164
+ rvec = rvecs[0]
165
+ tvec = tvecs[0]
166
+ # Define 3D coordinates for the marker's corners (in marker coordinate system)
167
+ obj_points = np.array([
168
+ [-marker_length/2, marker_length/2, 0],
169
+ [ marker_length/2, marker_length/2, 0],
170
+ [ marker_length/2, -marker_length/2, 0],
171
+ [-marker_length/2, -marker_length/2, 0]
172
+ ], dtype=np.float32)
173
+ projected_points, _ = cv2.projectPoints(obj_points, rvec, tvec, cameraMatrix, distCoeffs)
174
+ projected_points = projected_points.reshape((4,2))
175
+ # Compute the pixel distance between two adjacent projected corners (e.g. top edge)
176
+ pixel_distance = np.linalg.norm(projected_points[0] - projected_points[1])
177
+ # Since the marker is 10 cm wide, the conversion factor is:
178
+ marker_conversion_factor = 10.0 / pixel_distance # cm per pixel
179
+ # Optionally, draw the marker pose for visualization:
180
+ cv2.aruco.drawAxis(image, cameraMatrix, distCoeffs, rvec, tvec, 0.05)
181
  else:
182
+ marker_conversion_factor = None
 
183
  except Exception as e:
184
+ marker_conversion_factor = None
185
+
186
+ jobs[job_id]['progress'] = 60
187
 
188
+ # Process each detected box using the conversion factor from pose estimation.
189
  for pred in box_detections:
190
  x1, y1, x2, y2 = pred["box"]
191
  label = pred["class"]
192
  confidence = pred["confidence"]
193
  cv2.rectangle(image, (x1, y1), (x2, y2), (0, 255, 0), 2)
194
+ if marker_conversion_factor is not None:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
195
  box_width_pixels = x2 - x1
196
  box_height_pixels = y2 - y1
197
+ box_width_cm = box_width_pixels * marker_conversion_factor
198
+ box_height_cm = box_height_pixels * marker_conversion_factor
199
  width_str = f"{box_width_cm:.1f}"
200
  height_str = f"{box_height_cm:.1f}"
201
  else: