Here is an example of manipulating an Array of pixels. I chose the x-rite ColorChecker as a model so there would be published results to check my work. A number of details about color spaces have become clear through this exercise. The color adaptation process was modeled by converting betweenXYZ and LMS. Different black points may be selected depending on how close to zero illuminance one would accept as a good model. 

I look forward to extending this work to verify and improve the color calibration of my photography. Also some experimentation with demosaicing should be possible.

Initialization

 

restart

with(LinearAlgebra):

unprotect(gamma):``

NULL

x-rite Colorchecker xyY Matrix

  CCxyY_D50 := Matrix(4, 6, {(1, 1) = Vector(3, {(1) = .4316, (2) = .3777, (3) = .1008}), (1, 2) = Vector(3, {(1) = .4197, (2) = .3744, (3) = .3495}), (1, 3) = Vector(3, {(1) = .2760, (2) = .3016, (3) = .1836}), (1, 4) = Vector(3, {(1) = .3703, (2) = .4499, (3) = .1325}), (1, 5) = Vector(3, {(1) = .2999, (2) = .2856, (3) = .2304}), (1, 6) = Vector(3, {(1) = .2848, (2) = .3911, (3) = .4178}), (2, 1) = Vector(3, {(1) = .5295, (2) = .4055, (3) = .3118}), (2, 2) = Vector(3, {(1) = .2305, (2) = .2106, (3) = .1126}), (2, 3) = Vector(3, {(1) = .5012, (2) = .3273, (3) = .1938}), (2, 4) = Vector(3, {(1) = .3319, (2) = .2482, (3) = 0.637e-1}), (2, 5) = Vector(3, {(1) = .3984, (2) = .5008, (3) = .4446}), (2, 6) = Vector(3, {(1) = .4957, (2) = .4427, (3) = .4357}), (3, 1) = Vector(3, {(1) = .2018, (2) = .1692, (3) = 0.575e-1}), (3, 2) = Vector(3, {(1) = .3253, (2) = .5032, (3) = .2318}), (3, 3) = Vector(3, {(1) = .5686, (2) = .3303, (3) = .1257}), (3, 4) = Vector(3, {(1) = .4697, (2) = .4734, (3) = .5981}), (3, 5) = Vector(3, {(1) = .4159, (2) = .2688, (3) = .2009}), (3, 6) = Vector(3, {(1) = .2131, (2) = .3023, (3) = .1930}), (4, 1) = Vector(3, {(1) = .3469, (2) = .3608, (3) = .9131}), (4, 2) = Vector(3, {(1) = .3440, (2) = .3584, (3) = .5894}), (4, 3) = Vector(3, {(1) = .3432, (2) = .3581, (3) = .3632}), (4, 4) = Vector(3, {(1) = .3446, (2) = .3579, (3) = .1915}), (4, 5) = Vector(3, {(1) = .3401, (2) = .3548, (3) = 0.883e-1}), (4, 6) = Vector(3, {(1) = .3406, (2) = .3537, (3) = 0.311e-1})})

NULL

NULL

M := RowDimension(CCxyY_D50) = 4NULL

N := ColumnDimension(CCxyY_D50) = 6

NULL

Convert xyY to XYZ

   

NULL

CCXYZ_D50 := C_xyY_to_XYZ(CCxyY_D50):

