【问题标题】:Missing keypoints from image图像中缺少关键点
【发布时间】:2020-09-09 10:43:44
【问题描述】:

我正在尝试在图像上手动设置 22 个关键点,以便提取它们的特征。对于这个任务,我使用我手动选择的坐标创建了一个关键点数组,并将向量作为参数传递给 orb.compute,然后它们分别绘制关键点。

我的问题是我在图像的不同部分设置了 22 个点,但在图像中显示的关键点不会超过 14 个。

以下是我期望在哪些位置绘制 22 个关键点的示例:

实际发生的情况:

点从一个图像到另一个图像有所改变,但代码中的坐标才是最重要的,这些图像是我试图做什么和得到什么的说明性示例。

这是我的代码的可重现版本:

import pandas as pd
import skimage
import cv2
                imageList = skimage.io.imread("./a.png")  
                orb = cv2.ORB_create()
                key_points = [cv2.KeyPoint(65, 9, 10), <---- missing
                              cv2.KeyPoint(66, 12, 10), 
                              cv2.KeyPoint(62, 21, 10),
                              cv2.KeyPoint(60, 13, 10),
                              cv2.KeyPoint(67, 12, 10),
                              cv2.KeyPoint(107, 6, 10), <---- missing
                              cv2.KeyPoint(170, 10, 10),<---- missing 
                              cv2.KeyPoint(25, 60, 10), 
                              cv2.KeyPoint(60, 40, 10), 
                              cv2.KeyPoint(110, 35, 10), 
                              cv2.KeyPoint(170, 35, 10), 
                              cv2.KeyPoint(190, 60, 1), 
                              cv2.KeyPoint(30, 95, 10), <---- missing
                              cv2.KeyPoint(60, 80, 10), 
                              cv2.KeyPoint(100, 105, 10), 
                              cv2.KeyPoint(120, 105, 10),
                              cv2.KeyPoint(160, 180, 10), 
                              cv2.KeyPoint(185, 95, 10), 
                              cv2.KeyPoint(25, 160, 10), <---- missing
                              cv2.KeyPoint(55, 160, 10), 
                              cv2.KeyPoint(155, 160, 10), 
                              cv2.KeyPoint(185, 160, 10), <---- missing
                              cv2.KeyPoint(65, 200, 10), <----- missing
                              cv2.KeyPoint(83, 186, 10), 
                              cv2.KeyPoint(128, 186, 10), 
                              cv2.KeyPoint(157, 197, 10) <---- missing]
                kp, des = orb.compute(imageList, key_points)
                kparray = cv2.drawKeypoints(imageList, kp, None, flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS); 
                cv2.imshow("Image", kparray)
                cv2.waitKey(0)

所以,出于某种原因,我设置了上面可以看到的所有这 22 个点,但是当我运行我的代码时,它只显示 14 个,有些丢失了 我什至尝试在 cv2.drawKeyPoints 中打印 kp 参数以确保:

[<KeyPoint 000002DF9DE83B40>, 
<KeyPoint 000002DF9DE83F90>, 
<KeyPoint 000002DF9DE83FC0>, 
<KeyPoint 000002DF9DE83F30>, 
<KeyPoint 000002DF9DE83DB0>, 
<KeyPoint 000002DFAB657030>, 
<KeyPoint 000002DFAB657B40>, 
<KeyPoint 000002DFAC1FED20>, 
<KeyPoint 000002DFAC1FE480>, 
<KeyPoint 000002DFAC1FEC90>, 
<KeyPoint 000002DFAC1FEDE0>, 
<KeyPoint 000002DFAC20D030>, 
<KeyPoint 000002DFAC20D060>, 
<KeyPoint 000002DFAC20D0C0>]

【问题讨论】:

  • 这能回答你的问题吗? OpenCV ORB detector finds very few keypoints
  • 我不能确定问题是否相同,但正确的答案肯定在这个线程上,而不是在那里。我尝试了该解决方案以确保,除了没有可接受的答案之外,我仍然得到较少的分数,这意味着问题可能尚未解决。

标签: python opencv feature-extraction cv2 orb


【解决方案1】:

首先,为了理解问题,我不得不大幅减少提供的代码。它可能会阻止人们提供帮助。

另外,你写道:

当我运行我的代码时,它只显示 14,有些丢失了我什至尝试在 cv2.drawKeyPoints 中打印 kp 参数以确保,即便如此:

所以,据我了解,这不是 OpenCV 显示的问题,而是关于 ORB 能够计算的关键点的问题。

所以让我重新表述你的问题:

在 OpenCV 中,为什么 ORB 计算会删除一些关键点。 这是重现的最少代码:

import skimage
import cv2

imageList = skimage.io.imread("./a.png")
orb = cv2.ORB_create()
key_points = [cv2.KeyPoint(65, 9, 10), cv2.KeyPoint(66, 40, 10)]
kp, des = orb.compute(imageList, key_points)
print(len(kp))

打印“1”

因此可能会找到答案in some other StackOverflow questions

例如,更改阈值改变了我的结果。

...
orb = cv2.ORB_create(edgeThreshold=1)
...
print(len(kp))

返回“2”

很遗憾,我不是 ORB 专家,因此如果重新表述您的问题以吸引 ORB 专家而不是我的注意力,您可能会得到更好的结果。

祝你好运。

【讨论】:

  • 像您一样更改阈值,正确调出所有 22 个点。我将根据您的建议编辑问题,以供偶然发现相同问题的人将来参考,但请解释一下,此阈值参数如何工作,我为什么要减少它?
【解决方案2】:

我也遇到过同样的难题,可以为您提供部分答案。 “部分”,因为它没有完全解释您提供的具体示例值:

来自compute()方法的docs

关键点,描述符 = cv.Feature2D.compute( 图像,关键点 [,描述符] )
[snip]
keypoints 输入关键点集合。 删除无法计算描述符的关键点。有时可以添加新的关键点,例如:SIFT 复制具有多个主要方向的关键点(针对每个方向)。

(突出显示我的)。

那么现在为什么不能计算描述符?在 ORB 的情况下,我在源代码中找到的唯一可能的答案是:如果它们离图像边框太近。事实上,在orb.cpp

KeyPointsFilter::runByImageBorder(keypoints, image.size(), edgeThreshold);

调用KeyPoints 的方法,它只是删除比edgeThreshold 更靠近边距的所有内容,在您的情况下,这将是ORB 的默认值31。

这解释了为什么您的一些示例关键点丢失了,但它没有解释为什么例如第二个 cv2.KeyPoint(66, 12, 10) 仍然存在,因为它显然比 31 更接近边距。可能是您的 OpenCV 版本中存在错误,或者可能我还没有完全理解发生了什么。

edgeThreshold 设置为 1 会有所帮助,因为它不会过滤掉任何点,除非它们在边界上,但是我建议不要这样做,因为描述符会考虑数据从更远的地方(由参数patchSize 控制),我不确定,但我认为如果这恰好包含图像之外的数据,那么 OpenCV 只会获取该内存地址中发生的任何内容。

所以我的建议是:如果您无法将关键点进一步移动到图像中,则将patchSize 设置为您可以容忍的尽可能小,并将edgeThreshold 设置为一半加上一点边距.

【讨论】:

    猜你喜欢
    • 2021-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-28
    • 2018-02-24
    • 2013-06-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多