Python Numpy-如何从4个输入图像中创建新图像,选择最亮的像素(最大(R+G+B))

Python Numpy-如何从4个输入图像中创建新图像,选择最亮的像素(最大(R+G+B)),python,numpy,multidimensional-array,Python,Numpy,Multidimensional Array,有以下四种图像阵列: image1 = np.array([ [ # [R G B] # | | | [1, 2, 3], [11, 22, 55], [12, 45, 56] ], [ [1, 2, 3], [56, 55, 13], [12, 45, 56] ], [ [11, 22, 55], [56, 55, 13], [12, 45, 56] ], ])

有以下四种图像阵列:

image1 = np.array([
    [
      # [R  G  B]
      #  |  |  |
        [1, 2, 3], [11, 22, 55], [12, 45, 56]
    ],
    [
        [1, 2, 3], [56, 55, 13], [12, 45, 56]
    ],
    [
        [11, 22, 55], [56, 55, 13], [12, 45, 56]
    ],
])

image2 = np.array([
    [
        [91, 72, 33], [111, 222, 155], [212, 245, 156]
    ],
    [
        [100, 200, 113], [56, 255, 213], [112, 145, 156]
    ],
    [
        [113, 223, 255], [156, 55, 113], [212, 245, 156]
    ],
])

image3 = np.array([
    [
        [9, 2, 3], [111, 222, 255], [22, 25, 16]
    ],
    [
        [10, 20, 13], [156, 25, 23], [12, 45, 16]
    ],
    [
        [13, 23, 155], [56, 255, 13], [222, 235, 216]
    ],
])

image4 = np.array([
    [
        [29, 22, 23], [111, 222, 255], [223, 125, 216]
    ],
    [
        [210, 220, 13], [156, 252, 232], [122, 145, 216]
    ],
    [
        [123, 232, 155], [56, 255, 213], [222, 235, 216]
    ],
])
对于每一行和每一列,我想计算图像阵列的红色、绿色和蓝色通道之和的最大RGB值,并使用最大值构建一个新的图像阵列

所以在尝试了下面的代码之后,它得到了重复的索引,因为在每行和每列中,三个图像数组的最大RGB可能是重复的。但我只想得到第一个匹配索引

array = np.array([image1, image2, image3, image4])
array_sum = array.sum(axis=3)
# array_sum_max_index = array_sum.argmax(axis=0)
indices = np.where(array_sum == array_sum.max(axis=0))
print(indices)
输出

(array([1, 1, 1, 2, 2, 3, 3, 3, 3, 3, 3]), array([0, 0, 2, 0, 2, 0, 1, 1, 1, 2, 2]), array([0, 2, 0, 1, 2, 1, 0, 1, 2, 1, 2]))
在这方面也有类似的答案,但它不能解决我的问题。因此,如何在索引首次匹配时获取索引

编辑:

输入图像的实际数量超过32个。涉及numpy.choose的解决方案可能无法正常工作,因此

您可以使用:

这将为您提供每个位置最亮的最高R+G+B像素:

array([[196, 588, 613],
       [443, 640, 483],
       [591, 524, 673]])

结果与array_sum.maxaxis=0相同。

我想这就是您要寻找的:

np.choose(array_sum_max_index[...,None], tuple(array))
输出:

说明:

array_sum_max_index的形状为m,n,其中每个图像都是形状为m,n,3的数组

数组是形状为4,m,n,3的数组,tuplearray的每个元素都是形状为m,n,3的子数组

我们尝试使用np.choose,将数组\u sum\u max\u索引作为选择器数组传递,将tuplearray作为选择器将从中选择的子数组序列。但是正如您在numpy.choose的文档中所看到的,选择器数组和从中选择的子数组必须都可以一起广播。由于选择器数组数组_sum_max_index的形状为m,n,为了使其可以与形状为m,n,3的子数组一起广播,我们使用表达式数组_sum_max_index[…,None]向数组_sum_max_index追加一个额外的单位长度维度

如果我们只使用数组而不是tuplearray,这仍然有效,但是numpy.choose的文档不鼓励这样做


提出一个不使用numpy.choose的替代解决方案,因为OP已经指出在numpy.choose的情况下32个choose数组的约束是一个问题

array = np.array([image1, image2, image3, image4])
array_sum = array.sum(axis=3)
array_sum_max_index = array_sum.argmax(axis=0)

m = 3 # Number of pixel rows
n = 3 # Number of pixel columns

array[array_sum_max_index, np.arange(m)[:,None,], np.arange(n)[None,:]]
输出:


根据@fountainhead的回答,在一行中:

np.take_along_axis(array, array.sum(3).argmax(0)[None, ..., None], 0)

Out[]: 
array([[[[ 91,  72,  33],
         [111, 222, 255],
         [212, 245, 156]],

        [[210, 220,  13],
         [156, 252, 232],
         [122, 145, 216]],

        [[113, 223, 255],
         [ 56, 255, 213],
         [222, 235, 216]]]])

array\u sum\u max\u index或array\u sum.maxaxis=0如何不满足您的需要?在我看来这是正确的,但也许我误解了你的目标。array_sum_max_index给出array[[1,2,1],[3,3,3],[1,3,2]]告诉您每个像素处哪个图像最亮,array_sum.maxaxis=0给出从每个位置的所有图像中获取的最亮像素。我想使用最大RGB生成一个新数组,但是,如何通过数组_sum_max_索引访问数组对我来说很难。您出于某种原因注释掉的线数组_sum_max_索引=数组_sum.argmaxaxis=0正好提供了您在问题中要求的3,3新图像数组。是的,数组_sum_max_索引是正确的答案,但我不知道如何使用它访问数组。所以我试着从哪里获取索引,返回索引。我认为真正需要的是np.choosarray\u sum\u max\u index,数组。不,不太需要。在数组_sum_max_索引返回中,每个行和列的编号表示数组的最大RGB索引。因此,我可以通过array\u sum\u max\u index return生成一个新数组,但这对我来说很难。是的,但是numpy.choose允许至少0个最多32个数组对象通过。所以x的形状。。。对于数组,x必须介于0和32之间。@luneice-是否要将32个以上的图像传递给np。选择从中进行选择?是的,当传递32个以上的图像时,它得到了ValueError:至少需要0个,最多需要32个数组对象。在这种情况下,您需要将所有这些代码包装到一个函数中,并多次调用该函数。因此,如果您有50个图像,那么对函数的第一次调用将返回一个使用前32个图像中最亮像素的新图像。对函数的下一次调用必须传递此返回图像和剩余的18个图像,才能获得使用所有50个图像中最亮像素的最终图像。@luneice-我发布了一个不使用numpy.choose的不同答案。请看一看,很好。想想这些学习的日子,我一直在寻找numpy的真实世界用例!它是为这个用例设计的,但是它可能非常笨拙,因为需要数组和索引具有相同的维数,因此[None,…,None]
array = np.array([image1, image2, image3, image4])
array_sum = array.sum(axis=3)
array_sum_max_index = array_sum.argmax(axis=0)

m = 3 # Number of pixel rows
n = 3 # Number of pixel columns

array[array_sum_max_index, np.arange(m)[:,None,], np.arange(n)[None,:]]
array([[[ 91,  72,  33],
        [111, 222, 255],
        [212, 245, 156]],

       [[210, 220,  13],
        [156, 252, 232],
        [122, 145, 216]],

       [[113, 223, 255],
        [ 56, 255, 213],
        [222, 235, 216]]])
np.take_along_axis(array, array.sum(3).argmax(0)[None, ..., None], 0)

Out[]: 
array([[[[ 91,  72,  33],
         [111, 222, 255],
         [212, 245, 156]],

        [[210, 220,  13],
         [156, 252, 232],
         [122, 145, 216]],

        [[113, 223, 255],
         [ 56, 255, 213],
         [222, 235, 216]]]])