Newer
Older
safe-algo-pro / common / detect_utils.py
import matplotlib.path as mpath


def is_within_alert_range(bbox, range):
    if range is None:
        return True
    bottom_left = [bbox[0], bbox[3]]
    bottom_right = [bbox[2], bbox[3]]

    in_fence = is_point_in_polygon(bottom_left, range) or is_point_in_polygon(bottom_right, range)
    return in_fence


def is_point_in_polygon(point, polygon):
    """
    判断点是否在多边形内

    参数:
    - point: 待判断的点,格式为(x, y)
    - polygon: 多边形的顶点坐标列表,格式为[(x1, y1), (x2, y2), ...]

    返回:
    - 如果点在多边形内,返回True;否则,返回False。
    """
    # 创建多边形路径对象
    # polygon = np.array(polygon, dtype=np.int32)
    #
    # hull = ConvexHull(polygon)
    # sorted_coordinates = polygon[hull.vertices]

    poly_path = mpath.Path(polygon)
    # 使用contains_point方法检查点是否在多边形内
    return poly_path.contains_point(point)


def intersection_area(bbox1, bbox2):
    # 计算两个坐标框的重叠面积
    x1, y1, x2, y2 = bbox1
    x3, y3, x4, y4 = bbox2

    xi1 = max(x1, x3)
    yi1 = max(y1, y3)
    xi2 = min(x2, x4)
    yi2 = min(y2, y4)

    width = max(0, xi2 - xi1)
    height = max(0, yi2 - yi1)

    return width * height


def bbox_area(bbox):
    # 计算坐标框的面积
    x1, y1, x2, y2 = bbox
    return (x2 - x1) * (y2 - y1)


def get_person_head(person_bbox, head_bboxes):
    best_head = None
    max_overlap = 0

    for head in head_bboxes:
        head_bbox = head.xyxy.cpu().squeeze()
        overlap_area = intersection_area(person_bbox, head_bbox)
        head_area = bbox_area(head_bbox)
        overlap_ratio = overlap_area / head_area

        if overlap_ratio >= 0.8 and (best_head is None or overlap_area > max_overlap or (
                overlap_area == max_overlap and float(head.conf) > float(best_head.conf))):
            best_head = head
            max_overlap = overlap_area
    return best_head