当前位置: 首页 > 面试题库 >

Python,OpenCV —对齐并覆盖多个图像,一个接一个

訾稳
2023-03-14
问题内容

我的项目是对齐航空照片,以制作出一张马赛克地图。我的计划是从两张照片开始,将第二张照片与第一张照片对齐,然后从两张对齐的图像中创建一个“初始镶嵌”。完成此操作后,我将第三张照片与初始镶嵌图对齐,然后将第四张照片与该图的结果对齐,以此类推,从而逐步构建地图。

我有两种技术可以做到这一点,但是使用的更精确的技术calcOpticalFlowPyrLK()仅适用于两个图像阶段,因为两个输入图像的大小必须相同。因此,我尝试了一种新的解决方案,但是它的准确性较差,并且在每个步骤中引入的错误都会堆积起来,最终产生荒谬的结果。

我的问题有两个方面,但是,如果您知道一个答案,那么除非您愿意,否则不必都回答。首先,是否有办法使用类似于calcOpticalFlowPyrLK()但带有两个不同大小的图像的方法(这包括任何可能的解决方法)?其次,是否有一种方法可以修改检测器/描述符解决方案以使其更加准确?

这是仅适用于两个图像的准确版本:

# load images
base = cv2.imread("images/1.jpg")
curr = cv2.imread("images/2.jpg")

# convert to grayscale
base_gray = cv2.cvtColor(base, cv2.COLOR_BGR2GRAY)

# find the coordinates of good features to track  in base
base_features = cv2.goodFeaturesToTrack(base_gray, 3000, .01, 10)

# find corresponding features in current photo
curr_features = np.array([])
curr_features, pyr_stati, _ = cv2.calcOpticalFlowPyrLK(base, curr, base_features, curr_features, flags=1)

# only add features for which a match was found to the pruned arrays
base_features_pruned = []
curr_features_pruned = []
for index, status in enumerate(pyr_stati):
    if status == 1:
        base_features_pruned.append(base_features[index])
        curr_features_pruned.append(curr_features[index])

# convert lists to numpy arrays so they can be passed to opencv function
bf_final = np.asarray(base_features_pruned)
cf_final = np.asarray(curr_features_pruned)

# find perspective transformation using the arrays of corresponding points
transformation, hom_stati = cv2.findHomography(cf_final, bf_final, method=cv2.RANSAC, ransacReprojThreshold=1)

# transform the images and overlay them to see if they align properly
# not what I do in the actual program, just for use in the example code
# so that you can see how they align, if you decide to run it
height, width = curr.shape[:2]
mod_photo = cv2.warpPerspective(curr, transformation, (width, height))
new_image = cv2.addWeighted(mod_photo, .5, base, .5, 1)

这是不正确的图像,适用于多张图像(直到错误变得太大为止):

# load images
base = cv2.imread("images/1.jpg")
curr = cv2.imread("images/2.jpg")


# convert to grayscale
base_gray = cv2.cvtColor(self.base, cv2.COLOR_BGR2GRAY)

# DIFFERENCES START
curr_gray = cv2.cvtColor(self.curr_photo, cv2.COLOR_BGR2GRAY)

# create detector, get keypoints and descriptors
detector = cv2.ORB_create()
base_keys, base_desc = detector.detectAndCompute(base_gray, None)
curr_keys, curr_desc = detector.detectAndCompute(curr_gray, None)

matcher = cv2.DescriptorMatcher_create("BruteForce-Hamming")

max_dist = 0.0
min_dist = 100.0

for match in matches:
     dist = match.distance
     min_dist = dist if dist < min_dist else min_dist
     max_dist = dist if dist > max_dist else max_dist

good_matches = [match for match in matches if match.distance <= 3 * min_dist ]

base_matches = []
curr_matches = []
for match in good_matches:
    base_matches.append(base_keys[match.queryIdx].pt)
    curr_matches.append(curr_keys[match.trainIdx].pt)

bf_final = np.asarray(base_matches)
cf_final = np.asarray(curr_matches)

# SAME AS BEFORE

# find perspective transformation using the arrays of corresponding points
transformation, hom_stati = cv2.findHomography(cf_final, bf_final, method=cv2.RANSAC, ransacReprojThreshold=1)

# transform the images and overlay them to see if they align properly
# not what I do in the actual program, just for use in the example code
# so that you can see how they align, if you decide to run it
height, width = curr.shape[:2]
mod_photo = cv2.warpPerspective(curr, transformation, (width, height))
new_image = cv2.addWeighted(mod_photo, .5, base, .5, 1)

