Home » Tutorial: Image Blending Using OpenCV in Python

Tutorial: Image Blending Using OpenCV in Python

Java SE 11 Programmer I [1Z0-815] Practice Tests
1 Year Subscription
Oracle Java Certification
Java SE 11 Developer (Upgrade) [1Z0-817]
Java SE 11 Programmer II [1Z0-816] Practice Tests
Spring Framework Basics Video Course

Image blending is a technique to combine two images with a weighted sum or through advanced techniques like pyramids. OpenCV provides multiple ways to blend images effectively, whether for basic overlaying or advanced image morphing.

What You’ll Learn

1. Introduction to Image Blending

Blending involves combining two images using weights or masks. The basic formula for blending is:

Blended Image=α⋅Image1+β⋅Image2+γ\text{Blended Image} = \alpha \cdot \text{Image1} + \beta \cdot \text{Image2} + \gamma

Where:

  • alpha: Weight for the first image.
  • beta: Weight for the second image.
  • gamma: Scalar added to the result.

2. Simple Weighted Blending

The function cv2.addWeighted() blends two images using the formula above.

Example: Simple Weighted Blending

import cv2

# Load two images of the same size
image1 = cv2.imread("image1.jpg")
image2 = cv2.imread("image2.jpg")

# Blend images with equal weights
blended = cv2.addWeighted(image1, 0.5, image2, 0.5, 0)

# Display the result
cv2.imshow("Blended Image", blended)
cv2.waitKey(0)
cv2.destroyAllWindows()

Adjusting Weights

# Blend with different weights
blended = cv2.addWeighted(image1, 0.7, image2, 0.3, 0)

3. Blending with Masks

Masks allow blending specific regions of two images.

Example: Blending with a Circular Mask

import cv2
import numpy as np

# Load two images of the same size
image1 = cv2.imread("image1.jpg")
image2 = cv2.imread("image2.jpg")