CCXYZ_D50 = Matrix(4, 6, {(1, 1) = Vector(3, {(1) = .1152, (2) = .1008, (3) = 0.509e-1}), (1, 2) = Vector(3, {(1) = .3918, (2) = .3495, (3) = .1922}), (1, 3) = Vector(3, {(1) = .1680, (2) = .1836, (3) = .2571}), (1, 4) = Vector(3, {(1) = .1091, (2) = .1325, (3) = 0.529e-1}), (1, 5) = Vector(3, {(1) = .2419, (2) = .2304, (3) = .3344}), (1, 6) = Vector(3, {(1) = .3042, (2) = .4178, (3) = .3462}), (2, 1) = Vector(3, {(1) = .4071, (2) = .3118, (3) = 0.500e-1}), (2, 2) = Vector(3, {(1) = .1232, (2) = .1126, (3) = .2988}), (2, 3) = Vector(3, {(1) = .2968, (2) = .1938, (3) = .1015}), (2, 4) = Vector(3, {(1) = 0.852e-1, (2) = 0.637e-1, (3) = .1078}), (2, 5) = Vector(3, {(1) = .3537, (2) = .4446, (3) = 0.895e-1}), (2, 6) = Vector(3, {(1) = .4879, (2) = .4357, (3) = 0.606e-1}), (3, 1) = Vector(3, {(1) = 0.686e-1, (2) = 0.575e-1, (3) = .2138}), (3, 2) = Vector(3, {(1) = .1498, (2) = .2318, (3) = 0.790e-1}), (3, 3) = Vector(3, {(1) = .2164, (2) = .1257, (3) = 0.385e-1}), (3, 4) = Vector(3, {(1) = .5934, (2) = .5981, (3) = 0.719e-1}), (3, 5) = Vector(3, {(1) = .3108, (2) = .2009, (3) = .2356}), (3, 6) = Vector(3, {(1) = .1360, (2) = .1930, (3) = .3094}), (4, 1) = Vector(3, {(1) = .8779, (2) = .9131, (3) = .7397}), (4, 2) = Vector(3, {(1) = .5657, (2) = .5894, (3) = .4894}), (4, 3) = Vector(3, {(1) = .3481, (2) = .3632, (3) = .3029}), (4, 4) = Vector(3, {(1) = .1844, (2) = .1915, (3) = .1592}), (4, 5) = Vector(3, {(1) = 0.846e-1, (2) = 0.883e-1, (3) = 0.759e-1}), (4, 6) = Vector(3, {(1) = 0.299e-1, (2) = 0.311e-1, (3) = 0.269e-1})})NULL

XYZ D50 to XYZ D65

   

NULL

CCXYZ_D65 := XYZ_D50_to_D65(CCXYZ_D50):

CCXYZ_D65 = Matrix(4, 6, {(1, 1) = Vector(3, {(1) = .1110, (2) = 0.996e-1, (3) = 0.670e-1}), (1, 2) = Vector(3, {(1) = .3785, (2) = .3459, (3) = .2533}), (1, 3) = Vector(3, {(1) = .1726, (2) = .1861, (3) = .3403}), (1, 4) = Vector(3, {(1) = .1045, (2) = .1318, (3) = 0.690e-1}), (1, 5) = Vector(3, {(1) = .2470, (2) = .2329, (3) = .4430}), (1, 6) = Vector(3, {(1) = .3030, (2) = .4206, (3) = .4556}), (2, 1) = Vector(3, {(1) = .3850, (2) = .3044, (3) = 0.651e-1}), (2, 2) = Vector(3, {(1) = .1340, (2) = .1165, (3) = .3966}), (2, 3) = Vector(3, {(1) = .2855, (2) = .1895, (3) = .1347}), (2, 4) = Vector(3, {(1) = 0.867e-1, (2) = 0.642e-1, (3) = .1431}), (2, 5) = Vector(3, {(1) = .3334, (2) = .4409, (3) = .1142}), (2, 6) = Vector(3, {(1) = .4600, (2) = .4275, (3) = 0.777e-1}), (3, 1) = Vector(3, {(1) = 0.777e-1, (2) = 0.606e-1, (3) = .2839}), (3, 2) = Vector(3, {(1) = .1428, (2) = .2315, (3) = .1022}), (3, 3) = Vector(3, {(1) = .2063, (2) = .1216, (3) = 0.512e-1}), (3, 4) = Vector(3, {(1) = .5578, (2) = .5888, (3) = 0.906e-1}), (3, 5) = Vector(3, {(1) = .3073, (2) = .1990, (3) = .3131}), (3, 6) = Vector(3, {(1) = .1451, (2) = .1976, (3) = .4092}), (4, 1) = Vector(3, {(1) = .8646, (2) = .9129, (3) = .9759}), (4, 2) = Vector(3, {(1) = .5579, (2) = .5895, (3) = .6458}), (4, 3) = Vector(3, {(1) = .3434, (2) = .3633, (3) = .3997}), (4, 4) = Vector(3, {(1) = .1818, (2) = .1915, (3) = .2100}), (4, 5) = Vector(3, {(1) = 0.836e-1, (2) = 0.884e-1, (3) = .1002}), (4, 6) = Vector(3, {(1) = 0.296e-1, (2) = 0.311e-1, (3) = 0.355e-1})})

