使用opencv或创建线性渐变蒙版 [英] Creating a Linear Gradient Mask using opencv or

查看:172
本文介绍了使用opencv或创建线性渐变蒙版的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我现在正在尝试将图像拼接在一起以创建全景图.到目前为止,我尝试过的方法是使第一个图像变形并使第二个图像与之对齐,然后重复n个图像.这似乎工作正常,但是当我尝试通过使用numpy切片创建二进制黑白蒙版来将两个图像串联在一起时,有一个明确的接缝将两个图像区分开.我在想,如果我可以在黑色与白色相交并具有过渡区域的区域中使用羽毛状蒙版,或者甚至可以使用从图像左侧到从黑色到白色的交叉淡入淡出的线性渐变蒙版,那会帮助使接缝融合得更好.我尝试使用高斯模糊来模糊我的二进制蒙版的边界,并尝试使用不同的内核大小,但是由于蒙版的边界开始出现在图像中,这使情况变得更糟. 我只是似乎无法找出一种使用numpy和openCV创建这样的蒙版并混合图像的方法.如果可以如下图所示创建蒙版,我什至会很高兴,因此可以将其用于混合图像以改善效果.任何建议将不胜感激

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

推荐答案

我可以想到两种方法来解决此问题.主要问题是Python/OpenCV/Numpy要求图像在混合时必须具有相同的形状.

I can think of two ways to approach this. The main issue is that Python/OpenCV/Numpy requires the images to be the same shape when blending.

第一种方法是用零填充两个图像到最终的缝合尺寸.然后在所需的重叠上创建线性坡道,并在其左右两侧分别用一个和/或零填充它们,以达到相同的最终缝合尺寸.然后混合.但这是创建所有填充的大量工作.

The first approach would be to pad out the two images with zeros to the final stitched size. Then create linear ramps over the desired overlap and pad them on the left and right appropriately with ones and/or zeros to the same final stitched size. Then blend. But this is a lot of work to create all the padding.

因此,更简单的方法是将图像分别裁剪为两部分:重叠区域和左侧图像的左侧以及重叠区域和右侧图像的右侧.然后混合重叠区域.然后适当连接裁切后的图像.这就是我下面要做的.我将最大的山峰用作重叠的右侧,并使用右图中其左侧的区域来定义重叠的左侧.我还首先增加了正确图像的亮度,以便能够看到混合效果.

So the simpler approach would be just to crop the images into two parts each: the overlap area and the left of the left image and overlap area and the right of the right image. Then blend the overlap areas. Then concatenate the cropped images appropriately. This is what I do below. I use the largest mountain peak as the right side of the overlap and the region to its left in the right image to define the left side of the overlap. I also first increase the brightness of the right image just to be able to see that the blending works.

import cv2
import numpy as np


# read left and right images
# images from https://medium.com/pylessons/image-stitching-with-opencv-and-python-1ebd9e0a6d78
left = cv2.imread('left.jpg')
right = cv2.imread('right.jpg')

# increase brightness of right image so that the blend difference can be seen after stitching
rightx = 1.5*right
rightx = np.clip((rightx), 0, 255)
rightx = np.uint8(rightx)

# get dimensions
hl, wl, cl = left.shape
hr, wr, cr = right.shape

print("left",hl,wl)
print("right",hr,wr)
#left 710 818
#right 709 816

# note that the two images have different dimensions
# compute min height
hm = min(hl, hr)

# measure mtn peak x location to compute overlap region x end point 
xpl = 603
xpr = 141

# note that everything from the mt peak to the left side of the right image overlaps in the left image
# So use xpr as the ramp width
ramp_width = xpr

# compute start x position of ramp in each image
xrampl = xpl-ramp_width
xrampr = 0

# crop left image into 2 parts horizontally
# start of image to ramp start and ramp start to ramp end 
left1 = left[0:hm, 0:xpl-ramp_width]
left2 = left[0:hm, xpl-ramp_width:xpl]

# crop right image into 2 parts horizontally
# ramp start to ramp end and ramp end to end of image
rightx1 = rightx[0:hm, 0:ramp_width]
rightx2 = rightx[0:hm, ramp_width:wr-ramp_width+1]

# create horizontal ramp down from 1 to 0 over the ramp width for the left image
# convert from one channel to three channels
rampl = np.linspace(1, 0, ramp_width)
rampl = np.tile(np.transpose(rampl), (hm,1))
rampl = cv2.merge([rampl,rampl,rampl])

# create horizontal ramp up from 0 to 1 over the ramp width for the right image
# convert from one channel to three channels
rampr = np.linspace(0, 1, ramp_width)
rampr = np.tile(np.transpose(rampr), (hm,1))
rampr = cv2.merge([rampr,rampr,rampr])

# blend the overlap regions, clip and make into int
blend = left2 * rampl + rightx1 * rampr
blend = np.clip((blend), 0, 255)
blend = np.uint8(blend)

# concatenate the images for the stitched result
stitched = np.concatenate((left1,blend,rightx2), axis=1)

cv2.imshow("left", left)
cv2.imshow("right", right)
cv2.imshow("rightx", rightx)
cv2.imshow("rampl", rampl)
cv2.imshow("rampr", rampr)
cv2.imshow("blend", blend)
cv2.imshow("stitched", stitched)
cv2.waitKey(0)
cv2.destroyAllWindows()

# write result to disk
cv2.imwrite("rightx.jpg", right)
cv2.imwrite("rampl.jpg", np.uint8(255*rampl))
cv2.imwrite("rampr.jpg", np.uint8(255*rampr))
cv2.imwrite("blend.jpg", blend)
cv2.imwrite("left_right_stitch.jpg", stitched)


原始左图:

原始右图:

右图像变亮:

为左图像降低坡度:

为正确的图像加坡:

重叠区域的混合图像:

缝合结果:

这篇关于使用opencv或创建线性渐变蒙版的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