Search code examples
pythonopencvblending

Overlaying two images with cv2 results as a noise


I'm trying to blend 3 images.

  1. First i overlay photo.png over base.png with some positioning. And it works.

base_photo.png

  1. Second i'm trying to overlay effect.png

effect.png

over resulting image from previous step.

The result looks like this

result.png

I'm using opencv blending described here. I've tried to use cv2.addWeighted but the result was the same

# blending function
def img_overlay(background, overlay, x_offset, y_offset):
    y1, y2 = y_offset, y_offset + overlay.shape[0]
    x1, x2 = x_offset, x_offset + overlay.shape[1]

    alpha_s = overlay[:, :, 3] / 255.0
    alpha_l = 1.0 - alpha_s

    for c in range(0, 3):
        background[y1:y2, x1:x2, c] = (alpha_s * overlay[:, :, c] +
                                   alpha_l * background[y1:y2, x1:x2, c])

    return background

# First step
background = cv2.imread('base.png')
overlay = cv2.imread('photo.png', -1)
x_offset = 386
y_offset = 70
base_photo = img_overlay(background, overlay, x_offset, y_offset)

# Second step
overlay = cv2.imread('effect.png', -1)
final_photo = img_overlay(base_photo, overlay, 0, 0)

cv2.imwrite(result, final_photo) 

How i can fix img_overlay function so it will overlay effect.png correctly?


Solution

  • The problem is your 'effect' image is in the a different scale. Correct this by dividing by 255.

    Yours 'Second Step' should look like this:

    # Second step
    overlay = cv2.imread('effect.png', -1)
    overlay = overlay / 255.0
    final_photo = img_overlay(base_photo, overlay, 0, 0)
    

    Which works for me.