[Python] How to detect if one segment is totally inside another segment in opencv

Discussão em 'Python' iniciado por Stack, Abril 4, 2025.

  1. Stack

    Stack Membro Participativo

    I am using a segmentation model to detect multiple classes in an image. Two classes can be in three different conditions:

    1. They can share a border:

    [​IMG]

    1. One class might be totally inside another class:

    [​IMG]

    1. Two classes can be totally distinct:

    [​IMG]

    Now I want to detect the second case where one class is totally inside another. Note that it is always the green one that will be inside. I can detect edge of the green layer and perform a cv2.pointPolygonTest() for each edge pixels. But I am looking for a faster way.

    Current method to check if green is inside:

    def is_totally_inside(red, green):
    green_edge = cv2.Canny(green, 0, 255)
    red_edge = cv2.Canny(red, 0, 255)
    red_contour, _ = cv2.findContours(red_edge, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    if len(red_contour) != 2:
    return False
    blank_image = np.zeros_like(green)
    green_edge_pixels = cv2.findNonZero(green_edge)
    for point in green_edge_pixels:
    point = tuple(point.squeeze().tolist())
    if cv2.pointPolygonTest(red_contour[0], point, measureDist=False) < 0 \
    or cv2.pointPolygonTest(red_contour[1], point, measureDist=False) < 0:
    return False
    return True


    Can be tested this way:

    green_inside_red = np.zeros((512, 512, 3), np.uint8)
    green_inside_red = cv2.circle(green_inside_red, (256, 256), 150, (255, 0, 0), -1)
    green_inside_red = cv2.circle(green_inside_red, (256, 256), 120, (0, 255, 0), -1)
    red = np.all(green_inside_red == [255, 0, 0], axis=-1).astype(np.uint8) * 255
    green = np.all(green_inside_red == [0, 255, 0], axis=-1).astype(np.uint8) * 255
    is_totally_inside(red, green) # True

    separate = np.zeros((512, 512, 3), np.uint8)
    separate = cv2.circle(separate.copy(), (100, 100), 100, (255, 0, 0), -1)
    separate = cv2.circle(separate.copy(), (400, 400), 100, (0, 255, 0), -1)
    red = np.all(separate == [255, 0, 0], axis=-1).astype(np.uint8) * 255
    green = np.all(separate == [0, 255, 0], axis=-1).astype(np.uint8) * 255
    is_totally_inside(red, green) # False

    Continue reading...

Compartilhe esta Página