验证CV检测到的矩形是否有效 检查内容: 1. 内部颜色是否有足够变化(排除纯色背景误检) 2. 边框与内部是否有明显区别 :param cv2_image: BGR图像 :param bbox: [x1, y1, x2, y2] :param min_std: 最小颜色标准差 :return: True=有效, False=可能是误检
(cv2_image: np.ndarray, bbox: list, min_std: float = 8)
| 755 | |
| 756 | # ======================== CV结果验证 ======================== |
| 757 | def _validate_cv_rectangle(cv2_image: np.ndarray, bbox: list, min_std: float = 8) -> bool: |
| 758 | """ |
| 759 | 验证CV检测到的矩形是否有效 |
| 760 | |
| 761 | 检查内容: |
| 762 | 1. 内部颜色是否有足够变化(排除纯色背景误检) |
| 763 | 2. 边框与内部是否有明显区别 |
| 764 | |
| 765 | :param cv2_image: BGR图像 |
| 766 | :param bbox: [x1, y1, x2, y2] |
| 767 | :param min_std: 最小颜色标准差 |
| 768 | :return: True=有效, False=可能是误检 |
| 769 | """ |
| 770 | x1, y1, x2, y2 = map(int, bbox) |
| 771 | h, w = cv2_image.shape[:2] |
| 772 | |
| 773 | # 边界检查 |
| 774 | x1, y1 = max(0, x1), max(0, y1) |
| 775 | x2, y2 = min(w, x2), min(h, y2) |
| 776 | |
| 777 | if x2 - x1 < 20 or y2 - y1 < 20: |
| 778 | return False |
| 779 | |
| 780 | roi = cv2_image[y1:y2, x1:x2] |
| 781 | gray_roi = cv2.cvtColor(roi, cv2.COLOR_BGR2GRAY) |
| 782 | |
| 783 | # 检查1:内部是否有足够的颜色变化 |
| 784 | roi_h, roi_w = gray_roi.shape |
| 785 | margin = max(3, min(roi_w, roi_h) // 10) |
| 786 | |
| 787 | if roi_h > 2 * margin and roi_w > 2 * margin: |
| 788 | inner = gray_roi[margin:-margin, margin:-margin] |
| 789 | inner_std = np.std(inner) |
| 790 | |
| 791 | # 如果内部颜色太均匀,可能是误检的背景区域 |
| 792 | if inner_std < min_std: |
| 793 | return False |
| 794 | |
| 795 | # 检查2:边框与内部是否有对比度 |
| 796 | border_size = max(2, min(roi_w, roi_h) // 20) |
| 797 | |
| 798 | if roi_h > 2 * border_size and roi_w > 2 * border_size: |
| 799 | border_top = gray_roi[:border_size, :].mean() |
| 800 | border_bottom = gray_roi[-border_size:, :].mean() |
| 801 | border_left = gray_roi[:, :border_size].mean() |
| 802 | border_right = gray_roi[:, -border_size:].mean() |
| 803 | border_mean = np.mean([border_top, border_bottom, border_left, border_right]) |
| 804 | |
| 805 | inner_region = gray_roi[border_size:-border_size, border_size:-border_size] |
| 806 | inner_mean = inner_region.mean() |
| 807 | |
| 808 | contrast = abs(border_mean - inner_mean) |
| 809 | |
| 810 | # 边框和内部需要有一定对比度 |
| 811 | if contrast < 5: |
| 812 | return False |
| 813 | |
| 814 | return True |
no outgoing calls
no test coverage detected