Advertisement
Guest User

LeapBridge.py

a guest
Oct 24th, 2014
1,383
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.90 KB | None | 0 0
  1. #!/usr/bin/env bin
  2.  
  3. import time
  4. import Image
  5. import numpy as np
  6. import cv2
  7. import cv2.cv as cv
  8. import ctypes
  9. import Leap
  10.  
  11. import warnings
  12.  
  13. class LeapBridge():
  14.     mx,my,img_leap,img_raw,img_rectified = {},{},{},{},{}  
  15.     img_disparity = None
  16.     sides = ["left","right"]
  17.     sbm = None
  18.  
  19.     def __init__(self,oWidth=640,oHeight=240,mapFile=None):
  20.         warnings.filterwarnings('ignore','.*PEP 3118*.',)
  21.         self.controller = Leap.Controller()
  22.         self.controller.set_policy_flags(Leap.Controller.POLICY_IMAGES)
  23.         self.width = oWidth
  24.         self.height = oHeight
  25.  
  26.         #generating the sbm object for stereo analysis:
  27.         self.sbm = cv.CreateStereoBMState()
  28.         self.sbm.SADWindowSize = 9
  29.         self.sbm.preFilterType = 1
  30.         self.sbm.preFilterSize = 5
  31.         self.sbm.preFilterCap = 39
  32.         self.sbm.minDisparity = 0
  33.         self.sbm.numberOfDisparities = 112
  34.         self.sbm.textureThreshold = 607
  35.         self.sbm.uniquenessRatio = 8
  36.         self.sbm.speckleRange = 8
  37.         self.sbm.speckleWindowSize = 0
  38.        
  39.         self.bm = cv2.StereoBM(cv2.STEREO_BM_FISH_EYE_PRESET,80,11)
  40.  
  41.         #generating blank image here for re-use later:
  42.         self.img_blank = np.zeros([self.height,self.width,3]).astype("uint8")
  43.         self.kernel = np.ones((3,3),np.uint8)
  44.         self.d2d = np.array([[1.0,0.,0.,-5.0638e+02],[0.,1.,0.,-2.3762e+02],[0.,0.,0.,1.3476e+03],[0.,0.,6.9349981e-01,3.503271]])  #depth-to-dist mapping
  45.         print "Initializing..."
  46.         while not self.controller.is_connected:     #always a delay prior to active frames
  47.             time.sleep(0.75)       
  48.         print "Leap initialized"
  49.  
  50.         if mapFile is not None:
  51.             print "Loading map file at: "+repr(mapFile)
  52.             m = np.load(mapFile).tolist()
  53.             if "mx" in m.keys() and "my" in m.keys():
  54.                 mx = m["mx"]
  55.                 my = m["my"]
  56.                 if all(s in mx.keys() and s in my.keys() for s in self.sides):
  57.                     if all(mx[s].shape[0]==self.height and mx[s].shape[1]==self.width and my[s].shape[0]==self.height and my[s].shape[1]==self.width for s in self.sides):
  58.                         print "Map loaded successfully!"
  59.                         self.mx = mx
  60.                         self.my = my
  61.                     else:
  62.                         print "ERROR: Map dimensionality mismatch"
  63.                 else:
  64.                     print "ERROR: Map key mismatch"
  65.             else:
  66.                 print "ERROR: Map file missing mappings"           
  67.         if len(self.mx)==0 or len(self.my)==0:
  68.             print "Missing or invalid map file..."
  69.             self._genMap()
  70.  
  71.     def view(self):
  72.         self._update()
  73.         for i,s in enumerate(self.sides):
  74.             cv2.imshow(s+" raw",self.img_raw[s])
  75.             cv2.imshow(s+" rectified",self.img_rectified[s])
  76.            
  77.         cv2.imshow('disparity',self.img_disparity)
  78.         cv2.waitKey()
  79.         cv2.destroyAllWindows()
  80.    
  81.     def _update(self):
  82.         self._poll()
  83.         self._genRectified()
  84.         self._genDisparity()
  85.    
  86.     #retrieves data from Leap  
  87.     def _poll(self):
  88.         f = self.controller.frame()
  89.         if not f.is_valid:
  90.             print "ERROR: invalid Leap frame"
  91.             return
  92.         imgs = f.images
  93.         for i,s in enumerate(self.sides):
  94.             self.img_leap[s] = imgs[i]
  95.             self.img_raw[s] = self.convertCV(self.img_leap[s])
  96.  
  97.     def _genDisparity(self):
  98.         self.img_disparity = self.getDisparity(self.img_rectified["left"],self.img_rectified["right"]) 
  99.         self.img_disparity = cv2.medianBlur(self.img_disparity,3)
  100.  
  101.     def _genRectified(self):
  102.         for i,s in enumerate(self.sides):
  103.             self.img_rectified[s] = self.undistort(self.img_raw[s],self.mx[s],self.my[s])
  104.  
  105.     def _genMap(self):
  106.         for s in self.sides:
  107.             print "Generating map for "+s+"..."
  108.             self.mx[s] = (np.ones([self.height,self.width])*-1).astype('float32')
  109.             self.my[s] = (np.ones([self.height,self.width])*-1).astype('float32')
  110.  
  111.             if len(self.img_leap)==0 or self.img_leap[s] is None:
  112.                 self._poll()
  113.             for iy in xrange(self.height):
  114.                 for ix in xrange(self.width):
  115.                     v_input = Leap.Vector(float(ix)/self.width, float(iy)/self.height,0)
  116.                     v_input.x = (v_input.x-self.img_leap[s].ray_offset_x) / self.img_leap[s].ray_scale_x
  117.                     v_input.y = (v_input.y-self.img_leap[s].ray_offset_y) / self.img_leap[s].ray_scale_y
  118.                     ip = self.img_leap[s].warp(v_input)
  119.                     if ip.x>=0 and ip.x<self.width and ip.y>=0 and ip.y<self.height:
  120.                         self.mx[s][iy,ix] = int(ip.x)
  121.                         self.my[s][iy,ix] = int(ip.y)
  122.                     else:
  123.                         self.mx[s][iy,ix] = -1
  124.                         self.my[s][iy,ix] = -1
  125.     def _saveMap(self,fileName="LeapMaps.npy"):
  126.         if len(self.mx)==0 or len(self.my)==0:
  127.             self._genMap()
  128.         np.save(fileName,{"mx":self.mx,"my":self.my})
  129.        
  130.     def getPointCloud(self,disp_img):
  131.         if len(disp_img.shape)==3:
  132.             disp_img = cv2.cvtColor(disp_img,cv2.COLOR_BGR2GRAY)    #single channel only for point clouds!
  133.         pc = np.reshape(cv2.reprojectImageTo3D(disp_img,self.d2d),(self.width*self.height,3))
  134.         p_thresh = 20
  135.         pc = pc[np.logical_and(np.logical_and(abs(pc[:,0])<p_thresh,abs(pc[:,1])<p_thresh),abs(pc[:,2])<p_thresh),:]
  136.         return pc
  137.     def getDisparity(self,cv_imgL,cv_imgR):
  138.         disparity = cv.CreateMat(cv_imgL.shape[0],cv_imgL.shape[1],cv.CV_32F)
  139.         disparity_visual = cv.CreateMat(cv_imgL.shape[0],cv_imgL.shape[1],cv.CV_8U)
  140.  
  141.         #generate former cv images from cv2:
  142.         imgL = cv.fromarray(cv2.cvtColor(cv_imgL,cv2.COLOR_BGR2GRAY))
  143.         imgR = cv.fromarray(cv2.cvtColor(cv_imgR,cv2.COLOR_BGR2GRAY))
  144.         cv.FindStereoCorrespondenceBM(imgL,imgR,disparity,self.sbm)
  145.         cv.Normalize(disparity,disparity_visual,0,255,cv.CV_MINMAX)
  146.         return cv2.cvtColor(np.array(disparity_visual),cv2.COLOR_GRAY2BGR)
  147.     def getDisparityBasic(self,cv_imgL,cv_imgR):
  148.         return self.bm.compute(cv_imgL,cv_imgR)
  149.  
  150.     def undistort(self,cv_img,mx,my):
  151.         return cv2.remap(cv_img,mx,my,cv2.INTER_LINEAR)
  152.     def leap_to_array(self,leap_img):
  153.         imdata = ctypes.cast(leap_img.data.cast().__long__(), ctypes.POINTER(leap_img.width*leap_img.height*ctypes.c_ubyte)).contents
  154.         return np.reshape(np.array(imdata,'int'),(leap_img.height,leap_img.width))
  155.  
  156.     def convertPIL(self,leap_img):
  157.         return Image.fromarray(self.leap_to_array(leap_img)).convert("RGB")
  158.     def convertCV(self,leap_img):
  159.         pil_img = self.convertPIL(leap_img)
  160.         cv_img = np.array(pil_img)[:,:,::-1].copy()     #still has three channels
  161.         return cv_img
  162.  
  163. if __name__=="__main__":
  164.     lb = LeapBridge(640,240,'LeapMaps.npy')
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement