OpenCV,Python:如何在 ORB 特征检测器中使用掩码参数
OpenCV, Python: How to use mask parameter in ORB feature detector
通过阅读一些关于 Whosebug 的回答,到目前为止我学到了很多东西:
掩码必须是数据类型为 CV_8UC1
的 numpy
数组(与图像具有相同的形状)并且具有从 0
到 255
的值.
这些数字的含义是什么?是否在检测过程中将忽略任何对应掩码值为零的像素,并使用任何掩码值为 255 的像素?两者之间的值呢?
此外,如何在 python 中初始化数据类型为 CV_8UC1
的 numpy
数组?我可以只使用 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 引导我找到部分答案。
通过阅读一些关于 Whosebug 的回答,到目前为止我学到了很多东西:
掩码必须是数据类型为 CV_8UC1
的 numpy
数组(与图像具有相同的形状)并且具有从 0
到 255
的值.
这些数字的含义是什么?是否在检测过程中将忽略任何对应掩码值为零的像素,并使用任何掩码值为 255 的像素?两者之间的值呢?
此外,如何在 python 中初始化数据类型为 CV_8UC1
的 numpy
数组?我可以只使用 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 引导我找到部分答案。