ultralytics / yolov5

YOLOv5 πŸš€ in PyTorch > ONNX > CoreML > TFLite
https://docs.ultralytics.com
GNU Affero General Public License v3.0
50.65k stars 16.33k forks source link

Cropping bounding box in separate image #803

Closed kriskris1973 closed 3 years ago

kriskris1973 commented 4 years ago

Hello, I need help to edit detect.py for crop bounding boxes (detected object) as separate image. and save them in specific directory. My idea will be something below what does not work , off course.

Write results

            for *xyxy, conf, cls in det:
                if save_txt:  # Write to file
                    xywh = (xyxy2xywh(torch.tensor(xyxy).view(1, 4)) / gn).view(-1).tolist()  # normalized xywh
                    with open(txt_path + '.txt', 'a') as f:
                        f.write(('%g ' * 5 + '\n') % (cls, *xywh))  # label format

                if save_img or view_img:  # Add bbox to image
                    label = '%s %.2f' % (names[int(cls)], conf)
                    plot_one_box(xyxy, im0, label=label, color=colors[int(cls)], line_thickness=3)

                if save_obj:
                    x,y,w,h = int(xywh[0]), int(xywh[1]), int(xywh[2]), int(xywh[3])
                    img_=np.transpose(xyxy, (2, 1, 0))
                    crop_img=img_[y:y+ h, x:x + w] 
                    cv2.imwrite(names[int(cls)]+ '{:}.jpg'.format(i+1), crop_img)
github-actions[bot] commented 4 years ago

Hello @kriskris1973, thank you for your interest in our work! Please visit our Custom Training Tutorial to get started, and see our Jupyter Notebook Open In Colab, Docker Image, and Google Cloud Quickstart Guide for example environments.

If this is a bug report, please provide screenshots and minimum viable code to reproduce your issue, otherwise we can not help you.

If this is a custom model or data training question, please note Ultralytics does not provide free personal support. As a leader in vision ML and AI, we do offer professional consulting, from simple expert advice up to delivery of fully customized, end-to-end production solutions for our clients, such as:

For more information please visit https://www.ultralytics.com.

glenn-jocher commented 4 years ago

@kriskris1973 what's the use case exactly? For passing to a classifier training set? You should be aware that classifiers tend to benefit from added contextual space around the object they are classifying, which the default boxes will not provide, as they are optimized to perfectly enclose the object of interest.

kriskris1973 commented 4 years ago

@kriskris1973 what's the use case exactly? For passing to a classifier training set? You should be aware that classifiers tend to benefit from added contextual space around the object they are classifying, which the default boxes will not provide, as they are optimized to perfectly enclose the object of interest.

The use case is comparing detected object with something ( recommendation systems), so the default boxes will be prefect for that aim

glenn-jocher commented 4 years ago

@kriskris1973 hmm ok. Then the best way to do this would be to develop and test a PR, and then submit to us for review. The code you showed looks like the perfect place to implement it, and it can go along with a new argparser argument, i..e --save-boxes

AKHILzz12345 commented 4 years ago

Hello @kriskris1973 , can you give me the code for cropping the boxes and saving them?

kriskris1973 commented 4 years ago

Hello , @glenn-jocher , this is adds to detect.py file for cropping and saving detected object which works very well for me @AKHILzz12345 , sorry for late answer

forum_detect.txt

sourangshupal commented 4 years ago

@AKHILzz12345 Thanks for the code for cropping the bounding box..It is working fine

Xyonia commented 4 years ago

@AKHILzz12345 , @sourangshupal
Hello. Where you add this forum_detect.txt code exatly to use. On detect.py? and from where you added and what you have changed? Can you help me? Thanks in advance.

gregrutkowski13 commented 4 years ago

Update - For those that want to implement forum_detect.txt above into detect.py, this is how I did it. Every time I call detect.py I want individual .jpgs for each bounding box. Probably not the best solution for everyone but it works for my purpose. So I just manually made a separate output folder for all of the bboxes and added

save_obj = True #right above "if save_obj:"

Xyonia commented 4 years ago

where you add forum_detect.txt exactly on detect.py or can you share your detect.py please? @gregrutkowski13 ? Mine is always stopped working. I always get

for *xyxy, conf, cls in det:

TypeError: 'NoneType' object is not iterable

Error

gregrutkowski13 commented 4 years ago

where you add forum_detect.txt exactly on detect.py or can you share your detect.py please? @gregrutkowski13 ? Mine is always stopped working.

