Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Blend overlapping images in python

I am taking two images in python and overlapping the first image onto the second image. What I would like to do is blend the images where they overlap. Is there a way to do this in python other than a for loop?

like image 889
Tim R Avatar asked Mar 17 '15 18:03

Tim R


People also ask

How do you overlay an image on another image in Python?

Firstly we opened the primary image and saved its image object into variable img1. Then we opened the image that would be used as an overlay and saved its image object into variable img2. Then we called the paste method to overlay/paste the passed image on img1.

How do you blend photos?

Image Blending is mixing two images of the corresponding pixel values to create a new target image. The concept of blending images is comparatively very easy. To achieve this, we can simply make a copy of an image and transfer each source pixel's values into a pixel in the target image.

How do I superimpose two images in OpenCV?

These are the steps taken to overlay one image over another in Python OpenCV. First, we will load both images using the imread() method. Next, we will blend the image using the cv2. addWeighted() method.


2 Answers

PIL has a blend function which combines two RGB images with a fixed alpha:

out = image1 * (1.0 - alpha) + image2 * alpha

However, to use blend, image1 and image2 must be the same size. So to prepare your images you'll need to paste each of them into a new image of the appropriate (combined) size.

Since blending with alpha=0.5 averages the RGB values from both images equally, we need to make two versions of the panorama -- one with img1 one top and one with img2 on top. Then regions with no overlap have RGB values which agree (so their averages will remain unchanged) and regions of overlap will get blended as desired.


import operator
from PIL import Image
from PIL import ImageDraw

# suppose img1 and img2 are your two images
img1 = Image.new('RGB', size=(100, 100), color=(255, 0, 0))
img2 = Image.new('RGB', size=(120, 130), color=(0, 255, 0))

# suppose img2 is to be shifted by `shift` amount 
shift = (50, 60)

# compute the size of the panorama
nw, nh = map(max, map(operator.add, img2.size, shift), img1.size)

# paste img1 on top of img2
newimg1 = Image.new('RGBA', size=(nw, nh), color=(0, 0, 0, 0))
newimg1.paste(img2, shift)
newimg1.paste(img1, (0, 0))

# paste img2 on top of img1
newimg2 = Image.new('RGBA', size=(nw, nh), color=(0, 0, 0, 0))
newimg2.paste(img1, (0, 0))
newimg2.paste(img2, shift)

# blend with alpha=0.5
result = Image.blend(newimg1, newimg2, alpha=0.5)

img1:

enter image description here

img2:

enter image description here

result:

enter image description here


If you have two RGBA images here is a way to perform alpha compositing.

like image 172
unutbu Avatar answered Oct 08 '22 13:10

unutbu


If you'd like a soft edge when stitching two images together you could blend them with a sigmoid function.

Here is a simple grayscale example:

import numpy as np
import matplotlib.image
import math

def sigmoid(x):
  y = np.zeros(len(x))
  for i in range(len(x)):
    y[i] = 1 / (1 + math.exp(-x[i]))
  return y

sigmoid_ = sigmoid(np.arange(-1, 1, 1/50))
alpha = np.repeat(sigmoid_.reshape((len(sigmoid_), 1)), repeats=100, axis=1)

image1_connect = np.ones((100, 100))
image2_connect = np.zeros((100, 100))
out = image1_connect * (1.0 - alpha) + image2_connect * alpha
matplotlib.image.imsave('blend.png', out, cmap = 'gray')

If you blend white and black squares result will look something like that:

enter image description here + enter image description here = enter image description here

like image 39
Massyanya Avatar answered Oct 08 '22 11:10

Massyanya