roboflow / supervision

We write your reusable computer vision tools. πŸ’œ
https://supervision.roboflow.com
MIT License
24.21k stars 1.8k forks source link

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

Open stevensagaert opened 3 months ago

stevensagaert commented 3 months ago

Search before asking

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?

Sapienscoding commented 1 month ago

Hi @stevensagaert, I'd like to help by submitting a PR

LinasKo commented 1 month ago

Hi @Sapienscoding,

I've assigned another issue to you. Let's go with one at a time.

LinasKo commented 1 month ago

Hi @stevensagaert πŸ‘‹

Apologies for the delay. If you're still keen, we'd be happy to include area occupation stats in our PolygonZone.

AyuK03 commented 1 month ago

Hi, it is my first time contributing to open source project and I would like to work on this issue. Please do guide me if possible. Thank you!

stevensagaert commented 1 month ago

Hi, I'll make some time in 2 weeks or so. Right now I'm too busy at work.


From: LinasKo @.> Sent: Tuesday, October 15, 2024 8:48 AM To: roboflow/supervision @.> Cc: Steven Sagaert @.>; Mention @.> Subject: Re: [roboflow/supervision] PolygonZone: estimate how much of the zone is occupied (Issue #1449)

CAUTION: This email originated from outside of the organization. Do not click links or open attachments unless you recognize the sender and know the content is safe.

Hi @stevensagaerthttps://github.com/stevensagaert πŸ‘‹

Apologies for the delay. If you're still keen, we'd be happy to include area occupation stats in our PolygonZone.

β€” Reply to this email directly, view it on GitHubhttps://github.com/roboflow/supervision/issues/1449#issuecomment-2413031995, or unsubscribehttps://github.com/notifications/unsubscribe-auth/A7A5SMGF3R5NLUEQ43D6KW3Z3S3CRAVCNFSM6AAAAABMQRAQWKVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDIMJTGAZTCOJZGU. You are receiving this because you were mentioned.Message ID: @.***>

AHB102 commented 2 weeks ago

@stevensagaert Can I resolve this issue ?

stevensagaert commented 2 weeks ago

You mean you want to implement it or just close it? I haven't had time to do it yet.

AHB102 commented 2 weeks ago

@stevensagaert I would like to try to implement it.

stevensagaert commented 2 weeks ago

Ok go ahead πŸ™‚. The bulk of the functionality is in the 2 functions I put in this issue. The rest should be just glue code.


From: Archit H Barve @.> Sent: Wednesday, October 30, 2024 10:01 AM To: roboflow/supervision @.> Cc: Steven Sagaert @.>; Mention @.> Subject: Re: [roboflow/supervision] PolygonZone: estimate how much of the zone is occupied (Issue #1449)

CAUTION: This email originated from outside of the organization. Do not click links or open attachments unless you recognize the sender and know the content is safe.

@stevensagaerthttps://github.com/stevensagaert I would like to try to implement it.

β€” Reply to this email directly, view it on GitHubhttps://github.com/roboflow/supervision/issues/1449#issuecomment-2446244157, or unsubscribehttps://github.com/notifications/unsubscribe-auth/A7A5SMB2O7BWFMEBCJGIMHLZ6CN6XAVCNFSM6AAAAABMQRAQWKVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDINBWGI2DIMJVG4. You are receiving this because you were mentioned.Message ID: @.***>

LinasKo commented 2 weeks ago

Hi @AHB102 πŸ‘‹

Assigning this to you.

Note that Detection can take one of 3 forms:

Ideally, this method should work regardless of detection type, but it's okay if it returns a slightly-approximated result.

You may find the polygon_to_mask method helpful. it resides in: supervision/detection/utils.py.

AHB102 commented 2 weeks ago

@LinasKo Thanks for the insight 😁, will get started on this.

AHB102 commented 2 weeks ago

@LinasKo Hi πŸ‘‹,I haven't written much code for this feature. I mostly used Steven's existing code, but I added checks for the detection cases based on your recommendations. Had some questions : 1)Type hinting: I wrote this feature in vanilla Python . I'm new to type hinting, is it still okay to use it ? 2)Code location: I put the feature code in β€œsupervision/detection/utils.py”, outside of the PolygonZone class. Is that the right place? 3)Testing: How do I test the feature? Can I use import statements, or is there a preferred way to write tests before submitting a pull request (PR)?

LinasKo commented 2 weeks ago

Hi @AHB102 πŸ‘‹

  1. Ideally, we'd love a bit of type hinting at least in function definitions. For arguments, it's as simple as adding : int, : str, : List[str] and so on. For numpy arrays it's fine to say np.ndarray. Return type is -> int: and so on. You can do -> None: if it returns nothing. I'd encourage you to try!
  2. I think so, but I'll need to see the PR first.
  3. We encourage making a Google Colab and showing how it works. If you want, you can use this Starter Template. There's no PolygonZone examples, but you can find some in the docs, the cheatsheet or a notebook. Try to come up with a situation where you can detect something in an image, and actually check the polygon zone occupancy. I suggest using Ultralytics for detection at the moment. Let me know how it goes, and if you can't figure it out πŸ˜‰
AHB102 commented 2 weeks ago

Okay nice! Will definitely make the type hinting work, and can I commit the changes and make a PR ?

LinasKo commented 2 weeks ago

Yes, absolutely. Typically contributors fork the repo, make the changes their version of it, on a branch such as feat/estimate-polygonzone-occupation, and then open a PR via github website to supervision's develop (there should be a button, as soon as you push to your own fork).

AHB102 commented 5 days ago

@LinasKo I got a bit lost in the first PR. I believe this one is correct. Thanks for your patienceπŸ˜…

LinasKo commented 5 days ago

Thank you @AHB102!

I'll have a look as soon as I can, likely next week.