Joachim Huet
Joachim Huet

Reputation: 422

Change pixel color as a function of its color

It's hard to find a really descriptive title for this question but basically, I want to make the light grey colors whiter.

For now I'm doing something like that :

# Separate channels of image (from BGR format)
b, g, r = gray[:, :, 0], gray[:, :, 1], gray[:, :, 2]

# Create a mask for the whitish pixels
mask = (b > 128) & (g > 128) & (r > 128)

# Put thoses pixels as white
gray[:, :, :3][mask] = [255, 255, 255]

But I don't want them to be full white but only whiter, so taking into account their current value. Here the pseudo code of an example function :

if (r>128 && g>128 && b>128)
    r = r + (255-r)/2
    g = ...

How can I do this in python ? Thanks in advance for your help, and I hope it was clear enough.

Upvotes: 2

Views: 331

Answers (1)

Divakar
Divakar

Reputation: 221684

With a as the input RGB image, two vectorized approaches could be suggested.

Approach #1 : Create the mask of places to be modified keeping the dimensions and use np.where to do the choosing between the new values and old values and thus create a new image array -

mask = (a > 128).all(-1,keepdims=True)
new_vals = a + (255 - a)//2
a = np.where(mask, new_vals, a )

Approach #2 : Create the mask of places to be modified without keeping the dimensions and that let's us use boolean-indexing for in-situ edit -

mask = (a > 128).all(-1,keepdims=False)
a_masked = a[mask]
new_vals_masked = a_masked + (255 - a_masked)//2
a[mask] = new_vals_masked

Sample run -

In [34]: np.random.seed(0)

In [35]: a = np.random.randint(0,255,(2,2,3)).astype(np.uint8)

In [36]: a[0,0] = [200,180,160]

In [37]: a[1,1] = [170,150,220]

In [38]: a  # Original image array
Out[38]: 
array([[[200, 180, 160],
        [192,  67, 251]],

       [[195, 103,   9],
        [170, 150, 220]]], dtype=uint8)

In [39]: mask = (a > 128).all(-1,keepdims=True)
    ...: new_vals = a + (255 - a)//2
    ...: a = np.where(mask, new_vals, a )
    ...: 

In [40]: a # New array
Out[40]: 
array([[[227, 217, 207],
        [192,  67, 251]],

       [[195, 103,   9],
        [212, 202, 237]]], dtype=uint8)

Upvotes: 2

Related Questions