Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.0k views
in Technique[技术] by (71.8m points)

python - Creating a Linear Gradient Mask using opencv or

I am trying to stitch images together right now to create panoramas. The approach that I have tried so far was to warp the first image and align the second image with it and repeat for n number of images. That seems to be working fine but when I try concatenating the two images together by creating a binary black and white mask using numpy slicing, there is a definite seam that differentiates the two images. I am thinking that if I could either have a feathered mask in the region where black meets white with a transition area or even just a linear gradient mask going from left side of the image to the right cross-fading from black to white, it would help make the seams blend in a little better. I tried using Gaussian Blur to blur the boundaries of my binary mask experimenting with different kernel sizes but it kinda made the situation worse since the Border of the mask started showing up in the images. I just can't seem to figure out a way using numpy and openCV to create such a mask and blend the images. I would even be happy if I can create a mask as shown below so I can use that to blend in the images to improve the results. Any suggestions would be appreciated

enter image description here enter image description here

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

So, I have/had quite the same ideas as fmw42 mentions in the comments, but instead of alpha blending I was thinking of plain linear blending using appropriate "blend masks" (which are the inverted masks you would use for alpha blending).

For the sake of simplicity, I assume two images with identical image sizes here. As fmw42 mentioned, you should use the "interesting" image parts here, for example obtained by cropping. Let's have a look at the code:

import cv2
import numpy as np

# Some input images
img1 = cv2.resize(cv2.imread('path/to/your/image1.png'), (400, 300))
img2 = cv2.resize(cv2.imread('path/to/your/image2.png'), (400, 300))

# Generate blend masks, here: linear, horizontal fading from 1 to 0 and from 0 to 1
mask1 = np.repeat(np.tile(np.linspace(1, 0, img1.shape[1]), (img1.shape[0], 1))[:, :, np.newaxis], 3, axis=2)
mask2 = np.repeat(np.tile(np.linspace(0, 1, img2.shape[1]), (img2.shape[0], 1))[:, :, np.newaxis], 3, axis=2)

# Generate output by linear blending
final = np.uint8(img1 * mask1 + img2 * mask2)

# Outputs
cv2.imshow('img1', img1)
cv2.imshow('img2', img2)
cv2.imshow('mask1', mask1)
cv2.imshow('mask2', mask2)
cv2.imshow('final', final)
cv2.waitKey(0)
cv2.destroyAllWindows()

These are the inputs and masks:

Inputs and masks

This would be the output:

Output

The linear "blend masks" are created by NumPy's linspace method, and some repeating of the vector by NumPy's tile and repeat methods. Maybe, that part can be further optimized.

Caveat: At least for the presented linear blending, ensure for every pixel you generate by

mask1[y, x] * img1[y, x] + mask2[y, x] * img2[y, x] 

that

mask1[y, x] + mask2[y, x] <= 1

or you might get some "over-exposure" for these pixels.

Hope that helps!


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...