最后,这是我正在使用的一些图像:
在此处输入图片说明

在此处输入图片说明

在此处输入图片说明

在此处输入图片说明


问题答案:

单应组成,所以如果你有间单应img1img2之间,img2img3那么这两个单应性的组合物提供之间的单应img1img3

您的尺寸不正确,因为您正试图匹配img3包含img1和的拼接图像img2。但是您不需要这样做。在每对连续的图像之间都有所有的单应性之前,请不要缝合它们。然后,您可以采用以下两种方式之一进行操作:从背面或正面进行工作。我将使用h31来指代扭曲img3为的坐标的单应性img1

从前面(伪代码):

warp img2 into coordinates of img1 with h21
warp img3 into coordinates of img1 with h31 = h32 @ h21
warp img4 into coordinates of img1 with h41 = h43 @ h31
...
stitch/blend images together

@是矩阵乘法运算符,它将实现我们的单应性构图(请注意,用单应性的最后一项进行除法是最安全的,以确保它们均按相同比例缩放)。

从后面(伪代码):

...
warp prev stitched img into coordinates of img3 with h43
stitch warped stitched img with img3
warp prev stitched img into coordinates of img2 with h32
stitch warped stitched img with img2
warp prev stitched img into coordinates of img1 with h21
stitch warped stitched img with img1

这个想法是,您可以从正面开始,然后将所有内容扭曲到第一个图像坐标系中,或者从背面开始,将所有内容扭曲到上一个图像并进行绣制,然后将那个已缝制的图像扭曲到先前的图像中,然后重复。我认为第一种方法可能更容易。无论哪种情况,您都必须担心单应性估计中误差的传播,因为它们会在多个组合单应性上累积。

这是将多个图像与同形异义词混合在一起的幼稚方法。更复杂的方法是使用捆绑调整,该调整考虑了所有图像的特征点。为了获得良好的融合效果,需要进行增益补偿以消除相机的增益调整和渐晕,然后进行多波段融合以防止模糊。见布朗和Lowe的开创性的论文在这里和一个光辉的榜样和免费demo软件在这里。



 类似资料:
  • 我正试图通过隐藏png来显示后面的gif来播放悬停上的gif。我可以在悬停状态下播放gif,问题是它不在div的中心。我在这里试过:

  • 问题内容: 我已在帖子中搜索了我的问题的答案,但没有找到能解决我问题的任何东西。我正在尝试使用一个AlarmSettings类设置3种不同的警报。当我设置两个警报时,第二个警报优先于第一个警报,第一个永不熄灭。我认为这可能与我的未决意图有关……我真的是android新手,非常感谢您的帮助。这是我设置警报的代码: 问题答案: 将0属性更改为警报的ID,例如,您有三个警报, 用0,1,2重复上述代码。

  • 我试图在一个div中放两个跨度,每边一个,都与div的底部对齐,而不使用绝对定位(因为这忽略了填充等,我总是在使用它后感觉不好)。右跨度中的文本比左跨度中的文本高。如果我使用垂直对齐来定位它们,如果它们都是浮动的,就不会受到影响,但是如果它们都没有浮动,它们就不会正确地水平对齐。我不能保证两个跨度中的哪一个会有更多的文本。 http://jsfiddle.net/gsvfn07f/

  • 我正在寻找帮助开发(或一个库),可以让我合并在一起的多个图像到一个ImageView。 我的应用程序将用户之间的交互组合在一起,而不是单独地显示它们,因此我希望合并它们的所有化身,这样一个适配器单元格就可视化了一个“组”。 Facebook.com的聊天就是一个很好的例子: 我的问题是,我如何在Android/Java中提供这个功能?据推测,它的图像数量可能介于1到4之间。请告诉我您能给出的任何建

  • 我有两张照片 图像1(对象): 没有标记关键点的原始图像: 图2为白色图片(500x500) 在图1和图2中,我标记了关键点。我想按关键点对齐图像2上的图像1。因此,目标是使两个关键点与拉伸、缩放和变换图像重叠2。 这是我的关键点(csv文件)。图像1中的图像1和图像2的坐标是x和y。 如何使用opencv和python实现这一点?因此,结果图像应如下所示(没有红点,红点仅用于演示关键点):

  • 在这段代码中,我试图将一个导航栏(content1)覆盖在另一个导航栏(content)之上,但似乎什么都不起作用。我做错了什么?即使我可以使其覆盖,它们也不是以容器为中心放置的。 null null 只是想知道如何将我的导航条覆盖在另一个导航条之上并使其在容器中居中,