11

I am using OpenCV with Python. I have an image, and what I want to do is set all pixels of BGR value [0, 0, 255] to [0, 255, 255].

I asked a previous question on how to posterize an image, and from the answer I learned about indexing with an Array of indices, for ex: image[image > 128] = 255

I understand how this works, since image > 128 will return an array of multi-dimensional array of indices that satisfy the condition, and then I apply this array to the image and set those to 255. However, I'm getting confused with how to extend this to doing a value for an array.

I tried doing the following:

      red = np.array([0, 0, 255])
      redIndex = np.where(np.equal(image, red))
      image[redIndex] = np.array([0, 255, 255])

but it doesn't work, with the error:

ValueError: array is not broadcastable to correct shape

Is there an efficient way to handle this?

Community
  • 1
  • 1
steve8918
  • 1,820
  • 6
  • 27
  • 38
  • 2
    I need an answer in Python hopefully using something available with NumPy, not C++, so it's not a duplicate. – steve8918 Jul 11 '12 at 13:55
  • Hi, do you want to create an image with all elements [0,255,255] or just change all elements in an image with value [0,0,255] to [0,255,255]? – Abid Rahman K Jul 11 '12 at 14:04
  • Hi, I would like to change all elements in an image with value [0,0,255] to [0,255,255], thanks – steve8918 Jul 11 '12 at 14:11

1 Answers1

20

Consider an image like array as below :

>>> red
array([[[  0,   0, 255],
        [  0,   0, 255],
        [  0,   0, 255],
        [  0,   0, 255],
        [  0,   0, 255]],

       [[  0,   0, 255],
        [  0,   0, 255],
        [  0,   0, 255],
        [  0,   0, 255],
        [  0,   0, 255]]])

Its all elements are [0,0,255]. Its shape is 2x5x3. Just think there are other values also in it. (I can't create all those).

Now you find where [0,0,255] are present and change them to [0,255,255]. You can do it as follows :

>>> red[np.where((red == [0,0,255]).all(axis = 2))] = [0,255,255]

Now check the red.

>>> red
array([[[  0, 255, 255],
        [  0, 255, 255],
        [  0, 255, 255],
        [  0, 255, 255],
        [  0, 255, 255]],

       [[  0, 255, 255],
        [  0, 255, 255],
        [  0, 255, 255],
        [  0, 255, 255],
        [  0, 255, 255]]])

Hope this is what you want.

Test Results:

Check out the code from this link : https://stackoverflow.com/a/11072667/1134940

I want to change all red pixels to yellow as asked in question.

So i added this below piece of code at the end :

im2[np.where((im2 == [0,0,255]).all(axis = 2))] = [0,255,255]

Below is the result I got :

enter image description here

What if i want to change green ground to yellow ground :

im2[np.where((im2 == [0,255,0]).all(axis = 2))] = [0,255,255]

Result :

enter image description here

Community
  • 1
  • 1
Abid Rahman K
  • 51,886
  • 31
  • 146
  • 157
  • Hey I have a question. Is there any way I can make use of this method if I need to set all pixels of a **range of BGR values** instead of a specific pixel value to another value? Thanks! – annena Jun 26 '15 at 07:54
  • I am trying this example but no change in image im = cv2.imread('it_captcha_green.jpg') im[np.where((im == [140, 230, 140]).all(axis=2))] = [0, 0, 0] cv2.imshow('grey image',im) – Jeya Kumar Sep 19 '18 at 10:53