Seite 1 von 1

suchen Indizes von RGB-Werten in numpy 3D arrays

Verfasst: Dienstag 31. August 2021, 14:47
von Erhy
Hallo,
vielleicht eine Newbie Frage:
Wie finde ich die Indizes in einem Image-Array für das Vorkommen eines bestimmten RGB Werts?
Wo ich gescheitert bin:

Code: Alles auswählen

be = np.arange( 5 * 4 * 3)
# zum Beispiel
be[ ( be % 3 )  != 0 ] = 0 
be[ ( be % 4 ) == 0] = 0
be_rgb = be.reshape( 5, 4, 3)
be_rgb
[
[[ 0, 0, 0], [ 3, 0, 0], [ 6, 0, 0], [ 9, 0, 0]],
[[ 0, 0, 0], [15, 0, 0], [18, 0, 0], [21, 0, 0]],
[[ 0, 0, 0], [27, 0, 0], [30, 0, 0], [33, 0, 0]],
[[ 0, 0, 0], [39, 0, 0], [42, 0, 0], [45, 0, 0]],
[[ 0, 0, 0], [51, 0, 0], [54, 0, 0], [57, 0, 0]]
]

sub = np.array( [0,0,0], dtype=be_rgb.dtype )

be_rgb_w = np.where( be_rgb[ : , : ] == sub )

be_rgb[ : , : ][ be_rgb_w ]
# ist:
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0])
# anstatt wie von mir erwartet
[[ 0, 0, 0],
 [ 0, 0, 0],
 [ 0, 0, 0],
 [ 0, 0, 0],
 [ 0, 0, 0]]
Ich möchte die gefundenen RGB Werte separat verändern.

Danke für eure Tipps
Erhy

Re: suchen Indizes von RGB-Werten in numpy 3D arrays

Verfasst: Dienstag 31. August 2021, 15:26
von __blackjack__
@Erhy: Damit findest Du die 0en *in* den Pixeln. Wenn Du die Pixel finden willst, musst Du das Ergebnis vom Vergleich mit `sub` noch reduzieren auf die RGB-Werte bei denen alle drei Komponenten mit `sub` übereinstimmen:

Code: Alles auswählen

In [15]: be_rgb                                                                 
Out[15]: 
array([[[ 0,  0,  0],
        [ 3,  0,  0],
        [ 6,  0,  0],
        [ 9,  0,  0]],

       [[ 0,  0,  0],
        [15,  0,  0],
        [18,  0,  0],
        [21,  0,  0]],

       [[ 0,  0,  0],
        [27,  0,  0],
        [30,  0,  0],
        [33,  0,  0]],

       [[ 0,  0,  0],
        [39,  0,  0],
        [42,  0,  0],
        [45,  0,  0]],

       [[ 0,  0,  0],
        [51,  0,  0],
        [54,  0,  0],
        [57,  0,  0]]])

In [16]: sub                                                                    
Out[16]: array([0, 0, 0])

In [17]: be_rgb == sub                                                          
Out[17]: 
array([[[ True,  True,  True],
        [False,  True,  True],
        [False,  True,  True],
        [False,  True,  True]],

       [[ True,  True,  True],
        [False,  True,  True],
        [False,  True,  True],
        [False,  True,  True]],

       [[ True,  True,  True],
        [False,  True,  True],
        [False,  True,  True],
        [False,  True,  True]],

       [[ True,  True,  True],
        [False,  True,  True],
        [False,  True,  True],
        [False,  True,  True]],

       [[ True,  True,  True],
        [False,  True,  True],
        [False,  True,  True],
        [False,  True,  True]]])

In [18]: np.all(be_rgb == sub, axis=-1)                                         
Out[18]: 
array([[ True, False, False, False],
       [ True, False, False, False],
       [ True, False, False, False],
       [ True, False, False, False],
       [ True, False, False, False]])

In [19]: be_rgb[np.all(be_rgb == sub, axis=-1)]                                 
Out[19]: 
array([[0, 0, 0],
       [0, 0, 0],
       [0, 0, 0],
       [0, 0, 0],
       [0, 0, 0]])

Re: suchen Indizes von RGB-Werten in numpy 3D arrays

Verfasst: Dienstag 31. August 2021, 16:33
von Erhy
Danke für die schnelle Antwort.

Das Beispiel hat nur den Nachteil, dass wenn ich

Code: Alles auswählen

be_rgb_found = be_rgb[np.all(be_rgb == sub, axis=-1)]
bearbeite,
wirkt sich dies im Ursprungs-Array aus
z.B.

Code: Alles auswählen

be_rgb_found [0,1] = 255
be_rgb ist unverändert!

Wie bekomme ich ein Ergebnis analog von np,where,
bei dem die Indices zurückgegeben weden ?

Re: suchen Indizes von RGB-Werten in numpy 3D arrays

Verfasst: Dienstag 31. August 2021, 16:57
von __blackjack__
@Erhy: Naja, mit `np.where()`:

Code: Alles auswählen

In [12]: np.where(np.all(be_rgb == sub, axis=-1))                               
Out[12]: (array([0, 1, 2, 3, 4]), array([0, 0, 0, 0, 0]))
Aber auch da bekommst Du eine Kopie der Pixel-Arrays wenn Du das als Index in das `be_rgb`-Array verwendest. Weil das Ergebnis nicht mehr als View in das Original-Array repräsentiert werden kann. Also im konkreten Fall ginge das zufälligerweise noch, aber der Code muss ja vom allgemeinen Fall ausgehen, dass die gefundenen Pixel beliebig verteilt sein können.

Re: suchen Indizes von RGB-Werten in numpy 3D arrays

Verfasst: Mittwoch 1. September 2021, 13:30
von Erhy
hier mein Beispiel, um schwarze Pixeln zu verrauschen:

Code: Alles auswählen

import numpy as np

be = np.arange( 5 * 4 * 3)
# data for example
be[(be % 3) !=0 ] = 0
be[(be % 4) ==0 ] = 0
be_rgb = be.reshape(5,4,3)

be_rgb_sub = np.array([0,0,0],dtype=be_rgb.dtype)

rgbreduced = be_rgb == be_rgb_sub # if equql values on the same position than true

be_rgb_logical = np.all(rgbreduced, axis=-1) # if all in the last axis are True than True

be_rgb_indices = np.where(be_rgb_logical) # the same as be_rgb_logical == True

# data for modification of the found rgb values
rgb_to_modify_flat = np.zeros( ( be_rgb_indices[0].shape[0] * be_rgb.shape[-1] ), dtype=be_rgb.dtype )

rgb_to_modify_flat[1::2] = 2

rgb_to_modify = rgb_to_modify_flat.reshape( ( be_rgb_indices[0].shape[0], be_rgb.shape[-1] ))

be_rgb[be_rgb_indices] += rgb_to_modify # modify the found RGB values

Re: suchen Indizes von RGB-Werten in numpy 3D arrays

Verfasst: Mittwoch 1. September 2021, 14:48
von __blackjack__

Code: Alles auswählen

import numpy as np

be = np.arange(5 * 4 * 3)
# data for example
be[(be % 3 != 0) & (be % 4 == 0)] = 0
be_rgb = be.reshape(5, 4, 3)

indices = np.all(be_rgb == [0, 0, 0], axis=-1).nonzero()

noise = np.zeros(len(indices[0]) * 3, dtype=be_rgb.dtype)
noise.reshape(-1)[1::2] = 2

be_rgb[indices] = noise.reshape(-1, 3)