| 400 | parent_area = max(1, int(pw * ph)) |
| 401 | horizontal = pw >= ph |
| 402 | ordered = sorted(boxes, key=lambda box: box[0] if horizontal else box[1]) |
| 403 | axis_len = max(pw, ph) |
| 404 | minor_len = max(1, min(pw, ph)) |
| 405 | min_minor = max(10, int(minor_len * 0.15)) |
| 406 | min_area = max(160, int(parent_area * 0.012)) |
| 407 | areas = [] |
| 408 | previous_end = None |
| 409 | |
| 410 | for box in ordered: |
| 411 | x, y, w, h = box |
| 412 | if w <= 0 or h <= 0: |
| 413 | return False |
| 414 | if x < px - 6 or y < py - 6 or (x + w) > (px + pw + 6) or (y + h) > (py + ph + 6): |
| 415 | return False |
| 416 | |
| 417 | area = int(w * h) |
| 418 | areas.append(area) |
| 419 | if area < min_area: |
| 420 | return False |
| 421 | if area > int(parent_area * 0.88): |
| 422 | return False |
| 423 | if (h if horizontal else w) < min_minor: |
| 424 | return False |
| 425 | |
| 426 | start = x if horizontal else y |
| 427 | end = start + (w if horizontal else h) |
| 428 | if previous_end is not None and start < previous_end - max(6, int(axis_len * 0.04)): |
| 429 | return False |
| 430 | previous_end = end |
| 431 | |
| 432 | if not areas: |
| 433 | return False |
| 434 | if min(areas) * 16 < max(areas): |
| 435 | return False |
| 436 | return True |
| 437 | |
| 438 | |
| 439 | def split_bbox_with_yellow_segments(crop, origin_x, origin_y, expected_count, horizontal): |
| 440 | h, w = crop.shape[:2] |
| 441 | if expected_count <= 0 or h <= 0 or w <= 0: |
| 442 | return [] |
| 443 | |
| 444 | boxes = [] |
| 445 | axis_len = w if horizontal else h |
| 446 | edges = np.linspace(0, axis_len, expected_count + 1).astype(int) |