NULL

NULLConvert XYZ to Lab (D50 or D65 White Point)

 

NULLNULL

Reference White Point for D50

NULL

X_D50wht := XYZ_D50wht[1] = .96422NULL

Y_D50wht := XYZ_D50wht[2] = 1NULL

Z_D50wht := XYZ_D50wht[3] = .82521

NULL

Lab Conversion Constants;

`ε` := 216/24389:

kappa := 24389/27:

NULL

fx_D50 := proc (XYZ) options operator, arrow; piecewise(`&epsilon;` < XYZ[1]/X_D50wht, (XYZ[1]/X_D50wht)^(1/3), XYZ[1]/X_D50wht <= `&epsilon;`, (1/116)*kappa*XYZ[1]/X_D50wht+4/29) end proc
                

NULLNULL

NULL

 
fy_D50 := proc (XYZ) options operator, arrow; piecewise(`&epsilon;` < XYZ[2]/Y_D50wht, (XYZ[2]/Y_D50wht)^(1/3), XYZ[2]/Y_D50wht <= `&epsilon;`, (1/116)*kappa*XYZ[2]/Y_D50wht+4/29) end proc
NULLNULL

NULLNULL

fz_D50 := proc (XYZ) options operator, arrow; piecewise(`&epsilon;` < XYZ[3]/Z_D50wht, (XYZ[3]/Z_D50wht)^(1/3), XYZ[3]/Z_D50wht <= `&epsilon;`, (1/116)*kappa*XYZ[3]/Z_D50wht+4/29) end proc
NULL

XYZ_to_Lab_D50 := proc (XYZ) options operator, arrow; `<,>`(116*fy_D50(XYZ)-16, 500*fx_D50(XYZ)-500*fy_D50(XYZ), 200*fy_D50(XYZ)-200*fz_D50(XYZ)) end proc:

NULL

Reference White Point for D65

NULL

X_D65wht := XYZ_D65wht[1] = .95047NULL

Y_D65wht := XYZ_D65wht[2] = 1NULL

Z_D65wht := XYZ_D65wht[3] = 1.08883 

NULL

NULL

NULL

NULL

NULL

NULL

NULL

fx_D65 := proc (XYZ) options operator, arrow; piecewise(`&epsilon;` < XYZ[1]/X_D65wht, (XYZ[1]/X_D65wht)^(1/3), XYZ[1]/X_D65wht <= `&epsilon;`, (1/116)*kappa*XYZ[1]/X_D65wht+4/29) end proc
                

NULLNULL

NULL

 
fy_D65 := proc (XYZ) options operator, arrow; piecewise(`&epsilon;` < XYZ[2]/Y_D65wht, (XYZ[2]/Y_D65wht)^(1/3), XYZ[2]/Y_D65wht <= `&epsilon;`, (1/116)*kappa*XYZ[2]/Y_D65wht+4/29) end proc
NULLNULL

NULLNULL

fz_D65 := proc (XYZ) options operator, arrow; piecewise(`&epsilon;` < XYZ[3]/Z_D65wht, (XYZ[3]/Z_D65wht)^(1/3), XYZ[3]/Z_D65wht <= `&epsilon;`, (1/116)*kappa*XYZ[3]/Z_D65wht+4/29) end proc
NULL

XYZ_to_Lab_D65 := proc (XYZ) options operator, arrow; `<,>`(116*fy_D65(XYZ)-16, 500*fx_D65(XYZ)-500*fy_D65(XYZ), 200*fy_D65(XYZ)-200*fz_D65(XYZ)) end proc:

NULL

