我有两个重叠的图像。我想对齐这两个图像。我目前的方法是在两个图像中找到一个共同的特征(标记)。然后,我想根据要素重叠的位置对齐这两个图像。
图像并不完美,所以我正在寻找一种基于“最佳”匹配(大多数重叠)对齐的方法。最初我试图通过SIFT使用特征匹配来对齐图像,但功能匹配通常不正确/太少。
以下是我用来查找template的代码:
template = cv2.imread('template.png', 0)
template = template - cv2.erode(template, None)
image1 = cv2.imread('Image to align1.png')
image2 = cv2.imread('Image to align2.png')
image = image2
img2 = image[:,:,2]
img2 = img2 - cv2.erode(img2, None)
ccnorm = cv2.matchTemplate(img2, template, cv2.TM_CCORR_NORMED)
print(ccnorm.max())
loc = np.where(ccnorm == ccnorm.max())
print(loc)
threshold = 0.1
th, tw = template.shape[:2]
for pt in zip(*loc[::-1]):
if ccnorm[pt[::-1]] < threshold:
continue
cv2.rectangle(image, pt, (pt[0] + tw, pt[1] + th),
(0, 0, 255), 2)
答案 0 :(得分:3)
您对OpenCV库的选择是使用任意数量的方法来选择几个点,并使用getAffineTransform
或getPerspectiveTransform
等函数在图像中的这些点之间创建转换。请注意,像这样的函数将 points 作为参数,不发光度值(图像)。您想要在第一张图片中找到感兴趣的点(比如那些标记点);并且您希望在第二张图片中找到相同的点,并将这些像素位置传递给getAffineTransform
或getPerspectiveTransform
等函数。然后,一旦有了变换矩阵,就可以使用warpAffine
或warpPerspective
将第二张图像变形为第一张图像的坐标(反之亦然)。
仿射转换包括平移,旋转,缩放和剪切。 透视变换包括来自仿射变换的所有内容,以及x
和y
方向上的透视变形。对于getAffineTransform
,您需要从第一张图像发送三对点,并且这三个相同的像素位于第二张图像中。对于getPerspectiveTransform
,您将从每个图像发送四个像素对。如果您想使用所有标记点,可以使用findHomography
代替,这样您可以放置更多而不是4个点,它将计算所有匹配点之间的最佳单应性
使用特征检测和匹配来对齐图像时,它会在后台使用这些功能。不同之处在于它为您找到了这些功能。但如果这不起作用,只需使用手动方法找到您喜欢的功能,然后在这些功能点上使用这些方法。例如,您可以找到已有的模板位置,并将其定义为感兴趣区域(ROI),然后将标记点分成较小的模板块并在ROI中找到这些位置。然后你从两个图像中得到相应的点对;您可以将自己的位置输入findHomography
或只选择三个用于getAffineTransform
或四个用getPerspectiveTransform
,然后您就可以进行图像转换,然后再应用。
否则,如果您不想使用基于特征的方法,那么您需要使用Lukas-Kanade optical flow algorithm之类的可以进行直接图像匹配的内容,但这些方法相对于选择如果你使用整个图像,很少有特征点和找到相似的方式。但是,如果您只需要为一些图像执行此操作,那就没那么大了。为了更加准确并使其收敛得更快,如果你能提供一个起始单应性,至少可以将它大致转换到正确的位置,它会有所帮助(例如,你进行特征检测,看到该特征大致为{ {1}}来自第一个图像的第二个图像中的像素,并使用该翻译创建单应性。)
如果您想尝试,也可以在线查找Lucas-Kanade逆组合算法等的单应性估计的Python例程。我也有自己的自定义例程用于该算法,但是我无法分享它,但是,如果您在没有边界框的情况下共享原始图像,我可以在您的图像上运行算法,以便为您提供一些估计的单应性比较。