python 遍历数组_python-3.x-如何遍历数组将阈值应用于每个像...

简单的一线解决方案

您可以像这样在一行中完成所需的操作:

new_img = (((image - color)**2).sum(axis=2)**.5 <= 10) * 255

优化的两线解决方案

上一行不是执行OP所需的所有操作的最有效方式.这是一种明显更快的方法(感谢Paul Panzer在注释中提出优化建议,但不能保证可读性):

d = image - color

new_img = (np.einsum('...i, ...i', d, d) <= 100) * 255

时间:

给定一些100×100像素的测试数据:

import numpy as np

color = np.array([30, 70, 130])

# random data within [20,60,120]-[40,80,140] for demo purposes

image = np.random.randint(10*2 + 1, size=[100,100,3]) + color - 10

这是OP方法的时序与该答案的解决方案的比较.一站式解决方案比OP解决方案快约100倍,而完全优化的版本则比OP快约300倍:

%%timeit

# OP's code

img_dim = image.shape

new_img = np.zeros((img_dim[0],img_dim[1])) # no alpha channel replica

for c in range(img_dim[0]):

for r in range(img_dim[1]):

pixel = image[r,c,:3]

new_img[r,c] = L2_dist(color,pixel)

43.8 ms ± 502 ?s per loop (mean ± std. dev. of 7 runs, 10 loops each)

%%timeit

# one line solution

new_img = (((image - color)**2).sum(axis=2)**.5 <= 10) * 255

439 ?s ± 13.7 ?s per loop (mean ± std. dev. of 7 runs, 1000 loops each)

%%timeit

# fully optimized solution

d = image - color

new_img = (np.einsum('...i, ...i', d, d) <= 100) * 255

145 ?s ± 2.29 ?s per loop (mean ± std. dev. of 7 runs, 10000 loops each)

简单的一线解决方案的说明

作为第一个解决方案提供的简单的单线将:

>查找图像中每个像素(将是形状(m,n,3)的数组)和颜色(将被形状(3)的数组)之间的欧几里得距离.

>检查这些距离中的任何一个是否在10之内,并在满足条件的任何地方返回一个布尔数组,该数组为True,否则为False.

>布尔数组实际上只是0和1的数组,因此我们将布尔数组乘以255,以获得所需的最终结果.

优化解决方案的说明

以下是使用的优化列表:

>使用einsum来计算距离计算所需的平方和.在后台,einsum利用Numpy包装的BLAS库来计算所需的求和积,因此它应该更快.

>通过比较距离的平方与阈值的平方来跳过平方根.

>我试图找到一种最小化数组分配/复制的方法,但这实际上使事情变慢了.这是优化解决方案的一个版本,该版本恰好分配两个数组(一个分配给中间结果,一个分配给最终结果),并且不进行其他复制:

%%timeit

# fully optimized solution, makes as few array copies as possible

scr = image.astype(np.double)

new_img = np.zeros(image.shape[:2], dtype=np.uint8)

np.multiply(np.less_equal(np.einsum('...i,...i', np.subtract(image, color, out=scr), scr, out=scr[:,:,0]), 100, out=new_img), 255, out=new_img)

232 ?s ± 7.72 ?s per loop (mean ± std. dev. of 7 runs, 1000 loops each)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值