PaulMartrenchar commited on
Commit
a0612ff
·
1 Parent(s): a73c25c

filter less the cards

Browse files
Files changed (1) hide show
  1. app.py +15 -15
app.py CHANGED
@@ -85,47 +85,47 @@ def detect_cards_and_sum(image, game):
85
  H, W = annotated.shape[:2]
86
  img_area = float(H * W)
87
 
88
- # --- robust edge map for rectangles ---
89
  gray = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2GRAY)
90
- gray = cv2.GaussianBlur(gray, (5, 5), 0)
91
- edges = cv2.Canny(gray, 60, 160)
92
  edges = cv2.dilate(edges, np.ones((3, 3), np.uint8), iterations=1)
93
 
94
  contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
95
 
 
 
 
96
  values = []
97
- drawn_boxes = 0
98
 
99
  for cnt in contours:
100
- # geometric filtering
101
- rect = cv2.minAreaRect(cnt) # (center, (w, h), angle)
102
  (cx, cy), (rw, rh), _ = rect
103
  if rw == 0 or rh == 0:
104
  continue
105
 
106
- box = cv2.boxPoints(rect) # 4 points, unordered
107
  box = np.int32(box)
108
 
109
- # use bounding area (more stable with edges than contour area)
110
  box_area = rw * rh
111
- if box_area < 0.01 * img_area or box_area > 0.8 * img_area:
112
  continue # too small or too big to be a card
113
 
114
- # aspect ratio (card ~ 1.41.8 between long/short edges)
115
  long_side = max(rw, rh)
116
  short_side = min(rw, rh)
117
  ratio = long_side / short_side
118
- if ratio < 1.2 or ratio > 1.9:
119
  continue
120
 
121
  # rectangularity: contour area close to its minAreaRect area
122
  cnt_area = cv2.contourArea(cnt)
123
- if cnt_area / box_area < 0.65:
124
  continue
125
 
126
  # perspective warp to a canonical card size (2:3 ratio)
127
  dst_w, dst_h = 300, 450
128
- M = cv2.getPerspectiveTransform(order_points(box),
129
  np.array([[0, 0],
130
  [dst_w-1, 0],
131
  [dst_w-1, dst_h-1],
@@ -151,9 +151,8 @@ def detect_cards_and_sum(image, game):
151
  ty = int(moments["m01"] / moments["m00"])
152
  else:
153
  tx, ty = int(cx), int(cy)
154
- cv2.putText(annotated, str(val), (tx - 10, ty - 10),
155
  cv2.FONT_HERSHEY_SIMPLEX, 1.2, (0, 0, 255), 3)
156
- drawn_boxes += 1
157
 
158
  if not values:
159
  # return the annotated image anyway so you can see what was (not) detected
@@ -166,6 +165,7 @@ def detect_cards_and_sum(image, game):
166
 
167
 
168
 
 
169
  # Gradio UI
170
  with gr.Blocks() as demo:
171
  gr.Markdown("## Card Value Detector (Skyjo / Flip7)")
 
85
  H, W = annotated.shape[:2]
86
  img_area = float(H * W)
87
 
88
+ # --- edge map ---
89
  gray = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2GRAY)
90
+ blur = cv2.GaussianBlur(gray, (5, 5), 0)
91
+ edges = cv2.Canny(blur, 50, 150)
92
  edges = cv2.dilate(edges, np.ones((3, 3), np.uint8), iterations=1)
93
 
94
  contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
95
 
96
+ # sort largest to smallest
97
+ contours = sorted(contours, key=cv2.contourArea, reverse=True)
98
+
99
  values = []
 
100
 
101
  for cnt in contours:
102
+ rect = cv2.minAreaRect(cnt)
 
103
  (cx, cy), (rw, rh), _ = rect
104
  if rw == 0 or rh == 0:
105
  continue
106
 
107
+ box = cv2.boxPoints(rect)
108
  box = np.int32(box)
109
 
 
110
  box_area = rw * rh
111
+ if box_area < 0.002 * img_area or box_area > 0.9 * img_area:
112
  continue # too small or too big to be a card
113
 
114
+ # aspect ratio (card ~ 1.41.8 between long/short edges)
115
  long_side = max(rw, rh)
116
  short_side = min(rw, rh)
117
  ratio = long_side / short_side
118
+ if ratio < 1.1 or ratio > 2.2:
119
  continue
120
 
121
  # rectangularity: contour area close to its minAreaRect area
122
  cnt_area = cv2.contourArea(cnt)
123
+ if cnt_area / box_area < 0.5:
124
  continue
125
 
126
  # perspective warp to a canonical card size (2:3 ratio)
127
  dst_w, dst_h = 300, 450
128
+ M = cv2.getPerspectiveTransform(order_points(box),
129
  np.array([[0, 0],
130
  [dst_w-1, 0],
131
  [dst_w-1, dst_h-1],
 
151
  ty = int(moments["m01"] / moments["m00"])
152
  else:
153
  tx, ty = int(cx), int(cy)
154
+ cv2.putText(annotated, str(val), (tx-10, ty-10),
155
  cv2.FONT_HERSHEY_SIMPLEX, 1.2, (0, 0, 255), 3)
 
156
 
157
  if not values:
158
  # return the annotated image anyway so you can see what was (not) detected
 
165
 
166
 
167
 
168
+
169
  # Gradio UI
170
  with gr.Blocks() as demo:
171
  gr.Markdown("## Card Value Detector (Skyjo / Flip7)")