大多数操作的工作方式与在相同大小的NumPy数组上的标量一样。我重写了这个函数,
def count_new(base, image, thresh=50): # these are the pixel absolute value differences differences = np.abs(base - image) # whether the difference exceeds the threshold big_difference = differences > thresh # whether each pixel has at least one big difference big_difference = big_difference.any(axis=2) # return 255 where big differences, and 0 everywhere else return 255 * big_difference.astype(int)
希望这些评论能够清楚地表明每一行的意图。同时检查这与前一个输出相同
x = np.random.randint(256, size=(10, 11, 3)) y = np.random.randint(256, size=(10, 11, 3)) assert((count(x,y) == count_new(x,y)).all())
这显示了它。
矢量化代码看起来很简单,除了一个问题:您的数据似乎是无符号的整数( uint8 从它的外观来看,它需要一些额外的关注,因为它们经常下溢并带来意想不到的结果。例如,显而易见的 np.abs(image-base)>50 事实上,检测大于50的差异是行不通的 np.abs 是无符号数据的nop。仔细翻译看起来更像
uint8
np.abs(image-base)>50
np.abs
sheet = np.array([[0,0,0],[255,255,255]], 'u1')[((np.maximum(base, image)-np.minimum(base, image))>50).any(2).view('u1')]
要么
sheet = np.array([[0,0,0],[255,255,255]], 'u1')[(np.abs(np.subtract(image, base, dtype='i2'))>50).any(2).view('u1')]
这个
正确计算亚像素明智的差异,
第一个版本模仿你的if / else子句
第二个强制签名的结果类型 'i2' 要么 int16 为了差异
'i2'
int16
检测到那些更大的50,
标记具有至少一个这样的子像素的像素( any(2) )
any(2)
将生成的布尔掩码转换为索引( .view('u1') )0和1
.view('u1')
并使用它们索引到模板数组。