NULL

 

NULL

C_XYZ_to_Lab := proc (XYZ, L) options operator, arrow; piecewise(evalb(L = D50), Array([`$`('[`$`('XYZ_to_Lab_D50(XYZ[m, n])', n = 1 .. N)]', m = 1 .. M)]), evalb(L = D65), Array([`$`('[`$`('XYZ_to_Lab_D65(XYZ[m, n])', n = 1 .. N)]', m = 1 .. M)])) end proc
 NULL

NULL

NULLNULL

NULL

CCLab_D50 := C_XYZ_to_Lab(CCXYZ_D50, D50): NULL

CCLab_D50 = Matrix(4, 6, {(1, 1) = Vector(3, {(1) = 37.99, (2) = 13.55, (3) = 14.06}), (1, 2) = Vector(3, {(1) = 65.71, (2) = 18.14, (3) = 17.82}), (1, 3) = Vector(3, {(1) = 49.93, (2) = -4.91, (3) = -21.92}), (1, 4) = Vector(3, {(1) = 43.14, (2) = -13.10, (3) = 21.89}), (1, 5) = Vector(3, {(1) = 55.11, (2) = 8.84, (3) = -25.39}), (1, 6) = Vector(3, {(1) = 70.72, (2) = -33.39, (3) = -.21}), (2, 1) = Vector(3, {(1) = 62.66, (2) = 36.06, (3) = 57.08}), (2, 2) = Vector(3, {(1) = 40.01, (2) = 10.42, (3) = -45.98}), (2, 3) = Vector(3, {(1) = 51.13, (2) = 48.24, (3) = 16.26}), (2, 4) = Vector(3, {(1) = 30.33, (2) = 23.00, (3) = -21.59}), (2, 5) = Vector(3, {(1) = 72.53, (2) = -23.70, (3) = 57.27}), (2, 6) = Vector(3, {(1) = 71.94, (2) = 19.37, (3) = 67.86}), (3, 1) = Vector(3, {(1) = 28.77, (2) = 14.17, (3) = -50.30}), (3, 2) = Vector(3, {(1) = 55.26, (2) = -38.32, (3) = 31.36}), (3, 3) = Vector(3, {(1) = 42.11, (2) = 53.38, (3) = 28.20}), (3, 4) = Vector(3, {(1) = 81.73, (2) = 4.03, (3) = 79.85}), (3, 5) = Vector(3, {(1) = 51.94, (2) = 50.00, (3) = -14.57}), (3, 6) = Vector(3, {(1) = 51.04, (2) = -28.65, (3) = -28.63}), (4, 1) = Vector(3, {(1) = 96.54, (2) = -.46, (3) = 1.19}), (4, 2) = Vector(3, {(1) = 81.26, (2) = -.64, (3) = -.35}), (4, 3) = Vector(3, {(1) = 66.76, (2) = -.72, (3) = -.51}), (4, 4) = Vector(3, {(1) = 50.86, (2) = -.14, (3) = -.28}), (4, 5) = Vector(3, {(1) = 35.65, (2) = -.44, (3) = -1.23}), (4, 6) = Vector(3, {(1) = 20.48, (2) = -0.7e-1, (3) = -.98})})NULL

NULL

Convert XYZ to aRGB (XYZ D50 or D65 to aRGB D65)

 

XYZ Scaling for aRGB Ymax,Ymin (Ref. Adobe RGB (1998) Color Image Encoding Section 4.3.2.2 and 4.3.8)

NULL

White Point (Luminance=160Cd/m^2) D65

Black Point (Luminance=0.5557Cd/m^2) D65

White Point (Luminance=160Cd/m^2) D50

Black Point (Luminance=0.5557Cd/m^2) D50

XW_D65 := 152.07*(1/160) = .9504375000NULL

YW_D65 := 160*(1/160) = 1``

ZW_D65 := 174.25*(1/160) = 1.089062500``

NULL

xXK_D65 := .5282*(1/160) = 0.3301250000e-2``

xYK_D65 := .5557*(1/160) = 0.3473125000e-2``

