Page 1 of 1
deducing Photoshop's grayscale weighting algorithm
Posted: Wed Feb 17, 2016 7:00 am
by Keya
I was curious, which weighting does Photoshop use when it converts from color to grayscale!?
i was guessing probably one of the two ITU-R's (BT.601 or 709):
Code: Select all
Procedure.l RGBtoLuma601(red,green,blue) ;ITU-R BT.601, Matlab
ProcedureReturn (red * 0.299) + (green * 0.587) + (blue * 0.114)
EndProcedure
Procedure.l RGBtoLuma709(red,green,blue) ;ITU-R BT.709
ProcedureReturn (red * 0.2126) + (green * 0.7152) + (blue * 0.0722)
EndProcedure
... or their own variation?
So I checked in Photoshop and it converts to grayscale from the following:
R $FF0000 -> $81
G $00FF00 -> $DC
B $0000FF -> $46
(just create blank image filled with the color, then Image->Mode->Grayscale, and i used Eyedropper tool to then check the gray color)
But im not sure if its possible to deduce their weighting just from that!? it's not important of course but i can't help but wonder lol
So then i checked the two ITU versions...
BT.601:
R $FF0000 -> $4C
G $00FF00 -> $96
B $0000FF -> $1D
BT.709:
R $FF0000 -> $36
G $00FF00 -> $B6
B $0000FF -> $12
Hmm, Photoshop secret sauce! can anyone figure out the weighting!? (is it even possible, seeing as the three values are added together!?)

Re: deducing Photoshop's grayscale weighting algorithm
Posted: Wed Feb 17, 2016 7:21 am
by Keya
Well, i thought i might've got it ...
Code: Select all
Procedure.l RGBtoPhotoshopGrayMaybe(red,green,blue)
ProcedureReturn (red * 0.5058823824) + (green * 0.8627451062) + (blue * 0.2745098174)
EndProcedure
That works for the three base colors, BUT I just tried with $112233, which Photoshop reduces to $20 but the above algorithm returns $34!

the mystery continues lol
Re: deducing Photoshop's grayscale weighting algorithm
Posted: Fri Feb 19, 2016 11:07 pm
by tj1010
It's probably be easier to BP their UI and trace routines than figure out the math from the results. They could have multiple handlers for multiple ranges.
Re: deducing Photoshop's grayscale weighting algorithm
Posted: Sat Feb 20, 2016 5:57 am
by wilbert
tj1010 wrote:It's probably be easier to BP their UI and trace routines than figure out the math from the results. They could have multiple handlers for multiple ranges.
Indeed all kinds of possibilities.
It looks like Photoshop uses the sRGB colorspace to do a grayscale conversion.
After experimenting a bit myself with different formulas and constants, this is a simple approximation
Code: Select all
Procedure.l grayconv(red, green, blue)
ProcedureReturn Sqr(0.23*red*red + 0.70*green*green + 0.07*blue*blue)
EndProcedure
If speed is important, you might use a lookup table for the sqr part.
Code: Select all
Global Dim SqrTable.a(65025)
For i = 0 To 65025
SqrTable(i) = Sqr(i)
Next
Procedure.l RGBtoLuma(red, green, blue); weighted Euclidean distance
!movzx eax, byte [p.v_red]
!movzx ecx, byte [p.v_green]
!movzx edx, byte [p.v_blue]
!imul eax, eax
!imul ecx, ecx
!imul edx, edx
!imul eax, 0x3ae1
!imul ecx, 0xb333
!imul edx, 0x11ec
!add eax, ecx
!lea eax, [eax + edx + 0x8000]
!shr eax, 16
CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
!mov rdx, [a_SqrTable]
!movzx eax, byte [rdx + rax]
CompilerElse
!mov edx, [a_SqrTable]
!movzx eax, byte [edx + eax]
CompilerEndIf
ProcedureReturn
EndProcedure
I also used this approach in the quality optimized version of my grayscale module
http://www.purebasic.fr/english/viewtop ... 18#p482418
Re: deducing Photoshop's grayscale weighting algorithm
Posted: Mon Feb 22, 2016 6:30 am
by wilbert
This official conversion to and from sRGB I found online seems to be the closest I can find to what Photoshop does.
If someone else finds a better procedure, please let it know
Code: Select all
Procedure.d inv_gam_sRGB(ic)
c.d = ic/255.0
If c <= 0.04045
ProcedureReturn c/12.92
Else
ProcedureReturn Pow((c+0.055)/1.055,2.4)
EndIf
EndProcedure
Procedure gam_sRGB(v.d)
If v <= 0.0031308
v * 12.92
Else
v = 1.055*Pow(v,1.0/2.4)-0.055
EndIf
ProcedureReturn Int(v*255+0.5)
EndProcedure
Procedure gray(r, g, b)
ProcedureReturn gam_sRGB(0.2126*inv_gam_sRGB(r) +
0.7152*inv_gam_sRGB(g) +
0.0722*inv_gam_sRGB(b))
EndProcedure
Re: deducing Photoshop's grayscale weighting algorithm
Posted: Thu Feb 25, 2016 4:59 am
by Keya
heehee brilliant detective work!!! i havent worked with any sRGB conversions before (coffee+wiki time here) so it should be fun to learn

Re: deducing Photoshop's grayscale weighting algorithm
Posted: Thu Feb 25, 2016 6:33 am
by wilbert
Keya wrote:heehee brilliant detective work!!! i havent worked with any sRGB conversions before (coffee+wiki time here) so it should be fun to learn

I hadn't used them before either.
When I looked at luma functions like this
Y' = 0.2126 R' + 0.7152 G' + 0.0722 B' , I always ignored the
' but it turns out to be very important as it indicates the RGB components are in a non linear color space.
So the results when using
Y = 0.2126 R + 0.7152 G + 0.0722 B are very different from
Y' = 0.2126 R' + 0.7152 G' + 0.0722 B' 
Re: deducing Photoshop's grayscale weighting algorithm
Posted: Thu Feb 25, 2016 6:54 am
by Keya

lol,
somehow ' managed to escape my attention, thanks for pointing out!
Re: deducing Photoshop's grayscale weighting algorithm
Posted: Thu Feb 25, 2016 9:39 am
by wilbert
I did a visual compare
The mean, average, 601 linear and 709 linear come from your own thread
http://www.purebasic.fr/english/viewtop ... 12&t=64914
709 sRGB is what I noticed to be closest to Photoshop (sRGB colorspace, 709 constants)
The last formula is my own simple approximation.
Re: deducing Photoshop's grayscale weighting algorithm
Posted: Thu Feb 25, 2016 10:12 am
by davido
@
wilbert,
I never thought that this would be so complicated.
Thank you for showing the comparison table. In my humble opinion your 'simple' approximation seems best.
Re: deducing Photoshop's grayscale weighting algorithm
Posted: Thu Feb 25, 2016 11:02 am
by Keya
Re: deducing Photoshop's grayscale weighting algorithm
Posted: Thu Feb 25, 2016 11:21 am
by wilbert
Thanks
Indeed the image makes things more clear.
As for my own approximation, you mainly see the difference when you put it over a Photoshop converted image and alter between them.
I think the sRGB looks slightly better but the Sqrt approximation has the advantage that it's faster to compute and could be converted to SSE2 to work on 4 color to gray conversions simultaneously.
When working with sRGB, it's probably best to use lookup tables otherwise it might get slow.