phyloforfun commited on
Commit
08d4311
·
1 Parent(s): 007b2fe
Files changed (1) hide show
  1. app.py +29 -24
app.py CHANGED
@@ -126,13 +126,16 @@ def get_points_from_contours(contours):
126
  centroids = [get_centroid(contour) for contour in contours if get_centroid(contour) is not None]
127
  return centroids
128
 
129
- def sort_points_clockwise(centroids):
130
- # Compute the centroid of the centroids
131
- centroid_x = sum(x for x, y in centroids) / len(centroids)
132
- centroid_y = sum(y for x, y in centroids) / len(centroids)
133
- # Sort the centroids
134
- centroids.sort(key=lambda point: (-math.atan2(point[1] - centroid_y, point[0] - centroid_x)) % (2 * np.pi))
135
- return centroids
 
 
 
136
 
137
  def create_polygon_mask(centroids, flag_mask_shape):
138
  # Create a polygon mask using the sorted centroids
@@ -204,37 +207,39 @@ def process_image(image_path, flag_lower, flag_upper, plant_lower, plant_upper,
204
 
205
  # Logic to handle cases where there are more than 4 significant contours
206
  if len(significant_contours) < 4:
207
- st.error("Not enough points to form a quadrilateral.")
 
208
  return None, None, None, None, None, None, None, None, None, None
209
- elif len(significant_contours) > 4:
210
- # Create all possible combinations of four points
211
- point_combinations = list(itertools.combinations(significant_contours, 4))
212
- selected_quad_index = 0 # Placeholder for quadrilateral indices
213
- centroids = get_points_from_contours(point_combinations[selected_quad_index])
214
- centroids = sort_points_clockwise(centroids)
 
 
 
 
 
 
 
215
  # Function to update displayed quadrilateral based on selected index
216
  def update_displayed_quadrilateral(index):
217
  # Extract the four points of the current quadrilateral
218
- centroids = get_points_from_contours(point_combinations[index])
219
  return centroids
220
 
221
  # Show initial quadrilateral
222
  centroids = update_displayed_quadrilateral(selected_quad_index)
223
 
224
  with btn_back:
225
- # Button to go to the previous quadrilateral
226
  if st.button('Previous'):
227
  selected_quad_index = max(selected_quad_index - 1, 0)
228
- centroids = update_displayed_quadrilateral(selected_quad_index)
229
-
230
  with btn_next:
231
- # Button to go to the next quadrilateral
232
  if st.button('Next'):
233
- selected_quad_index = min(selected_quad_index + 1, len(point_combinations) - 1)
234
- centroids = update_displayed_quadrilateral(selected_quad_index)
235
- else:
236
- centroids = get_points_from_contours(significant_contours)
237
- centroids = sort_points_clockwise(centroids)
238
 
239
  poly_mask = create_polygon_mask(centroids, flag_mask.shape)
240
 
 
126
  centroids = [get_centroid(contour) for contour in contours if get_centroid(contour) is not None]
127
  return centroids
128
 
129
+ # Function to check if a quadrilateral is valid (i.e., no sides intersect)
130
+ def is_valid_quadrilateral(pts):
131
+ def ccw(A, B, C):
132
+ return (C[1] - A[1]) * (B[0] - A[0]) > (B[1] - A[1]) * (C[0] - A[0])
133
+
134
+ def intersect(A, B, C, D):
135
+ return ccw(A, C, D) != ccw(B, C, D) and ccw(A, B, C) != ccw(A, B, D)
136
+
137
+ A, B, C, D = pts
138
+ return not (intersect(A, B, C, D) or intersect(A, D, B, C))
139
 
140
  def create_polygon_mask(centroids, flag_mask_shape):
141
  # Create a polygon mask using the sorted centroids
 
207
 
208
  # Logic to handle cases where there are more than 4 significant contours
209
  if len(significant_contours) < 4:
210
+ with loc:
211
+ st.info("Not enough points to form a quadrilateral.")
212
  return None, None, None, None, None, None, None, None, None, None
213
+ else:
214
+ # Generate all permutations of four points
215
+ permutations_of_four = list(itertools.permutations(significant_contours, 4))
216
+ valid_quadrilaterals = [perm for perm in permutations_of_four if is_valid_quadrilateral(get_points_from_contours(perm))]
217
+
218
+ if not valid_quadrilaterals:
219
+ with loc:
220
+ st.info("No valid quadrilaterals found.")
221
+ return None, None, None, None, None, None, None, None, None, None
222
+
223
+ # Initial quadrilateral index
224
+ selected_quad_index = 0
225
+ centroids = get_points_from_contours(valid_quadrilaterals[selected_quad_index]))
226
  # Function to update displayed quadrilateral based on selected index
227
  def update_displayed_quadrilateral(index):
228
  # Extract the four points of the current quadrilateral
229
+ centroids = get_points_from_contours(valid_quadrilaterals[index])
230
  return centroids
231
 
232
  # Show initial quadrilateral
233
  centroids = update_displayed_quadrilateral(selected_quad_index)
234
 
235
  with btn_back:
 
236
  if st.button('Previous'):
237
  selected_quad_index = max(selected_quad_index - 1, 0)
238
+ update_displayed_quadrilateral(selected_quad_index)
 
239
  with btn_next:
 
240
  if st.button('Next'):
241
+ selected_quad_index = min(selected_quad_index + 1, len(valid_quadrilaterals) - 1)
242
+ update_displayed_quadrilateral(selected_quad_index)
 
 
 
243
 
244
  poly_mask = create_polygon_mask(centroids, flag_mask.shape)
245