Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PolygonZone: estimate how much of the zone is occupied #1449

Open
2 tasks done
stevensagaert opened this issue Aug 14, 2024 · 0 comments
Open
2 tasks done

PolygonZone: estimate how much of the zone is occupied #1449

stevensagaert opened this issue Aug 14, 2024 · 0 comments
Labels
enhancement New feature or request

Comments

@stevensagaert
Copy link

stevensagaert commented Aug 14, 2024

Search before asking

  • I have searched the Supervision issues and found no similar feature requests.

Description

Next to the count of the objects in the zone, it would be useful to know how much of the zone area is occupied by the objects.

Use case

e.g. for loading zones in warehouses

Additional

Basically I've implemented it myself outside of the PolygonZone class. The core of what is needed is these two functions:

def polygon_to_binary_mask(img,contour):
    """convert bounding polygon coord to binary mask"""
    # Create binary mask
    b_mask = np.zeros(img.shape[:2], np.uint8)

    #  Extract contour result
    #contour = c.masks.xy.pop()
    #  Changing the type
    contour = contour.astype(np.int32) #Note: This must be int32 and not unit8!!!
    #  Reshaping
    contour = contour.reshape(-1, 1, 2)


    # Draw contour onto mask
    mask = cv2.drawContours(b_mask, [contour], -1, (1, 1, 1), cv2.FILLED)
    return mask

strategy:

  1. make union of binary masks of detected objects (only the classes for consideration in zone)
  2. make binary mask of the zone
  3. do and of zone mask & object masks
  4. sum the 1 pixels
def calculate_overlap_area(zone_mask, masks,show_plot=True):
    """calculate how much % of the zone is occupied"""
    #create one mask from the object masks as the union
    union_mask=np.bitwise_or.reduce(np.stack(masks),axis=0)
    #for debugging
    if show_plot:
        plt.title("union object mask")
        plt.imshow(union_mask,cmap='gray')
        plt.show()
    

    #do the bitwise and between union_mask & zone_mask
    overlap_mask=np.bitwise_and(union_mask,zone_mask)
    print(f"overlap_mask shape {overlap_mask.shape}")
    if show_plot:
        plt.title("overlap mask")
        plt.imshow(union_mask,cmap='gray')
        plt.show()
    
    overlap_size= np.sum(overlap_mask)
    zone_size=np.sum(zone_mask)
    return 100*overlap_size/zone_size

Are you willing to submit a PR?

  • Yes I'd like to help by submitting a PR!
@stevensagaert stevensagaert added the enhancement New feature or request label Aug 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant