Package Vision :: Module PILNodes
[hide private]
[frames] | no frames]

Source Code for Module Vision.PILNodes

  1  ######################################################################### 
  2  # 
  3  # Date: Nov 2001 Authors: Michel Sanner, Daniel Stoffler 
  4  # 
  5  #    sanner@scripps.edu 
  6  #    stoffler@scripps.edu 
  7  # 
  8  #       The Scripps Research Institute (TSRI) 
  9  #       Molecular Graphics Lab 
 10  #       La Jolla, CA 92037, USA 
 11  # 
 12  # Copyright: Michel Sanner, Daniel Stoffler and TSRI 
 13  # 
 14  ######################################################################### 
 15   
 16  import Tkinter 
 17  import Numeric 
 18  import Image, ImageTk 
 19  import types 
 20  import math 
 21   
 22  from NetworkEditor.items import NetworkNode 
 23  from Vision import UserLibBuild 
 24   
 25   
26 -class ImageFromArray(NetworkNode):
27 """based on the Image.open function. Reads an image file 28 Input: filename (string) 29 Output: Image""" 30
31 - def __init__(self, name='Image from array', **kw):
32 kw['name'] = name 33 apply( NetworkNode.__init__, (self,), kw) 34 35 code = """def doit(self, array, width, height, normalize, linkRGB): 36 lennar = len(array) 37 if lennar != width * height: 38 import warnings 39 print ("Image from array: width * height must be equal to len(array)") 40 return 41 if hasattr(array[0], '__len__') is False or len(array[0]) == 1: 42 lenarray = 1 43 elif len(array[0]) == 3: 44 lenarray = 3 45 elif len(array[0]) == 4: 46 lenarray = 4 47 48 nar = Numeric.array(array) 49 narOriginalShape = nar.shape 50 nar.shape = (width*height*lenarray,) 51 52 if type(nar[0]) == types.FloatType: 53 54 if normalize == 1: 55 nar.shape = narOriginalShape 56 if lenarray == 1: 57 mininar = min(nar) 58 maxinar = max(nar) 59 ecartnar = maxinar - mininar 60 if ecartnar > 0: 61 for i in range(lennar): 62 nar[i] = (nar[i] - mininar) / ecartnar 63 else: 64 narChannel = range(lennar) 65 mininar = [0,0,0,0] 66 maxinar = [0,0,0,0] 67 for j in range(lenarray): 68 for i in range(lennar): 69 narChannel[i] = nar[i][j] 70 mininar[j] = min(narChannel) 71 maxinar[j] = max(narChannel) 72 73 if linkRGB == 1: 74 mininarGlobal = min(mininar[0], mininar[1], mininar[2]) 75 mininar[0] = mininarGlobal 76 mininar[1] = mininarGlobal 77 mininar[2] = mininarGlobal 78 maxinarGlobal = max(maxinar[0], maxinar[1], maxinar[2]) 79 maxinar[0] = maxinarGlobal 80 maxinar[1] = maxinarGlobal 81 maxinar[2] = maxinarGlobal 82 83 for j in range(lenarray): 84 ecartnar = maxinar[j] - mininar[j] 85 if ecartnar > 0: 86 for i in range(lennar): 87 nar[i][j] = (nar[i][j] - mininar[j]) / ecartnar 88 89 nar.shape = (width*height*lenarray,) 90 for i in range(len(nar)): 91 nar[i] = int(math.floor( 255.999 * nar[i] )) 92 nar = nar.astype(Numeric.UnsignedInt8) 93 94 if lenarray == 1: 95 im = Image.fromstring('L', (width, height), nar.tostring()) 96 elif lenarray == 3: 97 im = Image.fromstring('RGB', (width, height), nar.tostring()) 98 elif lenarray == 4: 99 im = Image.fromstring('RGBA', (width, height), nar.tostring()) 100 if im: 101 self.outputData(image=im) 102 """ 103 104 self.setFunction(code) 105 106 self.inputPortsDescr.append(datatype='list', name='array') 107 self.inputPortsDescr.append(datatype='int', name='width') 108 self.inputPortsDescr.append(datatype='int', name='height') 109 self.inputPortsDescr.append(datatype='boolean', name='normalize') 110 self.inputPortsDescr.append(datatype='boolean', name='linkRGB') 111 self.outputPortsDescr.append(datatype='image', name='image') 112 113 self.widgetDescr['normalize'] = { 114 'class':'NECheckButton', 115 'master':'node', 116 'initialValue':False, 117 'labelGridCfg':{'sticky':'we'}, 118 'labelCfg':{'text':'normalize floats'}, 119 } 120 121 self.widgetDescr['linkRGB'] = { 122 'class':'NECheckButton', 123 'master':'node', 124 'initialValue':True, 125 'labelGridCfg':{'sticky':'we'}, 126 'labelCfg':{'text':'link RGB normalization'}, 127 }
128 129 130
131 -class ReadImage(NetworkNode):
132 """based on the Image.open function. Reads an image file 133 Input: filename (string) 134 Output: Image""" 135
136 - def __init__(self, name='Read Image', **kw):
137 kw['name'] = name 138 apply( NetworkNode.__init__, (self,), kw) 139 #self.readOnly = 1 140 code = """def doit(self, filename): 141 if filename: 142 im = Image.open(filename) 143 if im: 144 self.outputData(image=im)\n""" 145 146 self.setFunction(code) 147 148 fileTypes = [('all', '*'), ('jpeg', '*.jpg'), ('tiff', '*.tif'), 149 ('png', '*.png'), ('bmp', '*.bmp')] 150 151 self.widgetDescr['filename'] = { 152 'class':'NEEntryWithFileBrowser', 'master':'node', 153 'filetypes':fileTypes, 'title':'read image', 'width':10, 154 'labelCfg':{'text':'image file:'} } 155 156 self.inputPortsDescr.append(datatype='str', name='filename') 157 self.outputPortsDescr.append(datatype='image', name='image')
158 159
160 -class SaveImage(NetworkNode):
161 """saves an image.""" 162
163 - def __init__(self, name='Save Image', **kw):
164 kw['name'] = name 165 apply( NetworkNode.__init__, (self,), kw) 166 #self.readOnly = 1 167 code = """def doit(self, image, filename): 168 if filename: 169 image.save(filename)\n""" 170 171 self.setFunction(code) 172 173 fileTypes = [('all', '*')] 174 175 self.widgetDescr['filename'] = { 176 'class':'NEEntryWithFileSaver', 'master':'node', 177 'filetypes':fileTypes, 'title':'save image', 'width':10, 178 'labelCfg':{'text':'image file:'} } 179 180 self.inputPortsDescr.append(datatype='image', name='image') 181 self.inputPortsDescr.append(datatype='str', name='filename')
182 183
184 -class GetFrontBuffer(NetworkNode):
185 """Extract front buffer image of camera 0 of DejaVu Viewer""" 186
187 - def getFrontBuffer(self, width, height):
188 from opengltk.OpenGL import GL 189 #import bufarray 190 #bar = bufarray.Bufarray(3*width*height, bufarray.ubyteCtype) 191 #GL.glReadPixels( 0, 0, width, height, GL.GL_RGB, bar) 192 193 bar = GL.glReadPixels( 0, 0, width, height, GL.GL_RGB, GL_GL_UBYTE) 194 im = Image.fromstring('RGB', (width,height), bar) 195 #FIXME we have to destroy bar .. but how ? 196 197 # for some reason refount is 2 198 #import sys 199 #print sys.getrefcount(bar) 200 del bar 201 return im.transpose(Image.FLIP_TOP_BOTTOM)
202 203
204 - def __init__(self, name='Front Buffer', **kw):
205 kw['name'] = name 206 apply( NetworkNode.__init__, (self,), kw) 207 208 ip = self.inputPortsDescr 209 ip.append(datatype='viewer', name='viewer') 210 ip.append(datatype='int', required=False, name='cameraNum') 211 212 self.outputPortsDescr.append(datatype='image', name='image') 213 214 215 code = """def doit(self, viewer, cameraNum=None): 216 if cameraNum is None: 217 cameraNum=0 218 camera = viewer.cameras[cameraNum] 219 camera.Activate() 220 #width = divmod(camera.width, 4)[0]*4 221 #height = divmod(camera.height, 4)[0]*4 222 self.outputData(image = camera.GrabFrontBuffer() ) 223 """ 224 225 self.setFunction(code)
226
227 - def beforeAddingToNetwork(self, net):
228 try: 229 ed = net.getEditor() 230 from DejaVu.VisionInterface.DejaVuNodes import vizlib 231 ed.addLibraryInstance(vizlib, 232 'DejaVu.VisionInterface.DejaVuNodes', 233 'vizlib') 234 except: 235 import traceback 236 traceback.print_exc() 237 print 'Warning! Could not import vizlib from DejaVu/VisionInterface'
238 239
240 -class GetZBuffer(NetworkNode):
241 """Extract front buffer image of camera 0 of DejaVu Viewer""" 242
243 - def getZBuffer(self, width, height):
244 from opengltk.OpenGL import GL 245 depthString = GL.glReadPixels( 0, 0, width, height, 246 GL.GL_DEPTH_COMPONENT, GL.GL_FLOAT) 247 import struct 248 zval = Numeric.array(struct.unpack('%df'%width*height, depthString)) 249 zmax = max(zval) 250 zmin = min(zval) 251 zval1 = 255 * ((zval-zmin) / (zmax-zmin)) 252 ds = zval1.astype('c').tostring() 253 depthImage = Image.fromstring('P', (width, height), ds) 254 255 return depthImage.transpose(Image.FLIP_TOP_BOTTOM)
256 257
258 - def __init__(self, name='Z Buffer', **kw):
259 kw['name'] = name 260 apply( NetworkNode.__init__, (self,), kw) 261 262 ip = self.inputPortsDescr 263 ip.append(datatype='viewer', name='viewer') 264 ip.append(datatype='int', required=False, name='cameraNum') 265 266 self.outputPortsDescr.append(datatype='image', name='image') 267 268 code = """def doit(self, viewer, cameraNum=None): 269 if cameraNum is None: 270 cameraNum=0 271 camera = viewer.cameras[cameraNum] 272 camera.Activate() 273 #width = divmod(camera.width, 4)[0]*4 274 #height = divmod(camera.height, 4)[0]*4 275 self.outputData(image = camera.GrabZBuffer() ) 276 """ 277 278 self.setFunction(code)
279
280 - def beforeAddingToNetwork(self, net):
281 try: 282 ed = net.getEditor() 283 from DejaVu.VisionInterface.DejaVuNodes import vizlib 284 ed.addLibraryInstance(vizlib, 285 'DejaVu.VisionInterface.DejaVuNodes', 286 'vizlib') 287 except: 288 import traceback 289 traceback.print_exc() 290 print 'Warning! Could not import vizlib from DejaVu/VisionInterface'
291 292
293 -class ToRGB(NetworkNode):
294 """converts an Image to RGB""" 295
296 - def __init__(self, name='To RGB', **kw):
297 kw['name'] = name 298 apply( NetworkNode.__init__, (self,), kw) 299 300 self.inputPortsDescr.append(datatype='image', name='image') 301 302 self.outputPortsDescr.append(datatype='image', name='RGBimage') 303 304 code = """def doit(self, image): 305 if image.mode!='RGB': 306 image.draft('RGB', image.size) 307 image = image.convert('RGB') 308 self.outputData(RGBimage=image)\n""" 309 310 self.setFunction(code)
311 312
313 -class ResizeImage(NetworkNode):
314 """Resize image using scaling factor supplied by dial. The filter argument 315 can be NEAREST, BILINEAR, or BICUBIC. If omitted, it defaults to NEAREST. 316 """ 317
318 - def __init__(self, name='Resize', **kw):
319 kw['name'] = name 320 apply( NetworkNode.__init__, (self,), kw) 321 322 code = """def doit(self, image, scale, filter): 323 import Image 324 w,h = image.size 325 if filter is not None and filter != '': 326 op = eval('Image.'+filter) 327 result = image.resize( (w*scale, h*scale), op ) 328 else: 329 result = image.resize( (w*scale, h*scale) ) 330 331 self.outputData( scaledImage=result )\n""" 332 333 if code: self.setFunction(code) 334 335 self.widgetDescr['scale'] = { 336 'class': 'NEDial', 'master':'ParamPanel', 'size': 100, 337 'type': 'float', 'oneTurn': 1.0, 'min':0.01, 338 'initialValue':1.0, 339 'labelCfg':{'text':'Scale'}, 340 'widgetGridCfg':{'labelSide':'top'}, 341 } 342 343 filters = ['NEAREST','BILINEAR','BICUBIC' ] 344 self.widgetDescr['filter'] = { 345 'class':'NEComboBox', 346 'choices':filters, 347 'fixedChoices':True, 348 'initialValue':'NEAREST', 349 'entryfield_entry_width':12, 350 'labelCfg':{'text':'filter'}, 351 'widgetGridCfg':{'labelSide':'top'}, 352 } 353 354 ip = self.inputPortsDescr 355 ip.append(datatype='image', name='image') 356 ip.append(datatype='float', name='scale') 357 ip.append(datatype='string', name='filter') 358 359 op = self.outputPortsDescr 360 op.append(datatype='image', name='scaledImage')
361 362
363 -class ImageFilter(NetworkNode):
364 """Apply different filters to an image""" 365
366 - def __init__(self, name='Filter Image', **kw):
367 kw['name'] = name 368 apply( NetworkNode.__init__, (self,), kw) 369 370 filters = ['BLUR', 'CONTOUR', 'DETAIL', 'EDGE_ENHANCE', 371 'EDGE_ENHANCE_MORE', 'EMBOSS', 'FIND_EDGES', 372 'SMOOTH', 'SMOOTH_MORE', 'SHARPEN' ] 373 374 self.widgetDescr['filter'] = { 375 'class':'NEComboBox', 'master':'node', 376 'choices':filters, 377 'fixedChoices':True, 378 'entryfield_entry_width':14, 379 'labelCfg':{'text':'filter:'}, 380 } 381 382 ip = self.inputPortsDescr 383 ip.append(datatype='image', name='image') 384 ip.append(datatype='None', name='filter') 385 386 self.outputPortsDescr.append(datatype='image', name='image') 387 388 code = """def doit(self, image, filter): 389 import ImageFilter 390 if filter is not '' and image: 391 op = eval('ImageFilter.'+filter) 392 self.outputData(image= image.filter(op))\n""" 393 394 self.setFunction(code)
395 396
397 -class ImageInvert(NetworkNode):
398 """Inverts an image.""" 399
400 - def __init__(self, name='Invert Image', **kw):
401 kw['name'] = name 402 apply( NetworkNode.__init__, (self,), kw) 403 404 self.inputPortsDescr.append(datatype='image', name='image') 405 406 self.outputPortsDescr.append(datatype='image', name='image') 407 408 code = """def doit(self, image): 409 import ImageChops 410 self.outputData(image = ImageChops.invert(image))\n""" 411 412 self.setFunction(code)
413 414
415 -class ImageMultiply(NetworkNode):
416 """Superimposes two images on top of each other. If you multiply an 417 image with a solid black image, the result is black. If you multiply with 418 a solid white image, the image is unaffected.""" 419
420 - def __init__(self, name='Multiply Image', **kw):
421 kw['name'] = name 422 apply( NetworkNode.__init__, (self,), kw) 423 424 ip = self.inputPortsDescr 425 ip.append(datatype='image', name='image1') 426 ip.append(datatype='image', name='image2') 427 428 self.outputPortsDescr.append(datatype='image', name='image') 429 430 code = """def doit(self, image1, image2): 431 import ImageChops 432 self.outputData(image = ImageChops.multiply(image1, image2))\n""" 433 434 self.setFunction(code)
435 436
437 -class ImageSplit(NetworkNode):
438 """Apply different filters to an image""" 439
440 - def __init__(self, name='Split Image', **kw):
441 apply( NetworkNode.__init__, (self,), kw) 442 443 self.inputPortsDescr.append(datatype='image', name='image') 444 445 op = self.outputPortsDescr 446 op.append(datatype='None', name='r') 447 op.append(datatype='None', name='g') 448 op.append(datatype='None', name='b') 449 450 code = """def doit(self, image): 451 import Image 452 r,g,b = image.split() 453 self.outputData(r=r, g=g, b=b)\n""" 454 455 self.setFunction(code)
456 457
458 -class AlphaMask(NetworkNode):
459 """Apply different filters to an image""" 460
461 - def __init__(self, name='Alpha Mask', **kw):
462 kw['name'] = name 463 apply( NetworkNode.