cv2是否接受二进制图像?

问题描述:

我面临一个问题,像cv2.detectAndCompute,cv2.HoughlinesP这样的cv2方法在输入二进制图像时会出现深度错误或无类型错误。 例如在下面cv2是否接受二进制图像?

def high_blue(B, G): 
    if (B > 70 and abs(B-G) <= 15): 
     return 255 
    else: 
     return 0 

img = cv2.imread(os.path.join(dirPath,filename)) 
b1 = img[:,:,0] # Gives **Blue** 
b2 = img[:,:,1] # Gives Green 
b3 = img[:,:,2] # Gives **Red** 

zlRhmn_query = np.zeros((2400, 2400), dtype=np.uint8) 
zlRhmn_query[300:2100, 300:2100] = 255 
zlRhmn_query[325:2075, 325:2075] = 0 

cv2.imwrite('zlRhmn_query.jpg',zlRhmn_query) 

zl_Rahmen_bin = np.zeros((img.shape[0], img.shape[1]), dtype=np.uint8) 
zl_Rahmen_bin = np.vectorize(high_blue) 
zl_Rahmen_bin = zl_Rahmen_bin(b1, b2) 

cv2.imwrite('zl_Rahmen_bin.jpg',zl_Rahmen_bin) 

sift = cv2.xfeatures2d.SIFT_create() 

kp_query, des_query = sift.detectAndCompute(zlRhmn_query,None) 
kp_train, des_train = sift.detectAndCompute(zl_Rahmen_bin,None) 

只有带zl_Rahmen_bin的最后一行失败,伴随深度不匹配错误。奇怪的是,zlRhmn_query不会抛出任何错误。接下来,当我使用这里给出的骨架化片段[http://opencvpython.blogspot.de/2012/05/skeletonization-using-opencv-python.html]并将骨架传递给HoughLinesP时,我得到了一个类型为NoneType的线对象。在检查时,我注意到骨架阵列也是二进制的,即0或255.

请指教。

+0

看起来你是不是在谈论“二进制”图像(在这个意义上该像素是一个单一的位),但更准确地说,使用uint8为像素调用8位灰度,是吗? HoughLinesP肯定使用0/255的灰度进行工作,有可能是您的图像中找不到任何线条,并且提供给HoughLinesP的参数。我个人使用python opencv的经验是,命名所有可选参数是个好主意,比如'rawlines = cv2.HoughLinesP(cdst,1,np.pi/180,threshold = 50,minLineLength = 50,maxLineGap = 20) ' – barny

+0

@barny在图像处理二进制图像中总是指只有两个不同值的图像。数据类型和实际值无关紧要。虽然这可能听起来令一些程序员感到困惑:) – Piglet

+0

@Piglet无论如何。无论如何,HoughLinesP肯定会使用灰度二值图像 - 由于图像和参数的组合,最有可能找不到空结果的原因是什么也找不到。 – barny

我在我的生活中编程了50行Python,所以如果我在这里弄错了,不好意思。

zl_Rahmen_bin = np.zeros((img.shape[0], img.shape[1]), dtype=np.uint8) 

你刚刚创建了一个填充零的二维数组。

zl_Rahmen_bin = np.vectorize(high_blue) 

你现在立即指派另一个值(函数),以相同的变量,这使得第一线相当过时。

zl_Rahmen_bin = zl_Rahmen_bin(b1, b2) 

所以据我了解它,你只是调用的函数z1_Rahmen_bin并提供了蓝色和绿色的图像作为输入。输出应该是另一个二维数组,其值为0或255.

我想知道np.vectorize如何知道输出应该是哪种数据类型。你显然需要uint8。 documentation表示如果不给出该类型,则通过使用第一个参数调用该函数来确定。所以我猜这个例子中的默认类型是255或0。

和z1_Rahmen_bin.dtype实际上是np.uint32。

所以我修改了这个:

zl_Rahmen_bin = np.vectorize(high_blue) 

zl_Rahmen_bin = np.vectorize(high_blue, otypes=[np.uint8]) 

这似乎做的工作。

也许就足够了只是做

z1_Rahmen_bin.dtype = np.uint8 

但正如我说我不知道​​Python的想法...

+0

@AvishekDutta我只是做了一个疯狂的猜测并将其打印:)'print(zl_Rahmen_bin.dtype)' – Piglet