deducing Photoshop's grayscale weighting algorithm

For everything that's not in any way related to PureBasic. General chat etc...
User avatar
Keya
Addict
Addict
Posts: 1890
Joined: Thu Jun 04, 2015 7:10 am

deducing Photoshop's grayscale weighting algorithm

Post 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!?) :)
User avatar
Keya
Addict
Addict
Posts: 1890
Joined: Thu Jun 04, 2015 7:10 am

Re: deducing Photoshop's grayscale weighting algorithm

Post 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
tj1010
Enthusiast
Enthusiast
Posts: 716
Joined: Mon Feb 25, 2013 5:51 pm

Re: deducing Photoshop's grayscale weighting algorithm

Post 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.
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3942
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: deducing Photoshop's grayscale weighting algorithm

Post 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
Last edited by wilbert on Mon Feb 22, 2016 6:11 am, edited 4 times in total.
Windows (x64)
Raspberry Pi OS (Arm64)
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3942
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: deducing Photoshop's grayscale weighting algorithm

Post 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
Windows (x64)
Raspberry Pi OS (Arm64)
User avatar
Keya
Addict
Addict
Posts: 1890
Joined: Thu Jun 04, 2015 7:10 am

Re: deducing Photoshop's grayscale weighting algorithm

Post 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 :)
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3942
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: deducing Photoshop's grayscale weighting algorithm

Post 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' :)
Windows (x64)
Raspberry Pi OS (Arm64)
User avatar
Keya
Addict
Addict
Posts: 1890
Joined: Thu Jun 04, 2015 7:10 am

Re: deducing Photoshop's grayscale weighting algorithm

Post by Keya »

:shock: lol, somehow ' managed to escape my attention, thanks for pointing out!
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3942
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: deducing Photoshop's grayscale weighting algorithm

Post 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.
Last edited by wilbert on Wed May 31, 2017 3:05 pm, edited 1 time in total.
Windows (x64)
Raspberry Pi OS (Arm64)
davido
Addict
Addict
Posts: 1890
Joined: Fri Nov 09, 2012 11:04 pm
Location: Uttoxeter, UK

Re: deducing Photoshop's grayscale weighting algorithm

Post 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.
DE AA EB
User avatar
Keya
Addict
Addict
Posts: 1890
Joined: Thu Jun 04, 2015 7:10 am

Re: deducing Photoshop's grayscale weighting algorithm

Post 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 :)
Last edited by Keya on Thu Feb 25, 2016 11:30 am, edited 5 times in total.
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3942
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: deducing Photoshop's grayscale weighting algorithm

Post 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.
Windows (x64)
Raspberry Pi OS (Arm64)
Post Reply