there is a #Write Results portion of the detect.py. you can replace this entire section with the forum_detect script and make sure save_obj = True above #write results if you would like individual bboxes every time you call detect.py. Make sure you change the write path for the individual bbox jpgs as well. This should be the bare minimum to generate cropped bboxes.

For me, I found the loop under "if save_obj:" was also iterating unnecessarily and causing new bboxes to overwrite others. Also you will have to change how the code indexes and assigns names to your individual bbox jpgs based on your classes/data.

glenn-jocher commented 4 years ago

All, if you want to extract boxes, you might want to just see the apply_classifier() function in detect.py. It extracts boxes for second stage classifier inference, but you can simply comment that part and replace it with a cv2.imwrite for the box.

https://github.com/ultralytics/yolov5/blob/83deec133d62021b496ba6cc475c38e717098053/detect.py#L79-L82

Xyonia commented 4 years ago

I am an idiot or something but i cannot achieve with that way. I tried to comment pred = apply_classifier(pred, modelc, img, im0s) then add cv2.imwrite() but i dont know the image name is it img,im0 or im0s or something else. I tried to comment out

modelc = load_classifier(name='resnet101', n=2) # initialize

modelc.load_state_dict(torch.load('weights/resnet101.pt', map_location=device)['model']) # load weights

modelc.to(device).eval()

these lines and add cv2.imwrite there and i cannot make it done. Somehow cv2. iwrite dows not work or i cannot place it to the right place. Please if anyone see that help me that such an easy task turns out a nightmare for. Thanks in advance.

github-actions[bot] commented 3 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

shivprasad94 commented 3 years ago

Hello , @glenn-jocher , this is adds to detect.py file for cropping and saving detected object which works very well for me @AKHILzz12345 , sorry for late answer

forum_detect.txt

worked well for me. thanks @kriskris1973

shivprasad94 commented 3 years ago

https://github.com/ultralytics/yolov5/issues/2608#issuecomment-809094537

here is the complete code changes link

glenn-jocher commented 3 years ago

@gregrutkowski13 @AKHILzz12345 @Xyonia @sourangshupal Prediction box cropping is now available in YOLOv5 via PR https://github.com/ultralytics/yolov5/pull/2827! PyTorch Hub models can use results.crop() or detect.py can be called with the --save-crop argument. Example usage:

python detect.py --save-crop
Screenshot 2021-04-20 at 23 50 51
manojkk1234 commented 2 years ago

you can use --save-crop to save the cropped images. Cropped images will be saved in yolov5/runs/detect/exp/crop

jmiller-dr commented 2 years ago

For those who use Python / PyTorch code (rather than the detect.py script), how do you save an image with results.crop()?

glenn-jocher commented 2 years ago

@jmiller-dr results.crop(save=True), or to specify save directory manually results.crop(save=True, save_dir='path/to/dir')

glenn-jocher commented 2 years ago

πŸ‘‹ Hello! Thanks for asking about cropping results with YOLOv5 πŸš€. Cropping bounding box detections can be useful for training classification models on box contents for example. This feature was added in PR https://github.com/ultralytics/yolov5/pull/2827. You can crop detections using either detect.py or YOLOv5 PyTorch Hub:

detect.py

Crops will be saved under runs/detect/exp/crops, with a directory for each class detected.

python detect.py --save-crop
Original Crop

YOLOv5 PyTorch Hub

Crops will be saved under runs/detect/exp/crops if save=True, and also returned as a dictionary with crops as numpy arrays.

import torch

# Model
model = torch.hub.load('ultralytics/yolov5', 'yolov5s')  # or yolov5m, yolov5l, yolov5x, custom

# Images
img = 'https://ultralytics.com/images/zidane.jpg'  # or file, Path, PIL, OpenCV, numpy, list

# Inference
results = model(img)

# Results
crops = results.crop(save=True) 
# -- or --
crops = results.crop(save=True, save_dir='runs/detect/exp')  # specify save dir

Good luck πŸ€ and let us know if you have any other questions!

jmiller-dr commented 2 years ago

Oh perfect! Thank you, that’s what I needed. On Sep 24, 2022 at 7:31 AM -0400, Glenn Jocher @.***>, wrote:

@jmiller-dr results.crop(save=True), or to specify save directory manually results.crop(save=True, save_dir='path/to/dir') β€” Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you were mentioned.Message ID: @.***>