xZK_D65 := .6025*(1/160) = 0.3765625000e-2``

XK_D65 := 0:

YK_D65 := 0:

ZK_D65 := 0:

``

``

XW_D50 := .9462:NULL

YW_D50 := 1.0000:

ZW_D50 := .8249:

``

NULL

xXK_D50 := 0.33488e-2:

xYK_D50 := 0.34751e-2:

xZK_D50 := 0.28650e-2:

``

XK_D50 := 0:

YK_D50 := 0:

ZK_D50 := 0:

NULL

 

NULL

XYZD65_to_aXYZ := proc (XYZ) options operator, arrow; `<,>`((XYZ[1]-XK_D65)*XW_D65/((XW_D65-XK_D65)*YW_D65), (XYZ[2]-YK_D65)/(YW_D65-YK_D65), (XYZ[3]-ZK_D65)*ZW_D65/((ZW_D65-ZK_D65)*YW_D65)) end proc:

XYZD50_to_aXYZ := proc (XYZ) options operator, arrow; `<,>`((XYZ[1]-XK_D50)*XW_D50/((XW_D50-XK_D50)*YW_D50), (XYZ[2]-YK_D50)/(YW_D50-YK_D50), (XYZ[3]-ZK_D50)*ZW_D50/((ZW_D50-ZK_D50)*YW_D50)) end proc:

 

NULL

(ref. Adobe RGB(1998) section 4.3.6.1, Bradford Matrix includes D50 to D65 adaptation)

M_XYZtoaRGB_D50 := Matrix(3, 3, {(1, 1) = 1.96253, (1, 2) = -.61068, (1, 3) = -.34137, (2, 1) = -.97876, (2, 2) = 1.91615, (2, 3) = 0.3342e-1, (3, 1) = 0.2869e-1, (3, 2) = -.14067, (3, 3) = 1.34926})

  aXYZ_to_RGB_D50 := proc (aXYZ) options operator, arrow; `<,>`(Typesetting:-delayDotProduct(M_XYZtoaRGB_D50, aXYZ)) end proc: NULL

 

(ref. Adobe RBG(1998) section 4.3.4.1, Bradford Matrix assumes XYZ is D65)

M_XYZtoaRGB_D65 := Matrix(3, 3, {(1, 1) = 2.04159, (1, 2) = -.56501, (1, 3) = -.34473, (2, 1) = -.96924, (2, 2) = 1.87597, (2, 3) = 0.4156e-1, (3, 1) = 0.1344e-1, (3, 2) = -.11836, (3, 3) = 1.01517})

  NULL

aXYZ_to_RGB_D65 := proc (aXYZ) options operator, arrow; `<,>`(Typesetting:-delayDotProduct(M_XYZtoaRGB_D65, aXYZ)) end proc:

NULL

  aRGB Expansion for 8bits

 

`&gamma;a` := 2.19921875:

RGB_to_aRGB := proc (RGB) options operator, arrow; `<,>`(round(255*Norm(RGB[1])^(1/`&gamma;a`)), round(255*Norm(RGB[2])^(1/`&gamma;a`)), round(255*Norm(RGB[3])^(1/`&gamma;a`))) end proc:
NULL

 

Combine Steps

NULL

XYZ_to_aRGB := proc (XYZ, L) options operator, arrow; piecewise(evalb(L = D50), Array([`$`('[`$`('RGB_to_aRGB(aXYZ_to_RGB_D50(XYZD50_to_aXYZ(XYZ[m, n])))', n = 1 .. N)]', m = 1 .. M)]), evalb(L = D65), Array([`$`('[`$`('RGB_to_aRGB(aXYZ_to_RGB_D65(XYZD65_to_aXYZ(XYZ[m, n])))', n = 1 .. N)]', m = 1 .. M)])) end proc

NULLNULL

NULLNULL

Note: The aRGB values published for ColorChecker assume a black point of 0cd/m^2.

````

aRGB_D50in := XYZ_to_aRGB(CCXYZ_D50, D50):

