简体   繁体   中英

Convert RGB pixel values in a range to consecutive numbers

Guys I'm new to python and I'm stuck on this. Would really appreciate it if you could help me out.

I've got an image that has a number of colours in each pixel. They all denote a number.

在此处输入图片说明

The image was constructed using this range from 0 to 15625 pixels. Each of the pixels in the range from 0 to 15625 has a different colour and the above image was constructed using that.

image range (it's massive so you might need to download it to see the image)

What I'm trying to do is convert the RGB values from the range such as the first pixel value (5,5,5) to 1 and the next pixel value in the range to 2 and so on. Therefore, each pixel in the image above could correspond to a value.

It's similar to this question but I don't think it does what I want to do. How to Convert all pixel values of an image to a certain range -python

This is the code I used to create the range

#!/usr/local/bin/python3
from PIL import Image
import numpy as np

# Create array to hold output image
result=np.zeros([1,25*25*25,3],dtype=np.uint8)

#change the values above i.e. 51*51*51 done by (upperbound-lowerbound)/step i.e (255-0)/5
j=0
for r in range(5,255,10):
    for g in range(5,255,10):
        for b in range(5,255,10):
            result[0,j]= (r,g,b)
            j+=1

# Convert output array to image and save
im=Image.fromarray(result)
im.save("perfect1.png")

This is the code to find the RGB values of each pixel in the range

from PIL import Image

i = Image.open('perfect1.png')
pixels = i.load() # this is not a list, nor is it list()'able
width, height = i.size

all_pixels = []
for x in range(width):
    for y in range(height):
        cpixel = pixels[x, y]
        all_pixels.append(cpixel)

print all_pixels

This is the code for creating a sub array with no extra pixel values as each "pixel" value in the image has a number of pixels enclosed. a = array of the image values

rows_mask = np.insert(np.diff(a[:, 0]).astype(np.bool), 0, True)
columns_mask = np.insert(np.diff(a[0]).astype(np.bool), 0, True)
b = a[np.ix_(rows_mask, columns_mask)]

Here's some idea.

Let's load your images

import numpy as np
from scipy.misc import imread

img = imread("img.png")[..., :3]   # drop alpha channel
lut = imread("lut.png").squeeze()  # squeeze 1D first axis

print(img.shape)
print(lut.shape)

Which outputs

(589, 612, 3)
(15625, 3)

Now let's say we want to look up the first pixel in the image

print(img[0, 0])
[245 245  95]

You can find all pixels in the look up table with the same value ( axis=1 to compare row by row)

np.all(img[0, 0] == lut, axis=1)

Which gives you a mask for all the pixels which is True for matches and False otherwise.

Now you can convert that to a list of indices (which in your case we can assume will have length 1 ) with np.where

idx = np.where(np.all(img[0, 0] == lut, axis=1))

And, assuming each pixel, has a unique mapping you will get

(array([15609]),)

Now this method is really slow and inefficient, you'll have to repeat it for each pixel of the image. There's probably some way to speed it up but at the moment I'm not seeing it, let's see if anyone else has some better input.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM