用元组乘以numpy数组的每个元素

时间:2017-03-03 00:58:23

标签: python arrays numpy multidimensional-array

给定一个形状为(height, width, 3)的2D numpy图像数组,并将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方式”是什么?

1 个答案:

答案 0 :(得分:2)

使用示例数组:

view

基本索引是最有效的方式(这将是In [221]: arr[:,:,0] Out[221]: 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]])

[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]]) 列表不是您想要的。但你可以把它作为一个bool数组。

copy

请注意,布尔值的形状仍为3d。如果你不想要那个,那么你需要重新塑造或挤压最后一个维度。此索引编制速度较慢,因为它生成In [226]: arr[:,:,[0]].shape Out[226]: (5, 5, 1)

这个布尔索引相当于

[0]

其中kernel是' true'的位置。 dot中的值。

您还可以使用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]]])

它会比索引慢。

元素乘法:

在[232]中:arr * np.array([1,0,0]) 出[232]: 数组([[[0,0,0,         [3,0,0],         [6,0,0],         [9,0,0],         [12,0,0]],

var client = new JsonServiceClient(baseUrl) {
    BearerToken = jwtToken
};

在这个乘法中,[1,0,0]表现得好像是一个(1,1,3)数组,并且用(n,n,3)广播就好了。