Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to paste a small image on another big image at center in python with an image processed with OpenCV?

I am learning OpenCV and tried to paste a small image over a large image. But, it showed an error as both the images should have an equal size. I have also tried to follow the suggestion provided (How to paste an image onto a larger image using Pillow?) and (How do you composite an image onto another image with PIL in Python?)

   import cv2 as cv
   from scipy import ndimage

   img1 = cv.imread('Please put your file name')

   top_left_x = min([x1,x2,x3,x4])
   top_left_y = min([y1,y2,y3,y4])
   bot_right_x = max([x1,x2,x3,x4])
   bot_right_y = max([y1,y2,y3,y4])

   y_right =bot_right_y + 1
   x_right =bot_right_x + 1

  cropped = img[top_left_y: y_right, top_left_x: x_right]

  rotate = ndimage.rotate(cropped, ang)

The final output image should be at centre.

like image 497
Rajkamal Mishra Avatar asked Jan 23 '26 22:01

Rajkamal Mishra


1 Answers

This is a Pure PIL solution:-

from PIL import Image

img1 = Image.open(r"Source_Image_path")

# The values used to crop the original image (will form a bbox)
x1, y1, x2, y2 = 10, 10, 400, 400

# The angle at which the cropped Image must be rotated
angle = 50

# cropping the original image 
img = img1.crop((x1, y1, x2, y2))

# Firstly converting the Image mode to RGBA, and then rotating it
img = img.convert("RGBA").rotate(angle, resample=Image.BICUBIC)

# calibrating the bbox for the beginning and end position of the cropped image in the original image 
# i.e the cropped image should lie in the center of the original image
x1 = int(.5 * img1.size[0]) - int(.5 * img.size[0])
y1 = int(.5 * img1.size[1]) - int(.5 * img.size[1])
x2 = int(.5 * img1.size[0]) + int(.5 * img.size[0])
y2 = int(.5 * img1.size[1]) + int(.5 * img.size[1])

# pasting the cropped image over the original image, guided by the transparency mask of cropped image
img1.paste(img, box=(x1, y1, x2, y2), mask=img)

# converting the final image into its original color mode, and then saving it
img1.convert(img1.mode).save("Destination_path")

INPUT IMAGE:-

enter image description here

OUTPUT IMAGE:-

enter image description here

The code itself is self explanatory, but you might be wondering why are we converting the cropped image back and forth to RGBA. The reason for that is, because if we rotate a non alpha image in PIL, we end up with black bars/edges on the image where the pixel values no longer exists (read this question for more). But if we do the same for an alpha image, i.e passing an alpha image via rotate() then the empty pixel values end up being fully transparent (or alpha = 0).

like image 141
Vasu Deo.S Avatar answered Jan 25 '26 10:01

Vasu Deo.S



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!