图像中缺少关键点
Missing keypoints from image
我正在尝试在图像上手动设置 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>]
首先,为了理解问题,我不得不大幅减少提供的代码。它可能会阻止人们提供帮助。
此外,您写道:
when I run my code, it shows only 14, some are missing I even tried printing the kp parameter in cv2.drawKeyPoints to make sure, even so:
因此,据我了解,这不是 OpenCV 显示的问题,而是 ORB 能够计算的关键点的问题。
所以让我改一下你的问题:
In OpenCV why is ORB computation removing some keypoints.
Here is minimal code to reproduce:
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))
prints "1"
因此可能会找到答案in some other Whosebug questions
例如,改变阈值,改变了我的结果。
...
orb = cv2.ORB_create(edgeThreshold=1)
...
print(len(kp))
returns“2”
不幸的是,我不是 ORB 专家,因此如果改写您的问题以引起 ORB 专家而不是我的注意,您可能会得到更好的结果。
祝你好运。
我遇到过同样的难题,可以为您提供部分答案。 “部分”,因为它没有完全解释您提供的具体示例值:
来自compute()
方法的docs:
keypoints, descriptors = cv.Feature2D.compute( images, keypoints[, descriptors] )
[snip]
keypoints Input collection of keypoints. Keypoints for which a descriptor cannot be computed are removed. Sometimes new keypoints can be added, for example: SIFT duplicates keypoint with several dominant orientations (for each orientation).
(突出显示我的)。
那么现在为什么不能计算描述符呢?在 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
设置为一半加上一些余量。
我正在尝试在图像上手动设置 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>]
首先,为了理解问题,我不得不大幅减少提供的代码。它可能会阻止人们提供帮助。
此外,您写道:
when I run my code, it shows only 14, some are missing I even tried printing the kp parameter in cv2.drawKeyPoints to make sure, even so:
因此,据我了解,这不是 OpenCV 显示的问题,而是 ORB 能够计算的关键点的问题。
所以让我改一下你的问题:
In OpenCV why is ORB computation removing some keypoints. Here is minimal code to reproduce:
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))
prints "1"
因此可能会找到答案in some other Whosebug questions
例如,改变阈值,改变了我的结果。
...
orb = cv2.ORB_create(edgeThreshold=1)
...
print(len(kp))
returns“2”
不幸的是,我不是 ORB 专家,因此如果改写您的问题以引起 ORB 专家而不是我的注意,您可能会得到更好的结果。
祝你好运。
我遇到过同样的难题,可以为您提供部分答案。 “部分”,因为它没有完全解释您提供的具体示例值:
来自compute()
方法的docs:
keypoints, descriptors = cv.Feature2D.compute( images, keypoints[, descriptors] )
[snip]
keypoints Input collection of keypoints. Keypoints for which a descriptor cannot be computed are removed. Sometimes new keypoints can be added, for example: SIFT duplicates keypoint with several dominant orientations (for each orientation).
(突出显示我的)。
那么现在为什么不能计算描述符呢?在 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
设置为一半加上一些余量。