eric lardon
eric lardon

Reputation: 359

Updating RGB image values given a list of indexes

l have an image of (240,320,3)

l would like to set some values to [255,0,0].

l give the indexes as follow:

indexes
[array([0, 0]),
 array([0, 1]),
 array([0, 2]),
 array([0, 3]),
 array([0, 4]),
 array([0, 5]),
 array([0, 6]),
 array([0, 7]),
 array([0, 8]),
 array([0, 9]),
 array([ 0, 10]),
 array([ 0, 11]),
 array([ 0, 12]),
 array([ 0, 13]),
 array([ 0, 14]),
 array([ 0, 15]),
 array([ 0, 16]),
 array([ 0, 17]),
 array([ 0, 18]),
 array([ 0, 19]),
 array([ 0, 20]),
 array([ 0, 21]),
 array([ 0, 22]),
 array([ 0, 23]),
 array([ 0, 24]),
 array([ 0, 25]),
 array([ 0, 26]),
 array([ 0, 27]),
 array([ 0, 28]),
 array([ 0, 29]),
 array([ 0, 30]),
 array([ 0, 31]),
 array([ 0, 32]),
 array([ 0, 33]),
 array([ 0, 34]),
 array([ 0, 35]),
 array([ 0, 36]),
 array([ 0, 37]),
 array([1, 0]),
 array([1, 1]),
 array([1, 2]),
 array([1, 3]),
 array([1, 4]),
 array([1, 5]),
 array([1, 6]),
 array([1, 7]),
 array([1, 8]),
 array([1, 9]),
 array([ 1, 10]),
 array([ 1, 11]),
 array([ 1, 12]),
 array([ 1, 13]),
 array([ 1, 14]),
 array([ 1, 15]),
 array([ 1, 16]),
 array([ 1, 17]),
 array([ 1, 18]),
 array([ 1, 19]),
 array([ 1, 20]),
 array([ 1, 21]),
 array([ 1, 22]),
 array([ 1, 23]),
 array([ 1, 24]),
 array([ 1, 25]),
 array([ 1, 26]),
 array([ 1, 27]),
 array([ 1, 28]),
 array([13, 34]),
 array([13, 35]),
 array([13, 36]),
 array([13, 37]),
 array([14,  0]),
 array([14,  1]),
 array([14,  2]),
 array([14,  3]),
 array([14,  4]),
 array([14,  5]),
 array([14,  6]),
 array([14,  7]),
 array([14,  8]),
 array([14,  9]),
 array([14, 10]),
 array([14, 11]),
 array([14, 12]),
 array([14, 13]),
 array([14, 14]),
 array([14, 15]),
 array([14, 16]),
 array([14, 17]),
 array([14, 18]),
 array([14, 19]),
 array([14, 20]),
 array([14, 21]),
 array([14, 22]),
 array([14, 23]),
 array([14, 24]),
 array([14, 25]),
 array([14, 26]),
 array([14, 27]),
 array([14, 28]),
 array([14, 29]),
 array([14, 30]),
 array([14, 31]),
 array([14, 32]),
 array([14, 33]),
 array([14, 34]),
 array([14, 35]),
 array([14, 36]),
 array([14, 37]),
 array([15,  0]),
 array([15,  1]),
 array([15,  2]),
 array([15,  3]),
 array([15,  4]),
 array([15,  5]),
 array([16, 13]),
 array([16, 14]),
 array([16, 15]),
 array([16, 16]),
 array([16, 17]),
 array([16, 18]),
 array([16, 19]),
 array([17, 24]),
 array([17, 25]),
 array([17, 26]),
 array([17, 27]),
 array([17, 28]),
 array([17, 29]),
 array([17, 30]),
 array([17, 31]),
 array([17, 32]),
 array([18,  0]),
 array([18,  1]),
 array([22, 18]),
 array([22, 19]),
 array([22, 20]),
 array([22, 21]),
 array([22, 22]),
 array([22, 23]),
 array([22, 24]),
 array([22, 25]),
 array([22, 26]),
 array([22, 27]),
 array([22, 28]),
 array([22, 29]),
 array([22, 30]),
 array([22, 31]),
 array([22, 32]),
 array([22, 33]),
 array([22, 34]),
 array([22, 35]),
 array([22, 36]),
 array([22, 37]),
 array([22, 38]),
 array([22, 39]),
 array([22, 40]),
 array([22, 41]),
 array([22, 42]),
 array([22, 43]),
 array([22, 44]),
 array([22, 45]),
 array([22, 46]),
 array([26,  1]),
 ...]

Now l load the image

from PIL import Image
img=Image.open(image)
img=np.array(img)

Given the list of indexes, l would like to set img[indexes]=[255,0,0]

What is wrong with img[indexes]=[255,0,0] ?

It doesn't seem to do the job :

img[indexes[0]] where indexes[0]=[0,0]

returns a an array of arrays, however l'm supposed to get the RGB vector at index (0,0).

Than l tried img[[0,0]] l got the same result.

It means that img[[0,0]]==img[indexes[0]] returns an array of arrays rather than the RGB vector at the index (0,0)

However, img[indexes[0,0],indexes[0,1]] returns the correct RGB vector.

My question

How can l pass a list of indexes to my image to update the values at the given indexes as follow;

img[indexes]=[255,0,0]

Thank you

EDIT 1 img[index[0]] returns

array([[[0, 0, 0],
        [0, 0, 0],
        [0, 0, 0],
        ..., 
        [0, 0, 0],
        [0, 0, 0],
        [0, 0, 0]],

       [[0, 0, 0],
        [0, 0, 0],
        [0, 0, 0],
        ..., 
        [0, 0, 0],
        [0, 0, 0],
        [0, 0, 0]]], dtype=uint8)

