将函数应用于3D numpy数组 [英] Apply functions to 3D numpy array

查看:108
本文介绍了将函数应用于3D numpy数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个来自Image(PIL / Pillow)对象的numpy 3D数组。

I have a numpy 3D array from Image(PIL/Pillow) object.

 [[178 214 235]
  [180 215 236]
  [180 215 235]
  ..., 
  [146 173 194]
  [145 172 193]
  [146 173 194]]
 ..., 
 [[126 171 203]
  [125 169 203]
  [128 171 205]
  ..., 
  [157 171 182]
  [144 167 182]
  [131 160 180]]]

图片大小约为500x500像素。我需要为每个像素应用两个函数。

Image size about 500x500 px. I need to apply two functions for each pixel.


  1. 将RGB转换为LAB(使用来自 python-colormath
    此函数采用一维数组,例如 [157,171,182] 并返回带有LAB颜色的一维数组,例如 [53.798345635,-10.358443685,100.358443685]

  2. 使用 scipy.spatial从自定义调色板中找到最接近的颜色。 cKDTree

  1. Convert RGB to LAB (using functions from python-colormath) This function takes 1D array like [157, 171, 182] and return 1D array with LAB color, e.g. [53.798345635, -10.358443685, 100.358443685].
  2. Find nearest color from custom palette using scipy.spatial.cKDTree.

自定义调色板为 kd树

palette = [[0,0,0], [127,127,127], [255,255,255]] #  or [[0.,0.,0.], [50.,0.,0.], [100.,0.,0.]] for LAB color
tree = scipy.spatial.cKDTree(palette)
def find nearest(pixel):
    distance, result = tree.query(pixel)
    new_pixel = palette[result]
    return new_pixel

有更快的速度吗?解决方案,而不是用Python进行迭代?例如,

Is there a faster solution than iterating with Python? E.g.

for row in array:
    for pixel in row:
        apply_fuction1(pixel) # where pixel is one dimensional array like [157 171 182]
        apply_fuction2(pixel)

UPD1 ,我不知道自己在做什么错,但是:

UPD1 I dont know what I am doing wrong, but:

python3 -mtimeit -s'import test' 'test.find_nearest()' # my variant with 2 loops and Image.putdata()
10 loops, best of 3: 3.35 sec per loop
python3 -mtimeit -s'import test' 'test.find_nearest_with_map()' # list comprehension with map and Image.fromarray() by traceur
10 loops, best of 3: 3.67 sec per loop
python3 -mtimeit -s'import test' 'test.along_axis()' # np.apply_along_axis() and Image.fromarray() by AdrienG
10 loops, best of 3: 5.25 sec per loop

def find_nearest(array=test_array):
    new_image = []
    for row in array:
        for pixel in row:
            distance, result = tree.query(pixel)
            new_pixel = palette[result]
            new_image.append(new_pixel)
    im = Image.new('RGB', (300, 200))
    im.putdata(new_image)


def _find_nearest(pixel):
    distance, result = tree.query(pixel)
    new_pixel = palette[result]
    return new_pixel


def along_axis(array=test_array):
    array = np.apply_along_axis(_find_nearest, 2, array)
    im = Image.fromarray(np.uint8(array))


def find_nearest_with_map(array=test_array):
    array = [list(map(_find_nearest, row)) for row in array]
    im = Image.fromarray(np.uint8(array))


推荐答案

很抱歉,

使用 numpy.apply_along_axis

a = np.arange(12).reshape((4,3))
def sum(array):
    return np.sum(array)

np.apply_along_axis(sum, 1, a)
>>> array([ 3, 12, 21, 30])

这篇关于将函数应用于3D numpy数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