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

How to crop the detected object after training using YOLO? #5412

Closed
1 task done
samahwaleed opened this issue Oct 31, 2021 · 16 comments
Closed
1 task done

How to crop the detected object after training using YOLO? #5412

samahwaleed opened this issue Oct 31, 2021 · 16 comments
Labels
question Further information is requested Stale

Comments

@samahwaleed
Copy link

Search before asking

Question

I am using YOLO for model training. I used save-txt to save the results in txt files. I want to crop the detected object and get the pixel values for each detected object from the txt file. The txt file has labeled, bbox coordinates and score.

Any help would be highly appreciated!

Additional

No response

@samahwaleed samahwaleed added the question Further information is requested label Oct 31, 2021
@glenn-jocher
Copy link
Member

glenn-jocher commented Oct 31, 2021

@samahwaleed 👋 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 #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 .show(), .save(), .print(), .pandas(), etc.

Good luck and let us know if you have any other questions!

@samahwaleed
Copy link
Author

samahwaleed commented Oct 31, 2021

Thank you. but I want to crop the images using the results saved in txt file.
This is my code:

`import glob
import cv2 as cv
import matplotlib.pyplot as plt
import PIL
import numpy as np


path = glob.glob("/content/yolov5/runs/detect/exp/FrameVid1_185.JPG")


 for img in path:
    
     imgs = PIL.Image.open(img).convert('RGB')
     image_width, image_height = imgs.size
     imgArrays = np.array(imgs)
     X = (df.iloc[0:, 1]*image_width).astype(int)
     Y = (df.iloc[0:, 2]*image_height).astype(int)
     W = (df.iloc[0:, 3]*image_width).astype(int)
     H = (df.iloc[0:, 4]*image_height).astype(int)
     
     cropped_image = np.zeros(imgs.size)
     for i in range(len(X)):
       cropped_image[Y[i]: H[i], X[i]: W[i]] = imgArrays[Y[i]: H[i], X[i]: W[i]]
      
     cv2.imshow('Cropped Image', cropped_image)`

I got this error,

ValueError: could not broadcast input array from shape (0,0,3) into shape (0,0)

@glenn-jocher
Copy link
Member

@samahwaleed crops are produced by the same text file predictions, but sure you can write your own script to do this as well.

@samahwaleed
Copy link
Author

samahwaleed commented Nov 2, 2021

This is my code.

path = glob.glob("/content/yolov5/runs/detect/exp/*.jpg")
 cropped_images =[]

for img in path:
  
   imgs = PIL.Image.open(img).convert('RGB')
   image_width, image_height = imgs.size
   imgArrays = np.array(imgs)

   #image coordinates:
   #(left, right, top, bottom) = (xmin * im_width, xmax * im_width, ymin * im_height, ymax * im_height)
  
   X = (x_min*image_width)          #left
   Y = (y_min*image_height)         #top
   W = (x_max*image_width)          #right
   H = (y_max*image_height)         #bottom
   cropped_image = np.zeros((image_height, image_width, 3))
      
   for i in range(len(X)):
            x1, y1, w, h = X[i], Y[i], W[i], H[i]
            x_start = int(torch.round(x1 - (w/2)))
            y_start = int(torch.round(y1 - (h/2)))
            x_end = int(torch.round(x_start + w))
            y_end = int(torch.round(y_start + h))
            
            temp = imgArrays[y_start: y_end, x_start: x_end]
            cropped_images = temp

@github-actions
Copy link
Contributor

github-actions bot commented Dec 3, 2021

👋 Hello, this issue has been automatically marked as stale because it has not had recent activity. Please note it will be closed if no further activity occurs.

Access additional YOLOv5 🚀 resources:

Access additional Ultralytics ⚡ resources:

Feel free to inform us of any other issues you discover or feature requests that come to mind in the future. Pull Requests (PRs) are also always welcomed!

Thank you for your contributions to YOLOv5 🚀 and Vision AI ⭐!

@github-actions github-actions bot added the Stale label Dec 3, 2021
@github-actions github-actions bot closed this as completed Dec 8, 2021
@Raymon360
Copy link

is there a method to cut-save multiple files in multiple folders?

@glenn-jocher
Copy link
Member

@Raymon360 👋 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 #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 .show(), .save(), .print(), .pandas(), etc.

Good luck 🍀 and let us know if you have any other questions!

@Arsmart1
Copy link

Arsmart1 commented Oct 9, 2022

can we only detect 'person' class and only save this class? Thank you!!!

@Laughing-q
Copy link
Member

Laughing-q commented Oct 9, 2022

@Arsmart1

python detect.py --source data/images --weights yolov5s.pt --classes 0

this might help you, use --classes option to chose which class you want to detect.

@JJ-McClure
Copy link

I just want to chime in that cropping the image using the coordinates from the txt-file does not give the same image as using the save-crops function. The save-crops function result in a slightly bigger crop compared to just using the coordinates. This can be a very important distinction for small detections/images and sequential yolo detections

@varunpusarla
Copy link

Is there a better of way of doing this in YOLOv8 ?

@glenn-jocher
Copy link
Member

@varunpusarla hello,

YOLOv8 is not an existing version of YOLO. The latest version is YOLOv5, which is currently maintained by Ultralytics. With YOLOv5, you can detect objects in images and videos using pre-trained models or custom trained models with your own dataset.

If you have any specific questions about implementation or functionality with YOLOv5, feel free to ask and we'll be happy to help.

Best regards.

@NawoyaSarah
Copy link

@glenn-jocher how can i maintain scale during cropping? because the generated crops vary in dimensions, yet i wound want to use the generated crops to measure object size. hence the dimensions need to be same scale

@glenn-jocher
Copy link
Member

@Sarai256 you can maintain the scale during cropping by calculating the width and height of the crop based on a fixed aspect ratio or a fixed scale factor. For example, if you want to maintain a fixed aspect ratio (e.g., 1:1) during cropping, you can calculate the width and height of the crop based on the longer side of the bounding box. Alternatively, if you want to maintain a fixed scale factor (e.g., 0.5), you can scale the width and height of the crop based on the original width and height of the image. By applying these calculations, you can ensure that the dimensions of the generated crops are in the same scale as the original objects.

@NawoyaSarah
Copy link

@glenn-jocher , thank you for the reply. however I am not sure to which part of the code i should include the scale factor,
Example: python detect.py --save-crop..
Do i include the scale in that command? I am a beginner

@glenn-jocher
Copy link
Member

@Sarai256 Thank you for reaching out! In order to maintain a specific scale during cropping, you would need to modify the code in the detect.py file.

The command python detect.py --save-crop does not have a built-in option to specify a scale factor. To achieve the desired scale, you would need to make changes in the code itself.

One way to implement scaling is by modifying the cropping logic in the detect.py file. Specifically, you can calculate the width and height of the crop based on the scale factor you want to maintain. You can then adjust the cropping coordinates accordingly.

If you are a beginner, I would recommend going through the detect.py code and understanding how the cropping is currently implemented. From there, you can make the necessary modifications to introduce the desired scaling functionality.

Feel free to ask any further questions if you need any clarification or assistance with the code. Happy coding!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested Stale
Projects
None yet
Development

No branches or pull requests

8 participants