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

OpenCV, Python: How to use mask parameter in ORB feature detector

通过阅读一些关于 Whosebug 的回答,到目前为止我学到了很多东西:

掩码必须是数据类型为 CV_8UC1numpy 数组(与图像具有相同的形状)并且具有从 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)
 # []

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

What is the meaning of those numbers

0 表示忽略该像素,255 表示使用它。我仍然不清楚两者之间的值,但我不认为掩码中的所有非零值都被视为 "equivalent" 到 255。参见 here

Also, how do I initialize a numpy array with data type CV_8UC1 in python?

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

import numpy as np
np.zeros((480, 720), dtype=np.uint8)

(三通道阵列的形状为 (480, 720, 3),四通道阵列为 (480, 720, 4),等等)这个掩码会导致检测器和提取器忽略整个图像,因为它是全为零。

how do I correct [the code]?

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

首先,我忘记设置 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.uint8类型,255表示"use this pixel",0表示"don't"

感谢 Dan Mašek 引导我找到部分答案。