在python opencv cv2中的掩码无法正常工作?

tho*_*ash 5 python opencv

虽然一般来说opencv(cv2)的新python绑定是一种美,但"面具"似乎并没有正常工作 - 除非我真的弄错了:

例如,"cv2.add"仍然可以在没有遮罩的情况下正常工作:

import cv2
a = ones((2,2,3), dtype=uint8)
cv2.add(a,a)
Run Code Online (Sandbox Code Playgroud)

正确给出

array([[[2, 2, 2],
        [2, 2, 2]],

       [[2, 2, 2],
        [2, 2, 2]]], dtype=uint8)
Run Code Online (Sandbox Code Playgroud)

但是当你添加一个掩码(和一个out数组"b" - 由于某种原因而未被指定)时,你得到一个RANDOM结果,即当你多次运行命令时结果会改变

myMask = zeros(a.shape[0:2], dtype = uint8)
mask[1,1] = 255
b = zeros(a.shape)
cv2.add(a,a,b,myMask)
cv2.add(a,a,b,myMask)
Run Code Online (Sandbox Code Playgroud)

在我的机器上给出(Win7,32bit,Python 2.7,opencv 2.3.1)

In [34]: cv2.add(a,a,b,myMask)
Out[34]: 
array([[[ 26,   0, 143],
        [  5, 216, 245]],

       [[156,   5, 104],
        [  2,   2,   2]]], dtype=uint8)

In [35]: cv2.add(a,a,b,myMask)
Out[35]: 
array([[[35,  0,  0],
        [ 0,  3,  0]],

       [[ 0,  0,  3],
        [ 2,  2,  2]]], dtype=uint8)
Run Code Online (Sandbox Code Playgroud)

...以及下一次试验的新内容.现在我得到了严重的错误,或者cv2绑定存在严重问题.

有什么建议?

Neo*_*n22 5

这是一个有趣的问题.我看到了同样的问题.我发布了一个错误并得到了回复.http://code.opencv.org/issues/1748

解决方案很简单.dst数组在创建时未定义,并且操作仅更改那些目标数组像素p,其掩码(p)!= 0.

因此唯一有效的机制是在添加之前预先制作dst.即

dst = np.zeros(...)
dst = cv2.add(a, a, dst=dst, mask=mask)
Run Code Online (Sandbox Code Playgroud)

下一个版本将在cv2.add,cv2.subtract,cv2.bitwise_and /或/ xor等操作中清除新创建的图像 - 因此它可以正常工作.

我的代码看起来像:

import cv2
import numpy as np
import time

a = np.ones((2,2,3), dtype=np.uint8)

print "simple add"
t = time.time()
for i in range(10000):
    b = cv2.add(a,a)
print "%5.4f seconds" % (time.time()-t)
print b

print "\nnumpy add"
t = time.time()
for i in range(10000):
    b = a+a
print "%5.4f seconds" % (time.time()-t)
print b

# make mask same dimensions but 1 byte deep(not three)
mask = np.zeros(a.shape[:-1], dtype=np.uint8)
mask[1,1] = 255

print "\nmask", mask.shape
print mask

print "\nmasked add - uninitialised"
t = time.time()
for i in range(10000):
    b = cv2.add(a,a,mask=mask)
print "%5.4f seconds" % (time.time()-t)
print b
print "uninitialised entries are unmodified - so random.\n Inconsistent when run more than once."
print "same calc a second time..."
b = cv2.add(a,a,mask=mask)
print b

print "\nmasked add - using preinitialised dst"
t = time.time()
b = a.copy()
for i in range(10000):
    b = cv2.add(a,a,b,mask=mask)
print "%5.4f seconds" % (time.time()-t)
print b
print "Consistent when run more than once."
print "same calc a second time..."
b = a.copy()
b = cv2.add(a,a,b,mask=mask)
print b
Run Code Online (Sandbox Code Playgroud)

仅供参考:时间安排(重复10k):

cv2.add - no mask            0.0120 seconds
cv2.add - with mask          0.0160 seconds
np.add                       0.0190 seconds
cv2.add - uninitialised mask 0.0220 seconds
Run Code Online (Sandbox Code Playgroud)

仅供参考:按照以下说明提交错误:http: //code.opencv.org/projects/OpenCV/wiki/WikiStart


小智 0

为什么不使用 numpy (就地)掩码表达式?

b = array(a, copy=True)
b[mask] += a
Run Code Online (Sandbox Code Playgroud)

mask 是一个布尔数组,在 opencv (cv2.add) 中模拟,当 mask != 0 时,值会更改

PS:但是,你的代码在我的机器上运行良好(Win7 64,Python 2.6(32位),OpenCV 2.3.0)