Python 将numpy数组的每个元素乘以一个元组
给定一个二维numpy图像数组,其中shapePython 将numpy数组的每个元素乘以一个元组,python,arrays,numpy,multidimensional-array,Python,Arrays,Numpy,Multidimensional Array,给定一个二维numpy图像数组,其中shape(height,width,3),BGR元组作为元素,我想将每个元素乘以一个内核,分别提取B/G/R通道。例如,蓝色内核将是(1,0,0)。大概是这样的: # extact color channel def extract_color_channel(image, kernel): channel = np.copy(image) height, width = image.shape[:2] for y in range(0,
(height,width,3)
,BGR元组作为元素,我想将每个元素乘以一个内核,分别提取B/G/R通道。例如,蓝色内核将是(1,0,0)
。大概是这样的:
# extact color channel
def extract_color_channel(image, kernel):
channel = np.copy(image)
height, width = image.shape[:2]
for y in range(0, height):
for x in range(0, width):
channel[y,x] = image[y, x] * kernel
return channel
# extract blue channel
def extract_blue(image):
return extract_color_channel(image, (1, 0, 0))
最有效的“numpy方式”是什么?使用示例数组:
In [220]: arr = np.arange(5*5*3).reshape(5,5,3)
基本索引是最有效的方法(这将是一个视图
)
[1,0,0]
列表不是您想要的。但是你可以把它变成布尔数组
In [222]: kernel = np.array([1,0,0],dtype=bool)
In [223]: kernel
Out[223]: array([ True, False, False], dtype=bool)
In [224]: arr[:,:,kernel].shape
Out[224]: (5, 5, 1)
In [225]: arr[:,:,kernel].squeeze()
Out[225]:
array([[ 0, 3, 6, 9, 12],
[15, 18, 21, 24, 27],
[30, 33, 36, 39, 42],
[45, 48, 51, 54, 57],
[60, 63, 66, 69, 72]])
请注意,带有布尔值的形状仍然是三维的。如果你不想这样,那么你需要重塑或挤出最后的尺寸。此索引速度较慢,因为它会生成副本
此布尔索引相当于
In [226]: arr[:,:,[0]].shape
Out[226]: (5, 5, 1)
其中[0]
是内核中“true”值的位置
您也可以使用点
(矩阵积):
它将比索引速度慢
元素乘法:
[232]中:arr*np.数组([1,0,0])
输出[232]:
数组([[0,0,0],
[ 3, 0, 0],
[ 6, 0, 0],
[ 9, 0, 0],
[12,0,0]]
[[15, 0, 0],
[18, 0, 0],
....
[66, 0, 0],
[69, 0, 0],
[72, 0, 0]]])
在这个乘法中,[1,0,0]的行为就好像它是一个(1,1,3)数组,并且用(n,n,3)进行广播很好。为什么不只是image[:,:,0]
?我对numpy是新手,你能解释一下/给我指出0
的解释吗?为什么不image[:,:,:,kernel]
?阅读numpy文档…这是完全基本的!这是基本索引,意味着您要从数组中提取一个切片,然后指定相应的索引。请参见此处。好的,我看到了此处发生的情况。在图像上下文中,图像[:,:,0]
丢弃红色和绿色通道,并从蓝色通道生成灰度图像。有没有办法不丢弃这些通道,而将它们设置为0?因此,如果我输出图像,它仍然以彩色显示?而不是使用图像[:,:,0]切片蓝色通道
,我只是将1和2个通道归零?这很有帮助,但我遗漏了一些东西。如果在我的示例数组中,我改为:arr=np.ones([5,5,3])*255,设置每个“像素”白色。我想要的是运行extract\u blues
获得一个平坦的蓝色图像,extract\u reds
获得一个平坦的红色图像,等等。我不想更改数组的形状。在我的示例中,每个值arr[y,x]
产生(255,255)
。在extract\u blues
之后,每个值arr[y,x]
应该生成(255,0,0)
。很抱歉,我可能在与[:,:,0]
进行比较时偏离了轨道。请确定您可以将(n,n,3)乘以(3,).他们一起广播。其他数学也很有用。点
就是这样的乘法加和。我专注于“提取”,而不是修改或构建新图像。是的,单词选择:/。无论如何,这让我走上了正确的轨道。还有“提取”不管怎样,从长远来看,灰度化可能是我想要做的。接受这个,谢谢你的帮助。
In [228]: np.dot(arr,[1,0,0])
Out[228]:
array([[ 0, 3, 6, 9, 12],
[15, 18, 21, 24, 27],
[30, 33, 36, 39, 42],
[45, 48, 51, 54, 57],
[60, 63, 66, 69, 72]])
[[15, 0, 0],
[18, 0, 0],
....
[66, 0, 0],
[69, 0, 0],
[72, 0, 0]]])