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

Vic*_*ard 5 python opencv numpy feature-detection

通过阅读有关 stackoverflow 的一些答案,到目前为止我已经学到了很多东西:

掩码必须是一个numpy数组(与图像具有相同的形状),其数据类型CV_8UC10255

但是,这些数字的含义是什么?是否在检测过程中将忽略任何具有相应掩码值为 0 的像素而将使用任何掩码值为 255 的像素?中间的值呢?

另外,如何在pythonnumpy中用数据类型初始化数组CV_8UC1?我可以用吗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)
 # []
Run Code Online (Sandbox Code Playgroud)

Vic*_*ard 6

所以这里是大部分(如果不是全部)答案:

这些数字是什么意思

0 表示忽略像素,255 表示使用它。我仍然不清楚两者之间的值,但我认为并非所有非零值都被视为“等效”于掩码中的 255。见这里

另外,如何在 python 中初始化数据类型为 CV_8UC1 的 numpy 数组?

类型 CV_8U 是无符号 8 位整数,使用 numpy,它是numpy.uint8. C1 后缀表示数组是 1 通道,而不是彩色图像的 3 通道和 rgba 图像的 4 通道。因此,要创建一个 1 通道的无符号 8 位整数数组:

import numpy as np
np.zeros((480, 720), dtype=np.uint8)
Run Code Online (Sandbox Code Playgroud)

(三通道阵列将具有 shape (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
Run Code Online (Sandbox Code Playgroud)

其次,我使用了错误的图像来生成我的curr_cond数组:

curr_cond = self.base[:,:,3] == 255 # wrong
curr_cond = self.curr[:,:,3] == 255 # right
Run Code Online (Sandbox Code Playgroud)

一些非常愚蠢的错误。

这是完整的更正代码:

# 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)
Run Code Online (Sandbox Code Playgroud)

TL;DR:掩码参数是一个 1 通道numpy数组,其形状与您尝试在其中查找特征的灰度图像相同(如果图像形状为(480, 720),则掩码也是如此)。

数组中的值是类型np.uint8255表示“使用这个像素”,0表示“不”

感谢Dan Mašek带领我找到这个答案的一部分。