Skip to content

Instantly share code, notes, and snippets.

@shamilnabiyev
Created April 17, 2025 21:11
Show Gist options
  • Save shamilnabiyev/19c484c7ce4db63eae0de1322f3dd6f4 to your computer and use it in GitHub Desktop.
Save shamilnabiyev/19c484c7ce4db63eae0de1322f3dd6f4 to your computer and use it in GitHub Desktop.
Simple copy paste augmentation for YOLO object detection task
from PIL import Image
import random
def paste_image(source_path, target_path, position=None):
"""
Pastes a small source image onto a larger target image.
Parameters:
- source_path: Path to the small source image.
- target_path: Path to the larger target image.
- position: Optional; A tuple (x, y) specifying the top-left corner where the source image will be pasted.
If not provided, a random position will be chosen.
Returns:
- new_image: The newly created image with the source image pasted onto it.
- bbox_yolo: A tuple (x_center, y_center, width, height) representing the bounding box of the pasted image in YOLO format.
"""
# Open the source and target images
source_image = Image.open(source_path)
target_image = Image.open(target_path)
# Get the dimensions of the source and target images
source_width, source_height = source_image.size
target_width, target_height = target_image.size
# Choose a random position if not provided
if position is None:
max_x = target_width - source_width
max_y = target_height - source_height
if max_x < 0 or max_y < 0:
raise ValueError("The source image is larger than the target image.")
position = (random.randint(0, max_x), random.randint(0, max_y))
else:
# Ensure the specified position is within bounds
if position[0] < 0 or position[1] < 0 or position[0] + source_width > target_width or position[1] + source_height > target_height:
raise ValueError("The specified position is out of the target image bounds.")
# Paste the source image onto the target image
target_image.paste(source_image, position)
# Calculate the bounding box of the pasted image
left = position[0]
upper = position[1]
right = position[0] + source_width
lower = position[1] + source_height
bbox = (left, upper, right, lower)
# Convert the bounding box to YOLO format
x_center = (left + right) / 2 / target_width
y_center = (upper + lower) / 2 / target_height
width = source_width / target_width
height = source_height / target_height
bbox_yolo = (x_center, y_center, width, height)
return target_image, bbox, bbox_yolo
# Example usage
if __name__ == "__main__":
source_path = "path/to/small_image.png" # Replace with the path to your small source image
target_path = "path/to/large_image.png" # Replace with the path to your large target image
# Example with a specified position
new_image, bbox_yolo = paste_image(source_path, target_path, position=(50, 50))
new_image.save("path/to/new_image_specified_position.png") # Replace with the desired path to save the new image
print("Bounding box of the pasted image (specified position) in YOLO format:", bbox_yolo)
# Example with a random position
new_image, bbox_yolo = paste_image(source_path, target_path)
new_image.save("path/to/new_image_random_position.png") # Replace with the desired path to save the new image
print("Bounding box of the pasted image (random position) in YOLO format:", bbox_yolo)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment