1

I am trying to make a little script to switch the rgb values of an image. The code I have works to alter the image, but the list of images is out of order when compared to the list of permutations. I have been unable to figure out why the images at indices 3 and 4 are switched in order.

from skimage import io
import numpy as np
import itertools

def create_permutations_auto(image):
    im_col = np.split(image, 3, axis = -1)
    color_keys = ["red", "green", "blue"]
    colors = dict(zip(color_keys, im_col))
    cp = list(itertools.permutations(color_keys))
    im_list = []
    for perm in cp:
        color_data = [colors.get(k) for k in perm]
        image = np.squeeze(np.stack(color_data, axis = -1))
        im_list.append(image)
    return cp, im_list

orig = io.imread(filename)
text, image_perms = create_permutations_auto(orig)

for i in range(len(image_perms)):
    print text[i]
    io.imshow(image_perms[i])
    io.imsave(filepath + "{}_{}_{}.png".format(text[i][0], text[i][1], text[i][2]), image_perms[i])
    io.show()

I would expect this code to output the original image with the green values replacing the red, the blue values replacing the green and the red values replacing the blue for the fourth image created. However, what I get is blue → red, red → green, and green → blue. The fifth image created seems like it should be the fourth.

Third Image (should be green, blue, red):

Third Image (should be green, blue, red)

Fourth Image(should be blue, red, green):

Fourth Image(should be blue, red, green)

To see if it was the something to do with the order of the dictionary, I tried to do the permutations manually. Using the following:

def create_permutations(image):
    red, green, blue = np.split(image, 3, axis = -1)
    perms = []
    perms.append(np.squeeze(np.stack((red, blue, green), axis = -1)))
    perms.append(np.squeeze(np.stack((green, red, blue), axis = -1)))
    perms.append(np.squeeze(np.stack((green, blue, red), axis = -1)))
    perms.append(np.squeeze(np.stack((blue, green, red), axis = -1)))
    perms.append(np.squeeze(np.stack((blue, red, green), axis = -1)))
    return perms

This code also seems to switch the placements of the two same permutations although it is the images at index 2 and 4. For this simple example, I can switch them around but it seems like I am missing something fundamental here. I am using a Python(x,y) distribution with Python 2.7.10 and numpy 1.12.1 on a machine running windows 10.

Tonechas
  • 13,398
  • 16
  • 46
  • 80
Vivixx
  • 13
  • 2

1 Answers1

1

The effect of spectral permutation is different from that of spatial permutation. When you split the original image into its chromatic bands, referred to as red, green, and blue, and then you rearrange them as blue, red, and green, the order of the colors from left to right in the resulting image is green-blue-red (spectral permutation) rather than blue-red-green (spatial permutation).

The figure below is intended to schematically explain such a counter-intuitive result. For the sake of clarity let us denote the red, green, and blue chromatic channels with indices 0, 1, and 2, respectively. It clearly emerges from the figure that the intensities of the pixels in the leftmost region of the image are transformed through permutattion from [255, 0, 0] to [0, 255, 0], Indeed, in the leftmost region of the permuted image pixels' intesities are 0 for channel 0 (red component), 255 for channel 1 (green component), and 0 for channel 2 (blue component). That's the reason why the color of the leftmost region of the image changes from red to green. Similar arguments apply to the central and rightmost regions.

blue-red-green

Bonus

You could simplify your function like this:

def create_permutations_auto(img):
    colors = {0: 'red', 1: 'green', 2: 'blue'}
    index_perm = list(itertools.permutations(colors.keys()))
    cp = [tuple(colors[i] for i in perm) for perm in index_perm] 
    im_list = [np.dstack([img[:, :, i] for i in perm]) for perm in index_perm]
    return cp, im_list
Tonechas
  • 13,398
  • 16
  • 46
  • 80