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
:shock: 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 :)

Image

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. :o
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
WHOA!!!!! excellent image, speaks for itself!!! Amazing how close your inexpensive Sqrt approximation gets, im not sure i'd be able to tell the difference between that and Photoshop's in a police lineup. It's like you've got 10 out of Adobe's 11 secret grayscale herbs and spices lol :)

reading earlier today i found this article a good brief introduction to sRGB and why its important in ecommerce including the web (and apparently the web is optimized for sRGB!). Just another little thing we can all take advantage of i guess! :)

Adobe RGB 1998:
Image Image

sRGB:
Image Image

hey... you know what'd make for a cool t-shirt??? "RGBA", with Red R, Green G, Blue B, and the A cut-out lol :)

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.