0

My task was to convert the RGB image into LuvImage. Perform linear stretching in this domain. And than convert it back in the RGB domain.

Original Image:

[[ 0 0 0]

[255 0 0]

[100 100 100]

[ 0 100 100]]

Luv image after linear stretching in Luv Domain

[[0 , 0, 0],

[100 , 175, 37.7],

[79.64, 0, 0],

[71.2 ,-29.29,-6.339]]

Now, I am converting it into XYZ image. The answer is,

[[0,0, 0],

[1.5, 1, 0.53],

[0.533, 0.56, 0.61],

[0.344, 0.425, 0.523]]

Now, after that I am converting it into linear sRGB image by multiplying image with matrix:

[[3.240479, -1.53715, -0.498535],

[-0.969256, 1.875991, 0.041556],

[0.055648, -0.204043, 1.057311]]

The answer for this conversion - linear sRGB image,

[[0. 0. 0. ],

[3.07132001 0.44046801 0.44082034],

[0.55904669 0.55972465 0.55993322],

[0.20106868 0.4850426 0.48520307]]

The problem here is that for the 2nd pixel sRGB values are not in the range of [0,1]. For all other pixels I am getting the correct value.

def XYZToLinearRGB(self, XYZImage):
    '''
    to find linearsRGBImage, we multiply XYZImage with static array
    [[3.240479, -1.53715, -0.498535],
     [-0.969256, 1.875991, 0.041556],
     [0.055648, -0.204043, 1.057311]]

    '''
    rows, cols, bands = XYZImage.shape # bands == 3

    linearsRGBImage =  np.zeros([rows, cols, bands], dtype=float)
    multiplierMatrix = np.array([[3.240479, -1.53715, -0.498535],
                                 [-0.969256, 1.875991, 0.041556],
                                 [0.055648, -0.204043, 1.057311]])

    for i in range(0, rows):
        for j in range(0, cols):
            X,Y,Z = XYZImage[i,j]
            linearsRGBImage[i,j] = np.matmul(multiplierMatrix, np.array([X,Y,Z]))
        #for j -ends
    #for i -ends

    return linearsRGBImage 

The code for this conversion is as per above. Can someone point out what I am doing wrong for 2nd pixel, and how to fix it?

nidhi vaishnav
  • 158
  • 1
  • 1
  • 9
  • Are you certain that the mapping will always be within the contained space? Some times color spaces are capable of expressing colors that other color spaces can not. – Stephen Rauch Feb 26 '18 at 01:30
  • Yeah, For XYZ range is not defined. But for linear sRGB, it should be within [0,1]. and For Luv, L should be within range [0,100]. – nidhi vaishnav Feb 26 '18 at 01:37

1 Answers1

0

Well, one simple solution I found after research is just clip the values. So, if the value is out of the range, say if r<0 than we will assign r as 0. Same for the larger values. If r>1 (in my case 3.07) than we will assign r as 1.

So the latest version of my code:

def XYZToLinearRGB(self, XYZImage):
    '''
    to find linearsRGBImage, we multiply XYZImage with static array
    [[3.240479, -1.53715, -0.498535],
     [-0.969256, 1.875991, 0.041556],
     [0.055648, -0.204043, 1.057311]]

    '''
    rows, cols, bands = XYZImage.shape # bands == 3

    linearsRGBImage =  np.zeros([rows, cols, bands], dtype=float)
    multiplierMatrix = np.array([[3.240479, -1.53715, -0.498535],
                                 [-0.969256, 1.875991, 0.041556],
                                 [0.055648, -0.204043, 1.057311]])

    for i in range(0, rows):
        for j in range(0, cols):
            X,Y,Z = XYZImage[i,j]
            rgbList = np.matmul(multiplierMatrix, np.array([X,Y,Z]))
            for index, val in enumerate(rgbList):
                if val<0:
                    rgbList[index]=0
                #if val -ends
                if val>1:
                    rgbList[index]=1
                #if val -ends
            #for index, val -ends
            linearsRGBImage[i,j]=rgbList
        #for j -ends
    #for i -ends

    return linearsRGBImage 

Though if anyone have better suggestion, it is most welcomed.

nidhi vaishnav
  • 158
  • 1
  • 1
  • 9