run_detector.py
Go to the documentation of this file.
00001 import numpy as np
00002 
00003 import time
00004 import pylab
00005 from scipy import ndimage
00006 import cv2
00007 import os,sys
00008 
00009 import config_feats
00010 import cPickle
00011 from shogun.Classifier import LibSVM
00012 from shogun.Features import RealFeatures
00013 
00014 from iri_bow_object_detector.bow_detector_utils import save_data_for_log
00015 import ehbsw
00016 
00017 #import ipdb
00018 
00019 
00020 def local_maxima(array, min_distance = 1, periodic=False,
00021                  edges_allowed=True):
00022     """Find all local maxima of the array, separated by at least
00023     min_distance.
00024     adapted from = http://old.nabble.com/Finding-local-minima-of-greater-than-a-given-depth-td18988309.html"""
00025     array = np.asarray(array)
00026     cval = 0
00027     if periodic:
00028         mode = 'wrap'
00029     elif edges_allowed:
00030         mode = 'nearest'
00031     else:
00032         mode = 'constant'
00033         cval = array.max()+1
00034     nbhood=ndimage.morphology.generate_binary_structure(len(array.shape),2)
00035     maxima = array == ndimage.maximum_filter(array, footprint=nbhood, mode=mode, cval=cval)
00036     background = (array==0)
00037     eroded_background = ndimage.morphology.binary_erosion(
00038         background, structure=nbhood, border_value=1)
00039     maxima = maxima - eroded_background
00040     maxpy, maxpx = np.where(maxima)
00041     max_points = [(maxpy[i],maxpx[i]) for i in range(len(maxpy))]
00042     if not type(max_points)==list:
00043         max_points=[max_points]
00044     return max_points
00045 
00046 
00047 def fit_window(heat_map, margin=10, min_dist_maxima=5):
00048 
00049     #remove NaN
00050     heat_map[np.isnan(heat_map)]=0
00051     #gauss filter to remove aliasing
00052     heat_map=ndimage.gaussian_filter(heat_map, 5)
00053 
00054     #suppress margin
00055     if margin>0:
00056         heat_map[:,:margin]=0
00057         heat_map[:,-margin:]=0
00058         heat_map[:margin,:]=0
00059         heat_map[-margin:,:]=0
00060 
00061     ind = local_maxima(heat_map, min_distance=min_dist_maxima)
00062 
00063     if len(ind)>0:
00064         ind = np.array(ind).astype('int64')
00065         #estimate cov :(
00066         #for now average window (145x140):
00067         hw=145/2
00068         hh=140/2
00069         win = [(x-hw, y-hh, x+hw, y+hh) for y,x in ind]
00070 
00071     else:
00072         win = []
00073     return ind, heat_map[ind[:,0],ind[:,1]], win
00074 
00075 #---------
00076 
00077 
00078 def prepare_feats(desc, l=2, as_shogun=False):
00079     if l==2: desc = np.sqrt(desc) #bias not afected by sqrt
00080 
00081     norms = np.apply_along_axis(np.linalg.norm, 0, desc[:-1,:], l) #leave bias alone
00082 
00083     np.seterr(divide='ignore', invalid='ignore')
00084 
00085     desc[:-1,:]=desc[:-1,:]/norms #leave bias alone
00086     np.seterr(divide='warn', invalid='warn')
00087 
00088     if l==1: desc=desc[:-1,:] #removing bias dim if L1 -> nonlinear TODO find better way...
00089 
00090     desc[np.isnan(desc)]=0 #handle NaNs
00091     if as_shogun:
00092         desc=RealFeatures(desc.astype('float'))
00093     return desc
00094 
00095 
00096 def gen_windows_SWIG_wrapper(xstep=10, ystep=10, widthmin=100,
00097                              widthmax=170, widthstep=10, whratios=[0.5, 1, 1.5],
00098                              xmax=640, ymax=480):
00099     #upper bound
00100     maxboxes = len(whratios) * ((widthmax-widthmin)/widthstep) * (xmax/xstep) * (ymax/ystep)
00101     bboxes, used = ehbsw.gen_windows(maxboxes*4, xstep, ystep, widthmin, widthmax, widthstep, whratios, xmax, ymax)
00102     bboxes = bboxes[:used,:]
00103     return bboxes
00104     
00105 # def gen_windows(xstep=10, ystep=10, widthmin=100,
00106 #                 widthmax=170, widthstep=10, whratios=[0.5, 1, 1.5],
00107 #                 xmax=640, ymax=480):
00108 #     bboxes=[]
00109 #     for whr in whratios:
00110 #         for w in range(widthmin, widthmax, widthstep):
00111 #             h = w*whr
00112 #             for x in range(int(0+w/2), int(xmax-w/2), xstep):
00113 #                 for y in range(int(0+h/2), int(ymax-h/2), ystep):
00114 #                     bboxes.append( (int(round(x-w/2)), int(round(y-h/2)),
00115 #                                     int(round(x+w/2)), int(round(y+h/2))) )
00116 #     return bboxes
00117 
00118 def splash_as_box(hmap, x1, y1, x2, y2, score, normit):
00119     hmap[y1:y2][:,x1:x2] += score * np.ones((y2-y1, x2-x1))
00120     normit[y1:y2][:,x1:x2] += np.ones((y2-y1, x2-x1))
00121 
00122 def create_robust_histograms(vws, bboxes, NUM_VWORDS):
00123     hs=create_histograms_SWIG_wrapper(vws, bboxes, NUM_VWORDS)
00124     valid=hs.sum(0)!=0
00125     hs=hs[:,valid]
00126     valid=list(valid.nonzero()[0])
00127     bboxes=[bboxes[i] for i in valid]
00128     return hs,bboxes
00129 
00130 def create_histograms_SWIG_wrapper(vws, bboxes, NUM_VWORDS):
00131     nh = len(bboxes)
00132     mh = NUM_VWORDS[0]
00133     
00134     bboxes = np.array(bboxes)
00135     vws = np.array(vws[0])
00136     
00137     h = ehbsw.create_histograms(nh*mh, nh, mh, vws.astype(np.int32), bboxes.astype(np.float32))
00138     h.shape = (nh, mh)
00139     h=np.hstack((h,np.ones((h.shape[0],1))))
00140     return h.T
00141 
00142 # def create_histograms(vws, bboxes, NUM_VWORDS):
00143 # #deprecated by SWIG version!
00144 #     hh=None
00145 #     for i_feat in range(len(NUM_VWORDS)):
00146 #         h = np.zeros((NUM_VWORDS[i_feat], len(bboxes)))
00147 #         for i, bb in enumerate(bboxes):
00148 #             (x1, y1, x2, y2) = bb
00149 #             for geovw in vws[i_feat]:
00150 #                 x, y, vw = geovw
00151 #                 if x>=x1 and x<=x2 and y>=y1 and y<=y2:
00152 #                     h[vw,i] += 1
00153 #         if hh==None:
00154 #             hh=h
00155 #         else:
00156 #             hh=np.vstack((hh,h))
00157 #     hh=np.vstack((hh,np.ones(hh.shape[1])))
00158 #     return hh
00159 
00160 #---------------- Non-linear classifier ----------------
00161 def recode_win(w,xs,ys,xo,yo):
00162     x1,y1,x2,y2=w
00163     cx = xo + (x2+x1)/2
00164     cy = yo + (y2+y1)/2
00165     w = xs * (x2-x1)/2
00166     h = ys * (y2-y1)/2
00167     nx1 = int(round(cx-w/2))
00168     ny1 = int(round(cy-h/2))
00169     nx2 = int(round(cx+w/2))
00170     ny2 = int(round(cy+h/2))
00171     return (nx1,ny1,nx2,ny2)
00172 
00173 def local_search_wins(win):
00174     #shape factors (x_scale, y_scale)
00175     shape_factors=[(1,1.25), (1,1), (1.25,1),
00176                    (1.25, 1.25), (1.4,1), (1, 1.4), (1.4, 1.4)]
00177     #position factors (offset_x, offset_y)
00178     position_factors=[(0,0),
00179         (-32,0),   (-24,0),  (-16,0),  (32,0),
00180         (24,0),    (16,0),   (0,-32),  (0,-24),
00181         (0,-16),   (0,32),   (0,24),   (0,16),
00182         (-8,-8),   (-8,8),   (8,-8),   (8,8),
00183         (-16,-16), (-16,16), (16,-16), (16,16),
00184         (-24,-24), (-24,24), (24,-24), (24,24)]
00185     wins2=[]
00186 
00187     for w in win:
00188         wins2.append([])
00189         for xs,ys in shape_factors:
00190             for xo,yo in position_factors:
00191                 wins2[-1].append(recode_win(w,xs,ys,xo,yo))
00192     return wins2
00193 
00194 
00195 def detect_boxes(w, non_linear_svm_file, ima, mask, conf, vws):
00196     gt_bboxes = None
00197     bias = None
00198     width=mask.shape[1]
00199     height=mask.shape[0]
00200 
00201     iclass = 'polo_collar'
00202     NUM_VWORDS = conf.num_vwords
00203 
00204     if 0: # Without EHBSW
00205         start=time.time()
00206         bboxes = gen_windows_SWIG_wrapper(xstep=20, ystep=20, widthstep=20, xmax=width, ymax=height)
00207         hs,bboxes = create_robust_histograms(vws, bboxes, NUM_VWORDS)
00208         hs=prepare_feats(hs,2)
00209         scores = 1/(1+np.exp(-np.dot(w,hs)))
00210 
00211         for i,b in enumerate(bboxes):
00212             if conf.use_mask:
00213                 if mask[int(round((b[3]+b[1])/2)), int(round((b[2]+b[0])/2))]<=0:
00214                     scores[i]=0
00215 
00216         heat_map = np.zeros((height,width))
00217         normit = np.zeros((height,width))
00218         for p, s in zip(bboxes, scores):
00219             (x1, y1, x2, y2) = p
00220             splash_as_box(heat_map, x1, y1, x2, y2, s, normit)
00221 
00222         np.seterr(divide='ignore', invalid='ignore')
00223         heat_map=np.divide(heat_map,normit)
00224         np.seterr(divide='warn', invalid='warn')
00225 
00226         if conf.verb >= 1: print "TIMESTAMP: done gen_windows ", time.time()-start
00227 
00228     if 1: #EHBSW
00229         start=time.time()
00230         vw_image = np.zeros((height, width)).astype('int32')
00231 
00232         for geovw in vws[0]: #[i_feat]
00233             x, y, vw = geovw
00234             vw_image[y,x]=vw+1
00235 
00236         scores=ehbsw.ehbsw_pownorm(width*height, vw_image, 55, w.astype('float32'))
00237         scores.shape=(height,width)
00238 
00239         if conf.verb >= 1: print "TIMESTAMP: done EHBSW gen_windows ", time.time()-start
00240 
00241         scores=scores*(mask/255.0)        
00242         save_data_for_log(scores) #Save log images
00243         heat_map = scores
00244 
00245 
00246     if conf.merge_windows==True:
00247         ind, prob, win = fit_window(heat_map)
00248     else: # scores is directly probabilities at this point
00249         prob=scores
00250         win=bboxes
00251 
00252     if conf.refine_nonlinear and conf.merge_windows:
00253         #multiply_windows
00254         start=time.time()
00255         win2=local_search_wins(win)
00256         hsbbox2=[create_robust_histograms(vws, w2, NUM_VWORDS) for w2 in win2]
00257         if conf.verb >= 2: print time.time()-start, "TIMESTAMP: create_robust_histograms non linear."
00258 
00259         start=time.time()
00260         #load nonlinear class
00261         if not os.path.exists(non_linear_svm_file):
00262             print "File not found:", non_linear_svm_file
00263             sys.exit(-1)
00264         pf=open(non_linear_svm_file, 'rb')
00265         svm = cPickle.load(pf)
00266         chi2_width = cPickle.load(pf)
00267         AA = cPickle.load(pf)
00268         BB = cPickle.load(pf)
00269         pf.close()
00270 
00271         #eval new windows
00272         win=[]
00273         prob=[]
00274         for hs2, bboxes2 in hsbbox2:
00275             scores2 = svm.apply(prepare_feats(hs2,1,as_shogun=True)).get_labels()
00276             scores2 = scores2*AA+BB
00277             sel_neg = (scores2<0).nonzero()
00278             sel_pos = (scores2>=0).nonzero()
00279             scores2[sel_neg] = 1.0/(1.0+np.exp(scores2[sel_neg]))
00280             scores2[sel_pos] = np.exp(-scores2[sel_pos])/(1.0+np.exp(-scores2[sel_pos]))
00281             #pick one/few best
00282             orderscores2 = [(ii,s) for ii,s in enumerate(scores2)]
00283             orderscores2.sort(key=lambda x: x[1], reverse=True)
00284             win.append(bboxes2[orderscores2[0][0]])
00285             prob.append(orderscores2[0][1])
00286         if conf.single_pred==True:
00287             i=np.argmax(prob)
00288             win=[win[i]]
00289             prob=[prob[i]]
00290         if conf.verb >= 2: print time.time()-start, "TIMESTAMP: non linear svm."
00291 
00292 
00293     ## Save bboxes
00294     #apply mask
00295     # TODO add more filtering (maybe based on score?)
00296     win2=[]
00297     prob2=[]
00298     for w,p in zip(win,prob):
00299         if ((w[3]<height and w[1]>=0 and w[2]<width and w[0]>=0)
00300             and mask[int(round((w[3]+w[1])/2)), int(round((w[2]+w[0])/2))]>0):
00301             win2.append(w)
00302             prob2.append(p)
00303 
00304     win=win2
00305     prob=prob2
00306 
00307 
00308     #if len(prob)>0:
00309     #    maxprob=max(prob)
00310     #    minprob=min(prob)
00311     #for ii,wi in enumerate(win):
00312     #    if minprob==maxprob: wi_color = 255
00313     #    else:                wi_color = int(np.round(255*((prob[ii]-minprob)/(maxprob-minprob))))
00314         #cv2.rectangle(ima,(wi[0],wi[1]), (wi[2],wi[3]), (wi_color,0,0), 3) # rectangles are drawn in image for later! re-done at refine_grasp!
00315 
00316     #cv.ShowImage("Bow detector", ima)
00317     #cv.WaitKey(1000)
00318 
00319 
00320     return (win, prob)
00321 
00322     # TODO
00323     # borrar ventanas con baja prob
00324 
00325 


iri_bow_object_detector
Author(s): dmartinez
autogenerated on Fri Dec 6 2013 22:45:46