OpenCV,Python:如何在ORB特征检测器中使用掩码参数

6

通过阅读stackoverflow上的几个答案,我已经了解到以下内容:

掩膜必须是一个numpy数组(形状与图像相同),其数据类型为CV_8UC1,并且具有从0255的值。

然而,这些数字的含义是什么呢?是说任何相应掩码值为零的像素都将在检测过程中被忽略,而任何掩码值为255的像素都将被使用吗?那么介于两者之间的值呢?

此外,在Python中如何初始化具有数据类型CV_8UC1numpy数组呢?我可以只使用dtype=cv2.CV_8UC1吗?

这是我目前正在使用的代码,基于我以上所做的假设。但问题在于当我对任何一张图片运行detectAndCompute时都没有得到关键点。我有一种感觉,可能是因为掩膜不是正确的数据类型。如果我的想法是正确的,那么我该怎么改正呢?

# convert images to grayscale
base_gray = cv2.cvtColor(self.base, cv2.COLOR_BGRA2GRAY)
curr_gray = cv2.cvtColor(self.curr, cv2.COLOR_BGRA2GRAY)

# initialize feature detector
detector = cv2.ORB_create()

# create a mask using the alpha channel of the original image--don't
# use transparent or partially transparent parts
base_cond = self.base[:,:,3] == 255
base_mask = np.array(np.where(base_cond, 255, 0))

curr_cond = self.base[:,:,3] == 255
curr_mask = np.array(np.where(curr_cond, 255, 0), dtype=np.uint8)

# use the mask and grayscale images to detect good features
base_keys, base_desc = detector.detectAndCompute(base_gray, mask=base_mask)
curr_keys, curr_desc = detector.detectAndCompute(curr_gray, mask=curr_mask)

 print("base keys: ", base_keys)
 # []
 print("curr keys: ", curr_keys)
 # []

2
“如何初始化一个numpy数组”-- 你尝试过阅读numpy数据类型文档了吗? - Dan Mašek
1
问题是,CV_8UC1在该列表中对应哪种数据类型?我倾向于认为它是uint8,因为有数字8和字母U,尽管我没有找到任何证明的文档。问题是我从那里没有得到任何关键点。 - Victor Odouard
你做对了,uint8。| 检查掩码确保它们是合理的。 | 这个链接是http://docs.opencv.org/2.4/modules/core/doc/basic_structures.html中的第一个自然段。 - Dan Mašek
1个回答

9
这里是大部分,如果不是全部的答案:
0 表示忽略该像素,255 表示使用它。我仍然不清楚中间的值,但我认为并非所有的非零值都被认为与掩码中的 255 相等。请参见 here
另外,在 Python 中如何初始化一个数据类型为 CV_8UC1 的 numpy 数组?
CV_8U 类型是无符号 8 位整数,使用 numpy 时是 numpy.uint8。C1 后缀表示数组是 1 通道的,而不是彩色图像的 3 通道和 rgba 图像的 4 通道。因此,要创建一个由无符号 8 位整数组成的 1 通道数组:
import numpy as np
np.zeros((480, 720), dtype=np.uint8)

(一个三通道数组的形状为(480, 720, 3),四通道为(480, 720, 4)等)。不过由于这个掩码全部为零,会导致检测器和提取器忽略整个图像。

我该如何修正[代码]?

有两个单独的问题,每个问题都分别导致关键点数组为空。

首先,我忘记了为base_mask设置类型。

base_mask = np.array(np.where(base_cond, 255, 0)) # wrong
base_mask = np.array(np.where(base_cond, 255, 0), dtype=uint8) # right

其次,我在生成curr_cond数组时使用了错误的图片:

curr_cond = self.base[:,:,3] == 255 # wrong
curr_cond = self.curr[:,:,3] == 255 # right

一些相当愚蠢的错误。

这里是完整的已纠正代码:

# convert images to grayscale
base_gray = cv2.cvtColor(self.base, cv2.COLOR_BGRA2GRAY)
curr_gray = cv2.cvtColor(self.curr, cv2.COLOR_BGRA2GRAY)

# initialize feature detector
detector = cv2.ORB_create()

# create a mask using the alpha channel of the original image--don't
# use transparent or partially transparent parts
base_cond = self.base[:,:,3] == 255
base_mask = np.array(np.where(base_cond, 255, 0), dtype=np.uint8)

curr_cond = self.curr[:,:,3] == 255
curr_mask = np.array(np.where(curr_cond, 255, 0), dtype=np.uint8)

# use the mask and grayscale images to detect good features
base_keys, base_desc = detector.detectAndCompute(base_gray, mask=base_mask)
curr_keys, curr_desc = detector.detectAndCompute(curr_gray, mask=curr_mask)

TL;DR:mask参数是一个1通道的numpy数组,其形状与你要查找特征的灰度图像相同(如果图像形状为(480, 720),则掩模也是如此)。
数组中的值的类型为np.uint8255表示“使用此像素”,0表示“不使用”。
感谢Dan Mašek为我提供部分答案。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接