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

Add crops = results.crop() dictionary #4676

Merged

Conversation

ELHoussineT
Copy link
Contributor

@ELHoussineT ELHoussineT commented Sep 5, 2021

Adding function that returns list of dicts containing cropped detections and their labels

        >>> result.get_cropped()
            [
                { 
                    'label': <label> <accuracy> 
                    'img': <cropped np image> 
                }, 
                { 
                    'label': <label> <accuracy> 
                    'img': <cropped np image> 
                }, 
                ...
            ]

🛠️ PR Summary

Made with ❤️ by Ultralytics Actions

🌟 Summary

Enhancements to image cropping and results output in the YOLOv5 model's inference display method.

📊 Key Changes

  • Added a crops list to gather crop data for images during inference.
  • Updated the image cropping logic to support conditional saving and added the cropped image data to the crops list.
  • Changed the crop method to return the crops list and support optional saving with a specified directory.

🎯 Purpose & Impact

  • 🔍 Clarity in Crop Outputs: Users now get detailed information about each crop, improving transparency regarding inference results.
  • 💾 Flexible Saving Options: The ability to choose whether to save cropped images or not adds flexibility for different user needs.
  • 🔄 Data Accessibility: By returning the crops list, downstream applications can easily utilize the cropping results for further processing or analysis.

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👋 Hello @ELHoussineT, thank you for submitting a 🚀 PR! To allow your work to be integrated as seamlessly as possible, we advise you to:

  • ✅ Verify your PR is up-to-date with origin/master. If your PR is behind origin/master an automatic GitHub actions rebase may be attempted by including the /rebase command in a comment body, or by running the following code, replacing 'feature' with the name of your local branch:
git remote add upstream https://github.com/ultralytics/yolov5.git
git fetch upstream
git checkout feature  # <----- replace 'feature' with local branch name
git rebase upstream/master
git push -u origin -f
  • ✅ Verify all Continuous Integration (CI) checks are passing.
  • ✅ Reduce changes to the absolute minimum required for your bug fix or feature addition. "It is not daily increase but daily decrease, hack away the unessential. The closer to the source, the less wastage there is." -Bruce Lee

@glenn-jocher
Copy link
Member

@ELHoussineT thanks for the PR! We can't accept this as-is because it is duplicating code and functionality, you should instead update the existing functionality to return the values you want. Details are below:

Existing display method handles all Detections object tasks like cropping:

yolov5/models/common.py

Lines 367 to 385 in fad57c2

def display(self, pprint=False, show=False, save=False, crop=False, render=False, save_dir=Path('')):
for i, (im, pred) in enumerate(zip(self.imgs, self.pred)):
str = f'image {i + 1}/{len(self.pred)}: {im.shape[0]}x{im.shape[1]} '
if pred.shape[0]:
for c in pred[:, -1].unique():
n = (pred[:, -1] == c).sum() # detections per class
str += f"{n} {self.names[int(c)]}{'s' * (n > 1)}, " # add to string
if show or save or render or crop:
annotator = Annotator(im, pil=not self.ascii)
for *box, conf, cls in reversed(pred): # xyxy, confidence, class
label = f'{self.names[int(cls)]} {conf:.2f}'
if crop:
save_one_box(box, im, file=save_dir / 'crops' / self.names[int(cls)] / self.files[i])
else: # all others
annotator.box_label(box, label, color=colors(cls))
im = annotator.im
else:
str += '(no detections)'

Existing .crop() method that you should simply update with your proposed functionality here:

yolov5/models/common.py

Lines 411 to 415 in fad57c2

def crop(self, save_dir='runs/detect/exp'):
save_dir = increment_path(save_dir, exist_ok=save_dir != 'runs/detect/exp', mkdir=True) # increment save_dir
self.display(crop=True, save_dir=save_dir) # crop results
LOGGER.info(f'Saved results to {save_dir}\n')

Thank you!

@ELHoussineT
Copy link
Contributor Author

Hi @glenn-jocher

Sure thing. I added the logic into existing functions (029401d).

I structured it in away that does not introduce radical change. The default save value is False in crop function; this would ensure that the code will not break for people used to the current version of the crop function.

@glenn-jocher
Copy link
Member

@ELHoussineT great, thanks for the updates, I will review these tomorrow!

The python crop return feature has been requested before so I think this is a good idea.

@ELHoussineT
Copy link
Contributor Author

@glenn-jocher Sure thing. I was actually quite surprised you didn't have this before.

@glenn-jocher
Copy link
Member

/rebase

@github-actions github-actions bot force-pushed the adding-get-cropped-functionality branch from ef5265f to 7bea695 Compare September 8, 2021 17:27
@glenn-jocher glenn-jocher changed the title Adding get cropped functionality Add crops = results.crops() dictionary Sep 8, 2021
@glenn-jocher glenn-jocher merged commit 0d8a184 into ultralytics:master Sep 8, 2021
@glenn-jocher
Copy link
Member

@ELHoussineT PR is merged. Thank you for your contributions to YOLOv5 🚀 and Vision AI ⭐

@glenn-jocher glenn-jocher changed the title Add crops = results.crops() dictionary Add crops = results.crop() dictionary Sep 8, 2021
@glenn-jocher
Copy link
Member

glenn-jocher commented Sep 8, 2021

PyTorch Hub tutorial updated with Usage example in https://docs.ultralytics.com/yolov5/tutorials/pytorch_hub_model_loading

Cropped Results

Results can be returned and saved as detection crops:

results = model(imgs)  # inference

crops = results.crop(save=True)  # cropped detections dictionary

@ELHoussineT
Copy link
Contributor Author

Thanks Glenn for sanitizing this.

@ELHoussineT ELHoussineT deleted the adding-get-cropped-functionality branch September 8, 2021 18:13
CesarBazanAV pushed a commit to CesarBazanAV/yolov5 that referenced this pull request Sep 29, 2021
* adding get cropped functionality

* Add target logic in existing functions

* Crops cleanup

* Add dictionary keys: conf, cls, box

* Bug fixes - avoid return after first image

Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com>
BjarneKuehl pushed a commit to fhkiel-mlaip/yolov5 that referenced this pull request Aug 26, 2022
* adding get cropped functionality

* Add target logic in existing functions

* Crops cleanup

* Add dictionary keys: conf, cls, box

* Bug fixes - avoid return after first image

Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants