Create a multi-channel image from pixel coordinates extracted from another image

I have a list of mask images with the shape of(3100,3100,3),

I want to create a new image with 5 channels ( 3100,3100,5)

form each image to represent the different colours in each mask. I searched for the specific colours in each image to get the pixel coordinates of each colour,

after that I want to insert these pixels into the new 5 channel image:

Q7val

# Define the colours

 green= [0,255,0]
 blue=[ 0, 0, 255]
 yel=[255, 255, 0]
 red=[ 255, 0, 0]
 white=[255, 255, 255]


  # create the new image with 5 channels
  new_img=np.zeros( ( np.array(mask).shape[0], np.array(mask).shape[1], 5 ) )

 # find each colour coordinate

 new_img[0,0,1]=np.where(np.all(mask==green,axis=2))
 new_img[0,0,2]=np.where(np.all(mask==blue,axis=2))
 new_img[0,0,3]=np.where(np.all(mask==yel,axis=2))
 new_img[0,0,4]=np.where(np.all(mask==red,axis=2))
 new_img[0,0,5]=np.where(np.all(mask==white,axis=2))

it shows this error, how can I create this 5 channel image?

    > TypeError                                 Traceback (most recent call last)
     TypeError: float() argument must be a string or a number, not 'tuple'

     The above exception was the direct cause of the following exception:

     ValueError                                Traceback (most recent call last)
       <ipython-input-197-5b9c268857b2> in <module>
        19 new_img=np.zeros( ( np.array(mask).shape[0], np.array(mask).shape[1], 5 ) )
          20 
       ---> 21 new_img[0,0,1]=np.where(np.all(mask==benign,axis=2))
         22 new_img[0,0,2]=np.where(np.all(mask==blue,axis=2))
          23 new_img[0,0,3]=np.where(np.all(mask==yel,axis=2))

      ValueError: setting an array element with a sequence.

This is the correct syntax:

new_img[:,:,1] = np.all(mask==green,axis=2).astype(np.uint8)

(you can omit the .astype() if you need only true/false.)

Thanks very much @kbarni

I tried to use cv2.merge to check whether I get the same image but I’m getting this image ?

  new_img[:,:,0] = np.all(mask==benign,axis=2).astype(np.uint8)
  new_img[:,:,1] = np.all(mask==blue,axis=2).astype(np.uint8)
  new_img[:,:,2] = np.all(mask==yel,axis=2).astype(np.uint8)
  new_img[:,:,3] = np.all(mask==red,axis=2).astype(np.uint8)
  new_img[:,:,4] = np.all(mask==white,axis=2).astype(np.uint8)


test_img=cv2.merge((new_img[:,:,3],new_img[:,:,4],new_img[:,:,1]))

plt.imshow(test_img)

:Capture

Yes. You have the red mask (3) as the red channel, the white mask (4) as the green channel and the blue mask (1) as the blue channel. This is the expected behaviour.

So, there is no way to re-create the original image from the related channels ?

The original image is a combination of masks of different colors. It makes sense to decompose it to different masks, but why recreate the exact original image?

Anyway, if you really need it, it should be something like (not tested):

test_img=np.where(new_img[:,:,3],[255,0,0],[0,0,0])
          +np.where(new_img[:,:,4],[255,255,255],[0,0,0])
          +np.where(new_img[:,:,3],[0,255,0],[0,0,0])

This method would set the pixels defined by the third (white) mask to white.