Package pyvision :: Package types :: Module ImageBuffer
[hide private]
[frames] | no frames]

Source Code for Module pyvision.types.ImageBuffer

  1  ''' 
  2  Created on Oct 22, 2010 
  3  @author: Stephen O'Hara 
  4  ''' 
  5  # PyVision License 
  6  # 
  7  # Copyright (c) 2006-2008 Stephen O'Hara 
  8  # All rights reserved. 
  9  # 
 10  # Redistribution and use in source and binary forms, with or without 
 11  # modification, are permitted provided that the following conditions 
 12  # are met: 
 13  #  
 14  # 1. Redistributions of source code must retain the above copyright 
 15  # notice, this list of conditions and the following disclaimer. 
 16  #  
 17  # 2. Redistributions in binary form must reproduce the above copyright 
 18  # notice, this list of conditions and the following disclaimer in the 
 19  # documentation and/or other materials provided with the distribution. 
 20  #  
 21  # 3. Neither name of copyright holders nor the names of its contributors 
 22  # may be used to endorse or promote products derived from this software 
 23  # without specific prior written permission. 
 24  #  
 25  #  
 26  # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
 27  # ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
 28  # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
 29  # A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR 
 30  # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
 31  # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
 32  # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
 33  # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
 34  # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
 35  # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
 36  # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 37  import scipy as sp 
 38  import pyvision as pv 
 39   
40 -class ImageBuffer:
41 ''' 42 Stores a limited number of images from a video (or any other source) 43 Makes it easy to do N-frame-differencing, for example, by easily being 44 able to get the current (middle) frame, plus the first and last frames of the 45 buffer. With an ImageBuffer of size N, as images are added, eventually the 46 buffer fills, and older items are dropped off the end. This is convenient 47 for streaming input sources, as the user can simply keep adding images 48 to this buffer, and internally, the most recent N will be kept available. 49 ''' 50
51 - def __init__(self, N=5):
52 ''' 53 @param N: how many image frames to buffer 54 ''' 55 self._data = [None for _ in xrange(N)] 56 self._count = 0 57 self._max = N
58
59 - def __getitem__(self, key):
60 return self._data[key]
61
62 - def __len__(self):
63 ''' 64 This is a fixed-sized ring buffer, so length is always the number 65 of images that can be stored in the buffer (as initialized with Nframes) 66 ''' 67 return self._max
68
69 - def isFull(self):
70 if self._count == self._max: 71 return True 72 else: 73 return False
74
75 - def clear(self):
76 self._data = [None for _ in xrange(self._max)] 77 self._count = 0
78
79 - def getCount(self):
80 ''' 81 Note that getCount() differs from __len__() in that this method returns the number of 82 image actually stored in the ImageBuffer, while __len__() returns the size of the buffer, 83 defined as the number of images the buffer is allowed to store. 84 ''' 85 return self._count
86
87 - def getBuffer(self):
88 return self._data
89
90 - def getFirst(self):
91 return self._data[0]
92
93 - def getLast(self):
94 return self._data[-1]
95
96 - def getMiddle(self):
97 mid = int(self._count/2) 98 return self._data[mid]
99
100 - def add(self, image):
101 ''' 102 add an image to the buffer, will kick out the oldest of the buffer is full 103 @param image: image to add to buffer 104 ''' 105 self._data.pop(0) #remove last, if just beginning, this will be None 106 self._data.append(image) 107 self._count += 1 108 if(self._count > self._max): 109 self._count = self._max
110
111 - def fillBuffer(self, v):
112 ''' 113 If buffer is empty, you can use this function to spool off the first 114 N frames of a video or list of images to initialize/fill the buffer. 115 @param v: Either a list of pv.Images, an instance of pv.Video or its 116 subclass, or any other iterable that yields a pv.Image() when 117 next() is called. 118 @note: Will cause an assertion exception if buffer is already full. 119 ''' 120 assert not self.isFull() 121 122 if type(v) == list: 123 #create an iterator from an input list of images 124 idxs = range(len(v)) 125 V = ( v[i] for i in idxs) 126 else: 127 V = v 128 129 while not self.isFull(): 130 im = V.next() 131 self.add(im) 132 133 return
134
135 - def asStackBW(self, size=None):
136 ''' 137 Outputs an image buffer as a 3D numpy array ("stack") of grayscale images. 138 @param size: A tuple (w,h) indicating the output size of each frame. 139 If None, then the size of the first image in the buffer will be used. 140 @return: a 3D array (stack) of the gray scale version of the images 141 in the buffer. The dimensions of the stack are (N,w,h), where N is 142 the number of images (buffer size), w and h are the width and height 143 of each image. 144 ''' 145 if size==None: 146 img0 = self[0] 147 (w,h) = img0.size 148 else: 149 (w,h) = size 150 151 f = self.getCount() 152 stack = sp.zeros((f,w,h)) 153 for i,img in enumerate(self._data): 154 #if img is not (w,h) in size, then resize first 155 sz = img.size 156 if (w,h) != sz: 157 img2 = img.resize((w,h)) 158 mat = img2.asMatrix2D() 159 else: 160 mat = img.asMatrix2D() 161 stack[i,:,:] = mat 162 163 return stack
164
165 - def asMontage(self, layout, tile_size=None, **kwargs):
166 (w,h) = self[0].size 167 if tile_size == None: 168 tw = w/5 169 th = h/5 170 if tw < 32: tw=32 171 if th < 24: th=24 172 tile_size = (tw,th) 173 174 im = pv.ImageMontage(self._data, layout=layout, tile_size=tile_size, **kwargs) 175 return im
176
177 - def show(self, N=10, window="Image Buffer", pos=None, delay=0):
178 ''' 179 @param N: The number of images in the buffer to display at once 180 @param window: The window name 181 @param pos: The window position 182 @param delay: The window display duration 183 ''' 184 if self[0] == None: return 185 186 if N <= self._count: 187 im = self.asMontage(layout=(1,N)) 188 else: 189 im = self.asMontage(layout=(1,self._count)) 190 im.show(window, pos, delay)
191 #img = im.asImage() 192 #img.show(window, pos, delay) 193