aRGB_D50in = Matrix(4, 6, {(1, 1) = Vector(3, {(1) = 107, (2) = 82, (3) = 70}), (1, 2) = Vector(3, {(1) = 184, (2) = 146, (3) = 128}), (1, 3) = Vector(3, {(1) = 101, (2) = 122, (3) = 153}), (1, 4) = Vector(3, {(1) = 95, (2) = 107, (3) = 69}), (1, 5) = Vector(3, {(1) = 128, (2) = 127, (3) = 173}), (1, 6) = Vector(3, {(1) = 129, (2) = 188, (3) = 171}), (2, 1) = Vector(3, {(1) = 201, (2) = 123, (3) = 56}), (2, 2) = Vector(3, {(1) = 77, (2) = 92, (3) = 166}), (2, 3) = Vector(3, {(1) = 174, (2) = 83, (3) = 97}), (2, 4) = Vector(3, {(1) = 86, (2) = 61, (3) = 104}), (2, 5) = Vector(3, {(1) = 167, (2) = 188, (3) = 75}), (2, 6) = Vector(3, {(1) = 213, (2) = 160, (3) = 55}), (3, 1) = Vector(3, {(1) = 49, (2) = 65, (3) = 143}), (3, 2) = Vector(3, {(1) = 99, (2) = 148, (3) = 80}), (3, 3) = Vector(3, {(1) = 155, (2) = 52, (3) = 59}), (3, 4) = Vector(3, {(1) = 227, (2) = 197, (3) = 52}), (3, 5) = Vector(3, {(1) = 169, (2) = 85, (3) = 147}), (3, 6) = Vector(3, {(1) = 61, (2) = 135, (3) = 167}), (4, 1) = Vector(3, {(1) = 245, (2) = 245, (3) = 242}), (4, 2) = Vector(3, {(1) = 200, (2) = 201, (3) = 201}), (4, 3) = Vector(3, {(1) = 160, (2) = 161, (3) = 162}), (4, 4) = Vector(3, {(1) = 120, (2) = 120, (3) = 121}), (4, 5) = Vector(3, {(1) = 84, (2) = 85, (3) = 86}), (4, 6) = Vector(3, {(1) = 52, (2) = 53, (3) = 54})})NULL

  

NULL

aRGB_D65in := XYZ_to_aRGB(CCXYZ_D65, D65):

aRGB_D65in = Matrix(4, 6, {(1, 1) = Vector(3, {(1) = 107, (2) = 82, (3) = 70}), (1, 2) = Vector(3, {(1) = 184, (2) = 146, (3) = 128}), (1, 3) = Vector(3, {(1) = 101, (2) = 122, (3) = 153}), (1, 4) = Vector(3, {(1) = 95, (2) = 107, (3) = 69}), (1, 5) = Vector(3, {(1) = 128, (2) = 127, (3) = 173}), (1, 6) = Vector(3, {(1) = 129, (2) = 188, (3) = 171}), (2, 1) = Vector(3, {(1) = 201, (2) = 123, (3) = 56}), (2, 2) = Vector(3, {(1) = 77, (2) = 92, (3) = 166}), (2, 3) = Vector(3, {(1) = 174, (2) = 83, (3) = 97}), (2, 4) = Vector(3, {(1) = 86, (2) = 61, (3) = 104}), (2, 5) = Vector(3, {(1) = 167, (2) = 188, (3) = 75}), (2, 6) = Vector(3, {(1) = 213, (2) = 160, (3) = 55}), (3, 1) = Vector(3, {(1) = 49, (2) = 65, (3) = 143}), (3, 2) = Vector(3, {(1) = 99, (2) = 148, (3) = 80}), (3, 3) = Vector(3, {(1) = 155, (2) = 52, (3) = 59}), (3, 4) = Vector(3, {(1) = 227, (2) = 197, (3) = 52}), (3, 5) = Vector(3, {(1) = 169, (2) = 85, (3) = 147}), (3, 6) = Vector(3, {(1) = 61, (2) = 135, (3) = 167}), (4, 1) = Vector(3, {(1) = 245, (2) = 245, (3) = 242}), (4, 2) = Vector(3, {(1) = 200, (2) = 201, (3) = 201}), (4, 3) = Vector(3, {(1) = 160, (2) = 161, (3) = 162}), (4, 4) = Vector(3, {(1) = 120, (2) = 120, (3) = 121}), (4, 5) = Vector(3, {(1) = 84, (2) = 85, (3) = 86}), (4, 6) = Vector(3, {(1) = 52, (2) = 53, (3) = 54})})

