Home > OS >  Convert RGB to class / single integer value
Convert RGB to class / single integer value

Time:08-09

I have a numpy array from a rgb image (64,64,3) and I need to convert each existing rgb combination to one class, represented by an integer value. So that in the end I have an array (64,64) which contains integer values (0-N). These values represent specific rgb combination from the picture. Of course every rgb combination just gets one value. In short: Every color is one class, and every pixel has one fitting class-value (0-N) :)

Obviously its not a big problem, I could just go through each pixel, check the rgb values and if they are not in an "already discovered RGB" tempList, I add these values and give those rgb values an integer value representing the class, otherwise I search in the tempList for the rgb values and give the integer value I wrote down in the List - or something like that.

But to be honest, I need to do this for a lot of images and I try to get better with python. So I want to know if someone has a more efficent way to do this? I scrolled through the libaries and boards and couldn't find a good approach.

CodePudding user response:

You can convert three 8 bit integers into a 32bit integer and easily recover the three integer back. The idea is to use bitwise operations, this way each 8 bit represents one of the rgb colors. This way you already know the N = 16777215 (including zero) = 256**3.

The following code can do this:

def rgbtoint32(rgb):
    color = 0
    for c in rgb[::-1]:
        color = (color<<8)   c
        # Do not forget parenthesis.
        # color<< 8   c is equivalent of color << (8 c)
    return color

def int32torgb(color):
    rgb = []
    for i in range(3):
        rgb.append(color&0xff)
        color = color >> 8
    return rgb

rgb = [32,253,200]
color = rgbtoint32(rgb)
rgb_c = int32torgb(color)

print(rgb)
print(color)
print(rgb_c)

This gives:

[32, 253, 200]
13172000
[32, 253, 200]

Update: Using "view" from numpy, as denoted below by "Mad Physicist ", one can efficiently do the above process as

rgb = np.array([[[32,253,200], [210,25,42]]],dtype = np.uint8)
size_d = list(rgb.shape)
size_d[2] = -1

# Converting to 2D int32 array
colorint32 = np.dstack((rgb,np.zeros(rgb.shape[:2], 'uint8'))).view('uint32').squeeze(-1)

# Converting back from the int32 array to RGB space
rgb_c = colorint32.view('uint8').reshape(size_d)[:,:,:3]

# Print results
print(rgb)
print(colorint32)
print(rgb_c)

Which gives

[[[ 32 253 200]
  [210  25  42]]]
[[13172000  2759122]]
[[[ 32 253 200]
  [210  25  42]]]

CodePudding user response:

If you have a MxNx3 numpy array of type uint8, you can add an empty alpha channel and view it as a unit32:

np.dstack((img, np.zeros(img.shape[:2], 'uint8'))).view('uint32').squeeze(-1)
  • Related