Home > Net >  When I put foreground image on the background, why this distortion happens?
When I put foreground image on the background, why this distortion happens?

Time:07-16

Here is the background image;

enter image description here

Here is the foreground image;

enter image description here

Here is the Mask image;

enter image description here

The code below;

background = cv2.imread('back.jpg')
image = cv2.imread('img.jpg')
mask = cv2.imread('mask.jpg')

crop_background = cv2.resize(background, (image.shape[1], image.shape[0]), interpolation = cv2.INTER_NEAREST)

mask = np.where(mask == 0, mask, image)
crop_background1 = np.where(mask == 0, crop_background, mask)

cv2.imshow(f'{i}', crop_background1)
cv2.waitKey(0)

output image After running the code;

enter image description here

CodePudding user response:

Carefully look at the data types you are handling. All three images are BGR, they have three intensity values per pixel. In the where function you are only checking and setting one intensity value, so you only change the blue channel, instead of all three channels.

Now, you also have to be careful while composing these images. Be aware of pixel values possible “wrapping around” (unsigned integer overflow) and masking the correct pixels. One possible solution is to compose the image using a linear relationship between pixels values. Nothing fancy, just assigning the pixel values according to the mask matrix:

newPixel = (originalPixel * maskPixel   backgroundPixel * (1-maskPixel))

Note what happens when maskPixel is 0 or 1 (You'll need to use float types). You can see that the "ramp" correctly sets the newPixel value. The operation is also vectorizable. Let's check out the new code:

import cv2
import numpy as np

# Image path
path = "D://opencvImages//"

# Reading the images in default mode:
background = cv2.imread(path   "jkU1C.jpg")
image = cv2.imread(path   "QNuXL.jpg")
mask = cv2.imread(path   "6yyNG.png")

# Resize background:    
crop_background = cv2.resize(background, (image.shape[1], image.shape[0]), interpolation = cv2.INTER_NEAREST)

# BGR to Gray mask:
mask = cv2.cvtColor(mask, cv2.COLOR_BGR2GRAY)

# Threshold mask:
_, mask = cv2.threshold(mask, 0, 255, cv2.THRESH_BINARY)

# Back to BGR:
mask = cv2.cvtColor(mask, cv2.COLOR_GRAY2BGR)

# Convert mask to float in range 0 to 1
mask = mask.astype(np.float64) / 255

# Get new pixel according to the mask matrix:
result = (image * mask   crop_background * (1 - mask))

# Clip values and convert back to uint8:
result = result.clip(0, 255).astype(np.uint8)

# Show result:    
cv2.imshow("result", result)
cv2.waitKey(0)

The result:

enter image description here

  • Related