Convert XYZ to ProPhoto RGB (D50)

   

NULL

CC_PPhoto := XYZ_to_PPhoto(CCXYZ_D50):

NULL

CC_PPhoto = Matrix(4, 6, {(1, 1) = Vector(3, {(1) = 81, (2) = 67, (3) = 54}), (1, 2) = Vector(3, {(1) = 159, (2) = 135, (3) = 113}), (1, 3) = Vector(3, {(1) = 94, (2) = 102, (3) = 133}), (1, 4) = Vector(3, {(1) = 75, (2) = 86, (3) = 55}), (1, 5) = Vector(3, {(1) = 118, (2) = 111, (3) = 154}), (1, 6) = Vector(3, {(1) = 127, (2) = 168, (3) = 157}), (2, 1) = Vector(3, {(1) = 167, (2) = 118, (3) = 54}), (2, 2) = Vector(3, {(1) = 79, (2) = 74, (3) = 145}), (2, 3) = Vector(3, {(1) = 141, (2) = 83, (3) = 80}), (2, 4) = Vector(3, {(1) = 68, (2) = 49, (3) = 82}), (2, 5) = Vector(3, {(1) = 144, (2) = 170, (3) = 74}), (2, 6) = Vector(3, {(1) = 181, (2) = 152, (3) = 60}), (3, 1) = Vector(3, {(1) = 57, (2) = 50, (3) = 120}), (3, 2) = Vector(3, {(1) = 85, (2) = 123, (3) = 69}), (3, 3) = Vector(3, {(1) = 120, (2) = 59, (3) = 46}), (3, 4) = Vector(3, {(1) = 199, (2) = 188, (3) = 66}), (3, 5) = Vector(3, {(1) = 143, (2) = 85, (3) = 127}), (3, 6) = Vector(3, {(1) = 78, (2) = 111, (3) = 148}), (4, 1) = Vector(3, {(1) = 242, (2) = 243, (3) = 240}), (4, 2) = Vector(3, {(1) = 189, (2) = 190, (3) = 191}), (4, 3) = Vector(3, {(1) = 145, (2) = 146, (3) = 146}), (4, 4) = Vector(3, {(1) = 102, (2) = 102, (3) = 102}), (4, 5) = Vector(3, {(1) = 66, (2) = 66, (3) = 68}), (4, 6) = Vector(3, {(1) = 37, (2) = 37, (3) = 38})})NULL

Convert XYZ to sRGB (XYZ D50 or D65 to sRGB D65)

   

NULL

Note: The sRGB values published for ColorChecker assume a black point of 0cd/m^2.

``

CCsRGB_D65in := XYZ_to_sRGB(CCXYZ_D65, D65):

NULL

