给定一个形状为(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方式”是什么?
答案 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)广播就好了。