where l'm supposed to get an RGB vector [223,15,78] corresponding to index(0,0)

and img[indexes] retruns

array([[[[  0,   0,   0],
         [  0,   0,   0],
         [  0,   0,   0],
         ..., 
         [  0,   0,   0],
         [  0,   0,   0],
         [  0,   0,   0]],

        [[  0,   0,   0],
         [  0,   0,   0],
         [  0,   0,   0],
         ..., 
         [  0,   0,   0],
         [  0,   0,   0],
         [  0,   0,   0]]],


       [[[  0,   0,   0],
         [  0,   0,   0],
         [  0,   0,   0],
         ..., 
         [  0,   0,   0],
         [  0,   0,   0],
         [  0,   0,   0]],

        [[  0,   0,   0],
         [  0,   0,   0],
         [  0,   0,   0],
         ..., 
         [  0,   0,   0],
         [  0,   0,   0],
         [  0,   0,   0]]],


       [[[  0,   0,   0],
         [  0,   0,   0],
         [  0,   0,   0],
         ..., 
         [  0,   0,   0],
         [  0,   0,   0],
         [  0,   0,   0]],

        [[  0,   0,   0],
         [  0,   0,   0],
         [  0,   0,   0],
         ..., 
         [  0,   0,   0],
         [  0,   0,   0],
         [  0,   0,   0]]],


       ..., 
       [[[  0,   0,   2],
         [  0,   0,   2],
         [  0,   0,   2],
         ..., 
         [  0,   2,   0],
         [  0,   2,   0],
         [  0,   2,   0]],

        [[108, 106,  93],
         [108, 106,  93],
         [109, 105,  93],
         ..., 
         [170, 165, 143],
         [177, 175, 150],
         [173, 171, 146]]],


       [[[  0,   0,   2],
         [  0,   0,   2],
         [  0,   0,   2],
         ..., 
         [  0,   2,   0],
         [  0,   2,   0],
         [  0,   2,   0]],

        [[129, 127, 114],
         [129, 127, 114],
         [130, 126, 114],
         ..., 
         [155, 150, 128],
         [164, 164, 138],
         [172, 172, 146]]],


       [[[  0,   0,   2],
         [  0,   0,   2],
         [  0,   0,   2],
         ..., 
         [  0,   2,   0],
         [  0,   2,   0],
         [  0,   2,   0]],

        [[150, 133, 126],
         [149, 132, 125],
         [147, 130, 123],
         ..., 
         [162, 135, 124],
         [179, 152, 143],
         [184, 157, 148]]]], dtype=uint8)

image sample :

img[140:200]
array([[[159, 146, 114],
        [115, 100,  71],
        [ 90,  73,  45],
        ..., 
        [245, 187, 183],
        [252, 197, 194],
        [253, 198, 195]],

       [[206, 193, 159],
        [164, 149, 118],
        [119, 102,  72],
        ..., 
        [243, 188, 185],
        [246, 192, 190],
        [251, 197, 195]],

       [[195, 182, 148],
        [182, 167, 134],
        [150, 134, 101],
        ..., 
        [241, 185, 184],
        [245, 191, 189],
        [251, 200, 197]],

       ..., 
       [[251, 234, 244],
        [251, 234, 244],
        [251, 234, 244],
        ..., 
        [104,  77,  70],
        [102,  75,  68],
        [102,  75,  68]],

       [[251, 234, 244],
        [251, 234, 244],
        [251, 234, 244],
        ..., 
        [ 94,  69,  62],
        [ 91,  66,  59],
        [ 89,  64,  57]],

       [[251, 234, 244],
        [251, 234, 244],
        [251, 234, 244],
        ..., 
        [ 85,  62,  56],
        [ 81,  58,  52],
        [ 78,  58,  51]]], dtype=uint8)

Upvotes: 1

Views: 239

Answers (1)

NickBraunagel
NickBraunagel

Reputation: 1599

I believe the problem you're running into is advanced indexing vs simple indexing, as described within the numpy documentation.

given a dummy img array of shape (240,320,3), we have something like this:

img = np.random.randint(1,255, (240,320,3))
print img

array([[[ 25, 160, 160],
        [238, 222, 252],
        [  7,  73,  81],
        ...,
        [144, 198,  83],
        [186, 204, 150],
        [249, 234, 105]],

       [[ 52, 242, 214],
        [230, 139, 165],
        [ 95,  69, 168],
        ...,
        [ 40, 226, 111],
        [190, 114, 165],
        [235, 189, 108]],

       [[146, 245,  22],
        [ 88, 156,  27],
        [120, 112,  13],
        ...,
        [220,  31, 119],
        [ 67, 117,  65],
        [108, 145, 196]],
     ...,

If we want to access the first element in the first nested array ([25, 160, 160]), we would call it with simple indexing:

print img[0,0]   # array([ 25, 160, 160])

However, when you pass in an index array, numpy interprets the indexing as advanced: img[[0,0]] return img[0] twice!; img[[0,0,0]] returns img[0] three times! This is why you're seeing oddly shaped arrays when you call img[indexes].

To achieve the desired result of updating img values to [255,0,0] as indicated in your indexes list, you need to first convert each index within indexes to a tuple; this will signal to numpy to interpret your arrays as simple indexing:

an_index = np.array([0,0])
( img[0,0] == img[tuple(an_index)] ).all()  # True

To convert your indexes to tuples, you can use map:

indexes = np.random.randint(0,10,(100,2))
index_of_tuples = map(tuple, indexes)
img[index_of_tuples] = [255,0,0]

Now, value of img will be updated to [255,0,0], as indicated within your original indexes.

Upvotes: 1

Related Questions