Commit | Line | Data |
---|---|---|
4f09d0a3 CE |
1 | # https://github.com/raplin/HexaWS2811/blob/master/gamma.py |
2 | # Lookup table generator | |
3 | # | |
4 | # Really it's correcting for the eye's luminance response, it's not actually gamma correction (it's misnamed!) | |
5 | # | |
6 | # We're generating a set of 256-entry lookup tables which you use to (separately) convert the 8-bit R, G and B components of your color | |
7 | # into something you output, typically with an intelligent RGB LED such as a WS2812B; but a simple CPU-based PWM will give the same results (and benefit from this correction) | |
8 | # | |
9 | # We generate several sets (2,4,8...) of 256-entry tables so you can cycle through them, using a successive 8-bit lookup table each successive output frame. | |
10 | # This is 'temporal dithering', which aims to give you better color resolution at the dark end of the scale. | |
11 | # If you update at e.g. 100hz, try using two or three 'ditherBits' (i.e. 2^^2 or 2^^3=8 tables. The faster your update the more tables you can use | |
12 | # and you get better color resolution. More than 5 ditherbits is probably excessive, even 2 will help somewhat. | |
13 | # | |
14 | # If you get objectionable flickering when displaying low-intensity pixels, you should either update your leds faster or reduce ditherBits | |
15 | # | |
16 | # | |
17 | # | |
18 | fout=open("gamma.h","wt") | |
19 | ||
20 | #adjust me! Each extra bit doubles the table size | |
21 | ditherBits=1 | |
22 | ||
23 | ditherMSB=1<<(ditherBits-1) | |
24 | ||
25 | res="/* Dithered luminance correction table - autogenerated by gamma.py */\n#define DITHER_BITS %d\nconst prog_uchar PROGMEM gammaTable[]={" % ditherBits | |
26 | ||
27 | useRealLuminanceCalcuation=True # CIE 1931 formula | |
28 | ||
29 | finalAdjust=0 #set this to 1 if you want your values to start at one (1..255). This is a quirky request for FastLED users only | |
30 | ||
31 | for dither in range(1<<ditherBits): | |
32 | out=[] | |
33 | ||
34 | #reverse the low order bits so the dithering is less flickery | |
35 | ditherValue=0 | |
36 | dread=1<<ditherBits | |
37 | dout=1 | |
38 | for d in range(ditherBits): | |
39 | dread>>=1 | |
40 | if dither & dread: | |
41 | ditherValue|=dout | |
42 | dout<<=1; | |
43 | ||
44 | ditherValue=(ditherValue<<(8-ditherBits)) | |
45 | ||
46 | for n in range(256): | |
47 | if useRealLuminanceCalcuation: | |
48 | # CIE 1931 | |
49 | brightness=n/2.56 | |
50 | if brightness > 8: | |
51 | pwmValue= pow( ((brightness + 16) / 116) , 3 ) | |
52 | else: | |
53 | pwmValue = brightness / 903.3 | |
54 | pwmValue*=256 | |
55 | else: | |
56 | #use simple power | |
57 | pwmValue=pow(255,(n/256.0))-1 | |
58 | pwmValue=int(pwmValue*256) | |
59 | pwmValue+=ditherValue | |
60 | pwmValue=min(255, (pwmValue>>8)+finalAdjust) | |
61 | out.append( pwmValue ) | |
62 | if dither: | |
63 | res+="," | |
64 | res+="\n\t"+(",".join([ "0x%x"%n for n in out])) | |
65 | ||
66 | res+="\n\t};\n" | |
67 | ||
68 | print >>fout,res | |
69 | fout.close() |