Package pyvision :: Package other :: Module color
[hide private]
[frames] | no frames]

Source Code for Module pyvision.other.color

  1  # PyVision License 
  2  # 
  3  # Copyright (c) 2011 David S. Bolme 
  4  # All rights reserved. 
  5  # 
  6  # Redistribution and use in source and binary forms, with or without 
  7  # modification, are permitted provided that the following conditions 
  8  # are met: 
  9  #  
 10  # 1. Redistributions of source code must retain the above copyright 
 11  # notice, this list of conditions and the following disclaimer. 
 12  #  
 13  # 2. Redistributions in binary form must reproduce the above copyright 
 14  # notice, this list of conditions and the following disclaimer in the 
 15  # documentation and/or other materials provided with the distribution. 
 16  #  
 17  # 3. Neither name of copyright holders nor the names of its contributors 
 18  # may be used to endorse or promote products derived from this software 
 19  # without specific prior written permission. 
 20  #  
 21  #  
 22  # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
 23  # ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
 24  # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
 25  # A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR 
 26  # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
 27  # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
 28  # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
 29  # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
 30  # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
 31  # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
 32  # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 33  ''' 
 34  Created on Jan 11, 2011 
 35   
 36  @author: bolme 
 37  ''' 
 38   
 39  import pyvision as pv 
 40  import cv 
 41  import numpy as np 
 42   
 43  HIST_HS = "HIST_HS" 
 44  HIST_RGB = "HIST_RGB" 
 45   
46 -class Histogram:
47 '''Basically a wrapper around an OpenCV histogram.''' 48
49 - def __init__(self,hist,hist_type,nbins1,nbins2,nbins3):
50 ''' 51 nbins* are the number of bins and should be set to None if they do not exist 52 @param hist: the OpenCV histogram 53 @param hist_type 54 ''' 55 self.hist = hist 56 self.hist_type = hist_type 57 self.nbins1 = nbins1 58 self.nbins2 = nbins2 59 self.nbins3 = nbins3 60 61 assert isinstance(nbins1,int) and nbins1 > 0
62
63 - def asMatrix(self):
64 if self.nbins2 == None: 65 result = np.zeros([self.nbins1]) 66 for i in range(self.nbins1): 67 result[i] = cv.QueryHistValue_1D(self.hist,i) 68 return result 69 elif self.nbins3 == None: 70 result = np.zeros([self.nbins1,self.nbins2]) 71 for i in range(self.nbins1): 72 for j in range(self.nbins2): 73 result[i,j] = cv.QueryHistValue_2D(self.hist,i,j) 74 return result 75 else: 76 result = np.zeros([self.nbins1,self.nbins2,self.nbins3]) 77 for i in range(self.nbins1): 78 for j in range(self.nbins2): 79 for k in range(self.nbins3): 80 result[i,j,k] = cv.QueryHistValue_3D(self.hist,i,j,k) 81 return result
82
83 - def rescaleMax(self,value=255):
84 ''' 85 Rescale the histogram such that the maximum equals the value. 86 ''' 87 cv.NormalizeHist(self.hist,1) 88 _,max_value,_,_ = cv.GetMinMaxHistValue(self.hist) 89 if max_value == 0: 90 max_value = 1.0 91 cv.NormalizeHist(self.hist,255/max_value)
92
93 - def rescaleSum(self,value=1.0):
94 ''' 95 Rescale the histogram such that the maximum equals the value. 96 ''' 97 cv.NormalizeHist(self.hist,value)
98
99 - def backProject(self,im,bg_hist=None):
100 if self.hist_type == pv.HIST_HS: 101 return pv.hsBackProjectHist(im,self,bg_hist) 102 if self.hist_type == pv.HIST_RGB: 103 return pv.rgbBackProjectHist(im,self,bg_hist) 104 else: 105 raise NotImplementedError("backProject not implemented for type: %s"%self.hist_type)
106 107
108 -def HSHist(im,h_bins=32,s_bins=32,mask=None,normalize=True):
109 ''' 110 Compute the hue saturation histogram of an image. (Based on OpenCV example code). 111 112 @param im: the image 113 @type im: pv.Image 114 @param h_bins: the number of bins for hue. 115 @type h_bins: int 116 @param s_bins: the number of bins for saturation. 117 @type s_bins: int 118 @param mask: an image containing a mask 119 @type mask: cv.Image or np.array(dtype=np.bool) 120 @return: an OpenCV histogram 121 @rtype: pv.Histogram 122 ''' 123 w,h = im.size 124 hsv = im.asHSV() 125 126 # Extract the H and S planes 127 h_plane = cv.CreateImage((w,h), cv.IPL_DEPTH_8U, 1) 128 s_plane = cv.CreateImage((w,h), cv.IPL_DEPTH_8U, 1) 129 cv.Split(hsv, h_plane, s_plane, None, None) 130 planes = [h_plane, s_plane] 131 132 # set the histogram size 133 hist_size = [h_bins, s_bins] 134 135 # hue varies from 0 (~0 deg red) to 180 (~360 deg red again */ 136 h_ranges = [0, 180] 137 138 # saturation varies from 0 (black-gray-white) to 139 # 255 (pure spectrum color) 140 s_ranges = [0, 255] 141 142 ranges = [h_ranges, s_ranges] 143 144 # Calculate the histogram 145 hist = cv.CreateHist(hist_size, cv.CV_HIST_ARRAY, ranges, 1) 146 if mask != None: 147 mask = mask.asOpenCVBW() 148 cv.CalcHist(planes, hist,mask=mask) 149 150 return pv.Histogram(hist,HIST_HS,h_bins,s_bins,None)
151 152
153 -def RGBHist(im,r_bins=8,g_bins=8,b_bins=8,mask=None,normalize=True):
154 ''' 155 Compute the rgb saturation histogram of an image. (Based on OpenCV example code). 156 157 @param im: the image 158 @type im: pv.Image 159 @param r_bins: the number of bins for hue. 160 @type r_bins: int 161 @param g_bins: the number of bins for hue. 162 @type g_bins: int 163 @param b_bins: the number of bins for hue. 164 @type b_bins: int 165 @param mask: an image containing a mask 166 @type mask: cv.Image or np.array(dtype=np.bool) 167 @return: an OpenCV histogram 168 @rtype: pv.Histogram 169 ''' 170 w,h = im.size 171 bgr = im.asOpenCV() 172 173 # Extract the H and S planes 174 b_plane = cv.CreateImage((w,h), cv.IPL_DEPTH_8U, 1) 175 g_plane = cv.CreateImage((w,h), cv.IPL_DEPTH_8U, 1) 176 r_plane = cv.CreateImage((w,h), cv.IPL_DEPTH_8U, 1) 177 cv.Split(bgr, b_plane, g_plane, r_plane, None) 178 planes = [b_plane, g_plane, r_plane] 179 180 # set the histogram size 181 hist_size = [b_bins, g_bins, r_bins] 182 183 # pixel value ranges 184 b_ranges = [0, 255] 185 g_ranges = [0, 255] 186 r_ranges = [0, 255] 187 188 ranges = [b_ranges, g_ranges, r_ranges] 189 190 # Calculate the histogram 191 hist = cv.CreateHist(hist_size, cv.CV_HIST_ARRAY, ranges, 1) 192 if mask != None: 193 mask = mask.asOpenCVBW() 194 cv.CalcHist(planes, hist, mask=mask) 195 196 return pv.Histogram(hist,HIST_RGB,b_bins,g_bins,r_bins)
197 198
199 -def hsBackProjectHist(im,fg_hist,bg_hist=None):
200 ''' 201 Compute the hue saturation histogram of an image. (Based on OpenCV example code). 202 203 @param im: the image 204 @type im: pv.Image 205 @param fg_hist: the histogram 206 @type fg_hist: pv.Histogram 207 @param bg_hist: 208 @type bg_hist: pv.Histogram 209 @return: an OpenCV histogram 210 @rtype: pv.Image 211 ''' 212 w,h = im.size 213 hsv = im.asHSV() 214 215 if bg_hist != None: 216 # set the histogram size 217 hist_size = [fg_hist.nbins1, fg_hist.nbins2] 218 219 # pixel value ranges 220 h_ranges = [0, 180] 221 s_ranges = [0, 255] 222 ranges = [h_ranges, s_ranges] 223 224 # Calculate the histogram 225 prob_hist = cv.CreateHist(hist_size, cv.CV_HIST_ARRAY, ranges, 1) 226 227 fg_hist.rescaleMax(255) 228 bg_hist.rescaleMax(255) 229 230 cv.CalcProbDensity(bg_hist.hist, fg_hist.hist, prob_hist, scale=255) 231 232 fg_hist = pv.Histogram(prob_hist,pv.HIST_HS,fg_hist.nbins1, fg_hist.nbins2, None) 233 234 # Extract the H and S planes 235 h_plane = cv.CreateImage((w,h), cv.IPL_DEPTH_8U, 1) 236 s_plane = cv.CreateImage((w,h), cv.IPL_DEPTH_8U, 1) 237 cv.Split(hsv, h_plane, s_plane, None, None) 238 planes = [h_plane, s_plane] 239 240 output = cv.CreateImage((w,h), cv.IPL_DEPTH_8U, 1) 241 242 # Normalize the histogram 243 fg_hist.rescaleMax(255) 244 245 cv.CalcBackProject(planes,output,fg_hist.hist) 246 247 return pv.Image(output)
248
249 -def rgbBackProjectHist(im,fg_hist,bg_hist=None):
250 ''' 251 Compute the hue saturation histogram of an image. (Based on OpenCV example code). 252 253 @param im: the image 254 @type im: pv.Image 255 @param fg_hist: the histogram 256 @type fg_hist: pv.Histogram 257 @param bg_hist: 258 @type bg_hist: pv.Histogram 259 @return: an OpenCV histogram 260 @rtype: pv.Image 261 ''' 262 w,h = im.size 263 bgr = im.asOpenCV() 264 265 if bg_hist != None: 266 # set the histogram size 267 hist_size = [fg_hist.nbins1, fg_hist.nbins2,fg_hist.nbins3] 268 269 # pixel value ranges 270 b_ranges = [0, 255] 271 g_ranges = [0, 255] 272 r_ranges = [0, 255] 273 ranges = [b_ranges, g_ranges, r_ranges] 274 275 # Calculate the histogram 276 prob_hist = cv.CreateHist(hist_size, cv.CV_HIST_ARRAY, ranges, 1) 277 278 fg_hist.rescaleMax(255) 279 bg_hist.rescaleMax(255) 280 281 cv.CalcProbDensity(bg_hist.hist, fg_hist.hist, prob_hist, scale=255) 282 283 fg_hist = pv.Histogram(prob_hist,pv.HIST_HS,fg_hist.nbins1, fg_hist.nbins2, None) 284 285 # Extract the H and S planes 286 b_plane = cv.CreateImage((w,h), cv.IPL_DEPTH_8U, 1) 287 g_plane = cv.CreateImage((w,h), cv.IPL_DEPTH_8U, 1) 288 r_plane = cv.CreateImage((w,h), cv.IPL_DEPTH_8U, 1) 289 cv.Split(bgr, b_plane, g_plane, r_plane, None) 290 planes = [b_plane, g_plane, r_plane] 291 292 output = cv.CreateImage((w,h), cv.IPL_DEPTH_8U, 1) 293 294 # Normalize the histogram 295 fg_hist.rescaleMax(255) 296 297 cv.CalcBackProject(planes,output,fg_hist.hist) 298 299 return pv.Image(output)
300 301 import unittest 302
303 -class ColorTest(unittest.TestCase):
304
305 - def test01_hsHist(self):
306 '''Test hue saturation histogram.''' 307 ilog = None # pv.ImageLog() 308 im = pv.Image(pv.BABOON) 309 mask = np.zeros((512,512),dtype=np.bool) 310 mask[150:200,128:300] = True 311 m = pv.Image(1.0*mask) 312 hist = HSHist(im,mask=m) 313 #print hist 314 #print dir(hist) 315 #print dir(hist.bins),hist.bins.channels 316 #for i in range(32): 317 # for j in range(30): 318 # print i,j,cv.QueryHistValue_2D(hist,j,i) 319 hist.rescaleMax(255) 320 321 #print hist.asMatrix() 322 #print cv.SetHistBinRanges 323 back = hist.backProject(im) 324 if ilog != None: 325 ilog(im) 326 ilog(m) 327 ilog(back) 328 ilog.show()
329 330 if __name__ == "__main__": 331 #import sys;sys.argv = ['', 'Test.testName'] 332 unittest.main(testRunner = unittest.TextTestRunner(verbosity=2)) 333