# Create a circular mask
rows, cols, _ = image1.shape
mask = np.zeros((rows, cols), dtype="uint8")
center = (cols // 2, rows // 2)
radius = min(rows, cols) // 4
cv2.circle(mask, center, radius, 255, -1)

# Blend the images using the mask
blended = cv2.bitwise_and(image1, image1, mask=mask)
inverse_mask = cv2.bitwise_not(mask)
blended += cv2.bitwise_and(image2, image2, mask=inverse_mask)

# Display the result
cv2.imshow("Masked Blended Image", blended)
cv2.waitKey(0)
cv2.destroyAllWindows()

4. Pyramid-Based Image Blending

Pyramid blending uses multi-scale image decomposition (Gaussian and Laplacian pyramids) to blend images seamlessly.

Steps for Pyramid Blending

  1. Create Gaussian pyramids for both images and the mask.
  2. Create Laplacian pyramids from Gaussian pyramids.
  3. Blend the Laplacian pyramids using the mask.
  4. Reconstruct the final image from the blended pyramid.

Example: Pyramid Blending

import cv2
import numpy as np

def blend_images_pyramid(image1, image2, mask, levels=4):
    # Generate Gaussian pyramids for images and mask
    gp_image1 = [image1]
    gp_image2 = [image2]
    gp_mask = [mask]
    
    for _ in range(levels):
        image1 = cv2.pyrDown(image1)
        image2 = cv2.pyrDown(image2)
        mask = cv2.pyrDown(mask)
        
        gp_image1.append(image1)
        gp_image2.append(image2)
        gp_mask.append(mask)
    
    # Generate Laplacian pyramids
    lp_image1 = [gp_image1[-1]]
    lp_image2 = [gp_image2[-1]]
    lp_mask = [gp_mask[-1]]
    
    for i in range(levels, 0, -1):
        laplacian_image1 = cv2.subtract(gp_image1[i-1], cv2.pyrUp(gp_image1[i]))
        laplacian_image2 = cv2.subtract(gp_image2[i-1], cv2.pyrUp(gp_image2[i]))
        lp_image1.append(laplacian_image1)
        lp_image2.append(laplacian_image2)
    
    # Blend pyramids
    blended_pyramid = []
    for la1, la2, gm in zip(lp_image1, lp_image2, gp_mask):
        blended = cv2.add(la1 * gm / 255, la2 * (1 - gm / 255))
        blended_pyramid.append(blended)
    
    # Reconstruct the blended image
    blended_image = blended_pyramid[0]
    for i in range(1, levels+1):
        blended_image = cv2.pyrUp(blended_image)
        blended_image = cv2.add(blended_image, blended_pyramid[i])
    
    return blended_image

# Load two images and a mask
image1 = cv2.imread("image1.jpg")
image2 = cv2.imread("image2.jpg")
rows, cols, _ = image1.shape
mask = np.zeros((rows, cols), dtype="uint8")
cv2.rectangle(mask, (cols // 2, 0), (cols, rows), 255, -1)

# Blend the images using pyramid blending
blended = blend_images_pyramid(image1, image2, mask, levels=4)

# Display the result
cv2.imshow("Pyramid Blended Image", blended)
cv2.waitKey(0)
cv2.destroyAllWindows()

5. Practical Examples

5.1 Combine Two Images Horizontally

import cv2
import numpy as np

# Load images
image1 = cv2.imread("image1.jpg")
image2 = cv2.imread("image2.jpg")

# Resize images to the same height
height = min(image1.shape[0], image2.shape[0])
image1 = cv2.resize(image1, (int(image1.shape[1] * height / image1.shape[0]), height))
image2 = cv2.resize(image2, (int(image2.shape[1] * height / image2.shape[0]), height))

# Blend horizontally
blended = np.hstack((image1, image2))

cv2.imshow("Combined Image", blended)
cv2.waitKey(0)
cv2.destroyAllWindows()

5.2 Create a Fade Transition Between Two Images

import cv2
import numpy as np

# Load images
image1 = cv2.imread("image1.jpg")
image2 = cv2.imread("image2.jpg")

# Ensure both images are the same size
image1 = cv2.resize(image1, (500, 500))
image2 = cv2.resize(image2, (500, 500))

# Create a fade effect
for alpha in np.linspace(0, 1, 50):
    blended = cv2.addWeighted(image1, alpha, image2, 1 - alpha, 0)
    cv2.imshow("Fade Transition", blended)
    if cv2.waitKey(50) & 0xFF == ord('q'):  # Press 'q' to exit
        break

cv2.destroyAllWindows()

5.3 Blend Multiple Images

import cv2
import numpy as np

# Load images
images = ["image1.jpg", "image2.jpg", "image3.jpg"]
loaded_images = [cv2.imread(img) for img in images]

# Resize all images to the same size
size = (500, 500)
loaded_images = [cv2.resize(img, size) for img in loaded_images]

# Blend all images equally
blended = np.zeros_like(loaded_images[0], dtype="float32")
for img in loaded_images:
    blended += img.astype("float32") / len(loaded_images)

# Convert back to uint8
blended = np.clip(blended, 0, 255).astype("uint8")

cv2.imshow("Blended Multiple Images", blended)
cv2.waitKey(0)
cv2.destroyAllWindows()

6. Summary

Key Functions

  • cv2.addWeighted(): Perform weighted blending.
  • cv2.bitwise_and() / cv2.bitwise_not(): Blend with masks.
  • Pyramid Blending: Advanced blending for seamless results.

Best Practices

  1. Ensure images are the same size for blending.
  2. Use masks to blend specific regions.
  3. Leverage pyramid blending for smooth transitions.

By mastering these techniques, you can create stunning image blends for animations, overlays, or seamless image combinations using OpenCV

You may also like

This website uses cookies to improve your experience. We'll assume you're ok with this, but you can opt-out if you wish. Accept Read More