CCsRGB_D65in = Matrix(4, 6, {(1, 1) = Vector(3, {(1) = 115, (2) = 81, (3) = 67}), (1, 2) = Vector(3, {(1) = 199, (2) = 147, (3) = 129}), (1, 3) = Vector(3, {(1) = 91, (2) = 122, (3) = 156}), (1, 4) = Vector(3, {(1) = 90, (2) = 108, (3) = 64}), (1, 5) = Vector(3, {(1) = 130, (2) = 128, (3) = 176}), (1, 6) = Vector(3, {(1) = 92, (2) = 190, (3) = 172}), (2, 1) = Vector(3, {(1) = 224, (2) = 124, (3) = 47}), (2, 2) = Vector(3, {(1) = 68, (2) = 91, (3) = 170}), (2, 3) = Vector(3, {(1) = 198, (2) = 82, (3) = 97}), (2, 4) = Vector(3, {(1) = 94, (2) = 58, (3) = 106}), (2, 5) = Vector(3, {(1) = 159, (2) = 189, (3) = 63}), (2, 6) = Vector(3, {(1) = 230, (2) = 162, (3) = 39}), (3, 1) = Vector(3, {(1) = 35, (2) = 63, (3) = 147}), (3, 2) = Vector(3, {(1) = 67, (2) = 149, (3) = 74}), (3, 3) = Vector(3, {(1) = 180, (2) = 49, (3) = 57}), (3, 4) = Vector(3, {(1) = 238, (2) = 198, (3) = 20}), (3, 5) = Vector(3, {(1) = 193, (2) = 84, (3) = 151}), (3, 6) = Vector(3, {(1) = 54, (2) = 136, (3) = 170}), (4, 1) = Vector(3, {(1) = 245, (2) = 245, (3) = 243}), (4, 2) = Vector(3, {(1) = 200, (2) = 202, (3) = 202}), (4, 3) = Vector(3, {(1) = 161, (2) = 163, (3) = 163}), (4, 4) = Vector(3, {(1) = 121, (2) = 121, (3) = 122}), (4, 5) = Vector(3, {(1) = 82, (2) = 84, (3) = 86}), (4, 6) = Vector(3, {(1) = 49, (2) = 49, (3) = 51})})NULL

``

CCsRGB_D50in := XYZ_to_sRGB(CCXYZ_D50, D50):

``

CCsRGB_D50in = Matrix(4, 6, {(1, 1) = Vector(3, {(1) = 115, (2) = 81, (3) = 67}), (1, 2) = Vector(3, {(1) = 199, (2) = 148, (3) = 129}), (1, 3) = Vector(3, {(1) = 91, (2) = 123, (3) = 156}), (1, 4) = Vector(3, {(1) = 90, (2) = 108, (3) = 64}), (1, 5) = Vector(3, {(1) = 130, (2) = 129, (3) = 176}), (1, 6) = Vector(3, {(1) = 92, (2) = 190, (3) = 172}), (2, 1) = Vector(3, {(1) = 224, (2) = 125, (3) = 47}), (2, 2) = Vector(3, {(1) = 68, (2) = 92, (3) = 170}), (2, 3) = Vector(3, {(1) = 198, (2) = 83, (3) = 97}), (2, 4) = Vector(3, {(1) = 94, (2) = 59, (3) = 106}), (2, 5) = Vector(3, {(1) = 159, (2) = 190, (3) = 63}), (2, 6) = Vector(3, {(1) = 230, (2) = 163, (3) = 39}), (3, 1) = Vector(3, {(1) = 35, (2) = 64, (3) = 147}), (3, 2) = Vector(3, {(1) = 67, (2) = 149, (3) = 74}), (3, 3) = Vector(3, {(1) = 180, (2) = 51, (3) = 57}), (3, 4) = Vector(3, {(1) = 238, (2) = 199, (3) = 20}), (3, 5) = Vector(3, {(1) = 193, (2) = 85, (3) = 151}), (3, 6) = Vector(3, {(1) = 54, (2) = 137, (3) = 170}), (4, 1) = Vector(3, {(1) = 245, (2) = 246, (3) = 243}), (4, 2) = Vector(3, {(1) = 200, (2) = 203, (3) = 202}), (4, 3) = Vector(3, {(1) = 161, (2) = 164, (3) = 163}), (4, 4) = Vector(3, {(1) = 121, (2) = 122, (3) = 122}), (4, 5) = Vector(3, {(1) = 82, (2) = 84, (3) = 86}), (4, 6) = Vector(3, {(1) = 49, (2) = 50, (3) = 51})})``

NULL

``

NULL

NULL

``

 

 

 

 

 

 

 

 

``

 

Corrections to the original version of theis document;
• Make the scaling for a nonzero black point the same for all RGB color spaces.
• Clip negative RGB values to zero.
• Remove the redundant Array container from matrix multiplications.
Use map in place of the $ to apply a function to each element of an Array.

Pixel_Conversion_B.mw

 


Please Wait...