suchen Indizes von RGB-Werten in numpy 3D arrays

mit matplotlib, NumPy, pandas, SciPy, SymPy und weiteren mathematischen Programmbibliotheken.
Antworten
Erhy
User
Beiträge: 64
Registriert: Mittwoch 2. Januar 2019, 21:09

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
Benutzeravatar
__blackjack__
User
Beiträge: 13110
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@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]])
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Erhy
User
Beiträge: 64
Registriert: Mittwoch 2. Januar 2019, 21:09

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 ?
Benutzeravatar
__blackjack__
User
Beiträge: 13110
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@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.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Erhy
User
Beiträge: 64
Registriert: Mittwoch 2. Januar 2019, 21:09

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
Benutzeravatar
__blackjack__
User
Beiträge: 13110
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

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)
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Antworten