(written by Egor Zindy, firstname.lastname@example.org )
LutCtrl for image processing applications provides controls for the selection of colour scales. The look-up table associated with the colour scale, converts greyscale pixel values between 0 and 255 to R,G,B triplet values. Colour scales are often used in visualisation, because the eye is more sensitive to colour changes than to intensity changes.
As well as the simple LutPanel (which displays the colour scale), there are two additional controls, LutSpin and LutChoice, which will let you pick a scale through either the use of a spin control or a drop down choice list.
The Look-up tables themselves were downloaded from http://rsb.info.nih.gov/ij/download/luts/ (luts.zip and luts2.zip) and may have a copyright attached. They are part of the Rasband, W.S., ImageJ project, U. S. National Institutes of Health, Bethesda, Maryland, USA. Project homepage located here: http://rsb.info.nih.gov/ij/, 1997-2005.
A simple python converter was written to read the ICOL, raw and ASCII formats. If you need it, drop me a mail.
Enough of the theory, this is what the controls look like (Windows and GTK):
Partial list of the luts included: LUT_Montage.jpg
Compared to earlier versions of the code I have released, this last one has two major adavantages:
lutdata/lutctrl do not rely on any numeric library anymore. New version relies on wx, though...
- lut controls generate events from which lut data is easily obtained.
At the cost of a slight increase in filesize, look-up tables are now stored in s="RGBRGBRGB..." interleaved strings, which are easy to convert back to separate r,g,b: r=s[0::3], g=s[1::3], b=s[2::3]. These in turn may be converted to numeric arrays. For instance, using the numpy library, one would write:
using lower level lutdata methods
Python 2.5.1 (r251:54863, Apr 18 2007, 08:51:08) [MSC v.1310 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> import lutdata >>> import numpy >>> l = lutdata.LutData() >>> r,g,b = l.get_rgb(0) >>> r_array = numpy.array(r,numpy.uint8) >>> g_array = numpy.array(g,numpy.uint8) >>> b_array = numpy.array(b,numpy.uint8)
using lutctrl methods
r,g,b = MyLutChoice.GetRGB(0) # get the greyscale values... r_array = numpy.array(r,numpy.uint8) g_array = numpy.array(g,numpy.uint8) b_array = numpy.array(b,numpy.uint8)
Note that the GetRGB() method is also available through lutctrl events.
complete test example (lutctrl_test.py)
This test code imports lutctrl:
1 #Simple LUT Dialog version 20071011. Use at your own risk! 2 #Code put in the public domain, for someone else could find a use for it. 3 4 import wx 5 import lutctrl 6 7 class MyFrame(wx.Frame): 8 def __init__(self): 9 wx.Frame.__init__(self, None, -1, "Lut Control", size=(350,120)) 10 self.CreateStatusBar() 11 12 p = wx.Panel(self,-1) 13 cl=lutctrl.LutChoice(p,0) 14 sl=lutctrl.LutSpin(p,28) 15 pl=lutctrl.LutPanel(p,13) 16 17 box = wx.BoxSizer(wx.VERTICAL) 18 box.Add(cl,0,wx.EXPAND|wx.ALL,2) 19 box.Add(sl,0,wx.EXPAND|wx.ALL,2) 20 box.Add(pl,1,wx.EXPAND|wx.ALL,2) 21 box.Layout() 22 p.SetSizer(box) 23 24 cl.Bind(lutctrl.EVT_LUT, self.OnLut) 25 sl.Bind(lutctrl.EVT_LUT, self.OnLut) 26 27 self.pl = pl 28 29 def OnLut(self,event): 30 s = "LUT %d of %d is '%s'" % ( 31 event.GetLutIndex(), 32 event.GetLutCount(), 33 event.GetLutName()) 34 35 self.SetStatusText(s) 36 self.pl.SetLutIndex(event.GetLutIndex()) 37 38 if __name__ == "__main__": 39 app = wx.PySimpleApp() 40 f = MyFrame() 41 f.Show() 42 app.MainLoop()
Well, I've done everything I could to make this library as generic as possible. If there are any improvements to be made, it's up to you now. For the time being, I think I've run out of ideas... or maybe not?
I've changed SetLut() to SetLutIndex() for consistency. GetLutIndex() was already defined.
- I've re-visited the luts and decided to include them all (without the obvious duplicates)
- Data is now stored inside a PNG file... which means lutdata.py now depends on wx. Maybe there's a better way of doing this? PNG is 18.3KB, raw data is 101KB (256*3*135 bytes)
- Anything else?