0

I have images that I would like to convert to red in case there is any green. If there's red, I'd like to keep it.

The images are in numpy arrays as follows:

x.shape (50, 15, 3)

In a fist instance I would like to take the max value of the first two elements of the third dimension (R and G) and set the corresponding value to R (the first element). Then I would like to set the second element (G) of the third dimension zo zero.

How can I do this? Essentially it woul need to be something like that:

x[:,:,0] = max(x[:,:,0],x[:,:,1])
x[:,:,1] = 0
Nickpick
  • 6,163
  • 16
  • 65
  • 116
  • 1
    Are you sure this is what you want to do? The value of the green colour plane contributes to most colours in the RGB spectrum, even to those that don't appear green. By setting it to 0, you're limiting yourself only to 256*256 colours. – Reti43 Oct 12 '17 at 11:11
  • (1) you can do it in loop. (2) you can split image to single channels, do mask op , `B[R>B]=0`, then merge – Kinght 金 Oct 12 '17 at 11:13
  • So you want pure yellow to turn to pure red, and white to become magenta? – PM 2Ring Oct 12 '17 at 11:13
  • 2
    @Silencer The general rule with Numpy is that if you find yourself looping over an array you're probably doing it wrong. Let Numpy do the looping for you, at C speed. If you use slow Python loops there's not much point using Numpy. – PM 2Ring Oct 12 '17 at 11:15
  • @Reti43 I only want black and red as I have a neural network that is trained on black and red cards. But sometimes they use green instead of red, in which case I want to convert green to red. Any better suggestions? – Nickpick Oct 12 '17 at 12:09
  • If you're only using the colours [255, 0, 0] (red) and [0, 0, 0] (black), the question you're asking is reasonable I guess. Though it still begs the question why you don't use a greyscale, with 255 indicating the presence of colour and 0 just black. – Reti43 Oct 12 '17 at 12:14
  • Because for my problem (recognizing standard 52 game cards with a neural network for playing poker), the current solution which is using grayscale has difficulties differentiating between club and diamond cards. I'm hoping the using red and black will help to solve that problem. But sometimes cards are green instead of red (and I don't use that for training), so I need to have everything that is green converted to red. – Nickpick Oct 12 '17 at 12:23
  • @nickpick So in essence, you want to convert all green `(0,255,0)` to be converted to `(255,0,0)`? So, anything that looks green like `(0,254,0)` won't be covered? – Divakar Oct 12 '17 at 12:26
  • Well, everything that looks greenish should become redish. I'm also ok to use PIL rather the numpy if that's easier – Nickpick Oct 12 '17 at 12:34
  • Well, then we need to define what's reddish and what's greenish, some kind of tolerance value. – Divakar Oct 12 '17 at 12:50
  • Opened a new question for that: https://stackoverflow.com/questions/46710213/convert-greenish-to-redish – Nickpick Oct 12 '17 at 12:57

1 Answers1

1

It seems you have already figured out the second step. Here's one way to do the first step -

x[...,0] = x[...,:2].max(axis=-1)

Alternatively, we can also use np.maximum for the element-wise max computation -

x[...,0] = np.maximum(x[...,0], x[...,1])

Alternatively, we can also use masking -

mask = x[...,0] < x[...,1]
x[mask,0] = x[mask,1]
Divakar
  • 218,885
  • 19
  • 262
  • 358
  • They are both identical? Would the .max(-1) not take the maximum accross the entire axis? – Nickpick Oct 12 '17 at 11:12
  • @nickpick That was a shortcut for `axis=-1` i.e. along the last axis considering only the first two elements because we had sliced with `...,:2]`. Edited. – Divakar Oct 12 '17 at 11:13