不透明度降低的图像对齐

Image alignment with reduced opacity

在下面给出的程序中,我使用单应性对齐两个图像并降低 im_out 图像中 im_dst 图像的不透明度(比如不透明度 =0.5),这样我就可以看到两个 [= im_out 图像中的 17=] 和 im_dst 图像。但我得到的只是 im_out 图像中变黑的 im_dst 图像!

import cv2
import numpy as np
im_src = cv2.imread('src.jpg')
pts_src = np.array([[141, 131], [480, 159], [493, 630],[64, 601]])
im_dst = cv2.imread('dst.jpg')
pts_dst = np.array([[318, 256],[534, 372],[316, 670],[73, 473]])
h, status = cv2.findHomography(pts_src, pts_dst)
img1 = np.array(im_dst , dtype=np.float)
img2 = np.array(im_src , dtype=np.float)
img1 /= 255.0
# pre-multiplication
a_channel = np.ones(img1.shape, dtype=np.float)/2.0
im_dst = img1*a_channel
im_src = img2*(1-a_channel)
im_out = cv2.warpPerspective(im_src, h, (im_dst.shape[1],im_dst.shape[0]))
cv2.imshow("Warped Image", im_out)
cv2.waitKey(0)

我是 openCV 的新手,所以我可能遗漏了一些简单的东西。感谢您的帮助!

嘿,我以前 seen those points

您的代码所做的是减少两个图像 im_dstim_src 的值,但是您只是将 im_src 的褪色图像移动到新位置并显示它。相反,您应该将褪色和变形的图像添加到目标图像并输出。以下是对代码末尾的有效修改:

alpha = 0.5
im_dst = img1 * alpha
im_src = img2 * (1-alpha)
im_out = cv2.warpPerspective(im_src, h, (im_dst.shape[1],im_dst.shape[0]))
im_blended = im_dst + im_out
cv2.imshow("Blended Warped Image", im_blended)
cv2.waitKey(0)

但是您只将 img1 而不是 img2 除以 255,因此您需要先将两者除以。


但是,没有理由手动执行此操作,因为您必须担心转换图像类型和缩放等问题。相反,一种更简单的方法是使用内置的 OpenCV 函数 addWeighted() 将两个图像添加到一起并进行 alpha 混合。所以你的整个代码会这么短:

import cv2
import numpy as np

im_src = cv2.imread('src.jpg')
pts_src = np.array([[141, 131], [480, 159], [493, 630],[64, 601]])
im_dst = cv2.imread('dst.jpg')
pts_dst = np.array([[318, 256],[534, 372],[316, 670],[73, 473]])

h, status = cv2.findHomography(pts_src, pts_dst)
im_out = cv2.warpPerspective(im_src, h, (im_dst.shape[1],im_dst.shape[0]))

alpha = 0.5
beta = (1.0 - alpha)
dst_warp_blended = cv2.addWeighted(im_dst, alpha, im_out, beta, 0.0)

cv2.imshow('Blended destination and warped image', dst_warp_blended)
cv2.waitKey(0)

函数addWeighted()将第一个图像im_dst乘以alpha,将第二个图像im_out乘以beta。最后一个参数是正向偏移,您可以在需要时将其添加到结果中。最后,结果是饱和的,因此超出您的数据类型允许的值的最大值被截断。这样,您的结果与输入的类型相同——您不必转换为浮点数。


关于您的代码的最后一点。很多教程,包括上面链接的教程,都使用 findHomography() 从四个匹配点获得单应性。在这种情况下使用 getPerspectiveTransform() 更合适。函数 findHomography() 基于 许多 匹配点找到最佳单应性,使用异常值拒绝方案和随机抽样来加速遍历所有可能的四个匹配点集。它当然适用于四个点的集合,但是当你有四个匹配点时使用 getPerspectiveTransform() 更有意义,当你有四个以上时使用 findHomography() 更有意义。尽管令人讨厌的是,无论出于何种原因,您传递给 getPerspectiveTransform() 的点都必须是 np.float32 类型。所以这将是我对您的代码的最终建议:

import cv2
import numpy as np

# Read source image.
im_src = cv2.imread('src.jpg')
# Four corners of the book in source image
pts_src = np.array([[141, 131], [480, 159], [493, 630],[64, 601]], dtype=np.float32)

# Read destination image.
im_dst = cv2.imread('dst.jpg')
# Four corners of the book in destination image.
pts_dst = np.array([[318, 256],[534, 372],[316, 670],[73, 473]], dtype=np.float32)

# Calculate Homography
h = cv2.getPerspectiveTransform(pts_src, pts_dst)

# Warp source image to destination based on homography
warp_src = cv2.warpPerspective(im_src, h, (im_dst.shape[1],im_dst.shape[0]))

# Blend the warped image and the destination image
alpha = 0.5
beta = (1.0 - alpha)
dst_warp_blended = cv2.addWeighted(im_dst, alpha, warp_src, beta, 0.0)

# Show the output
cv2.imshow('Blended destination and warped image', dst_warp_blended)
cv2.waitKey(0)

这(以及上述所有其他解决方案)将产生以下图像: