image3d.py
Go to the documentation of this file.
00001 import roslib; roslib.load_manifest('hrl_lib')
00002 
00003 import cv
00004 import numpy as np
00005 import hrl_lib.tf_utils as tfu
00006 import hrl_opencv.blob as blob
00007 import copy
00008 import pdb
00009 
00010 ##
00011 # calculate normal to a group of points
00012 # @param points3d 3d points 3xn matrix
00013 # @param p direction to return normals wrt
00014 def calc_normal(points3d, p=np.matrix([-1,0,0.]).T):
00015     #pdb.set_trace()
00016     u, s, vh = np.linalg.svd(np.cov(points3d))
00017     u = np.matrix(u)
00018 
00019     # Pick normal
00020     if (u[:,2].T * p)[0,0] < 0:
00021         normal = -u[:,2]
00022     else:
00023         normal = u[:,2]
00024     return normal
00025 
00026 ##
00027 # give indices of 2d points that are in the image frame
00028 #
00029 # @param points 2xn matrix of 2d points
00030 # @param cal_obj calibration object
00031 def indices_of_points_in_frame(points, cal_obj):
00032     valid_indices = np.where(np.multiply(np.multiply(points[0,:] > 0, points[0,:] < cal_obj.w-.6),
00033                                          np.multiply(points[1,:] > 0, points[1,:] < cal_obj.h-.6)))[1].A1
00034     return valid_indices
00035 
00036 
00037 ##
00038 # Given a 2d location and a window size, cut out a square of intensity values, 
00039 # returns (winsize*winsize)x1 array in range [0,1] just use local template image
00040 #
00041 # @param location
00042 # @param bw_image
00043 # @param winsize
00044 # @param resize_to
00045 # @param flatten whether to return a flat 1 column mat or the 3d matrix of pixels
00046 def local_window(location, bw_image, winsize, resize_to=None, flatten=True):
00047     loc = np.matrix(np.round(location), dtype='int')
00048     start = loc - winsize
00049     patch_size = winsize*2+1
00050     img_width = bw_image.shape[1]
00051     img_height = bw_image.shape[0]
00052 
00053     r = blob.Rect(start[0,0], start[1,0], patch_size, patch_size).keep_inside(0, img_width-1, 0, img_height-1) #640, 480
00054     if r.width < patch_size or r.height < patch_size:
00055         return None
00056     else:
00057         #pdb.set_trace()
00058         #subrect_cpy = np.zeros((subrect.shape[0], subrect.shape[1], subrect.shape[2]), dtype='uint8')
00059         #cv.Copy(cv.fromarray(subrect), cv.fromarray(subrect_cpy))
00060         subrect = bw_image[r.y:r.y+r.height, r.x:r.x+r.width, :]
00061         #subrect_cpy = np.array(copy.copy(subrect.tolist()), dtype='uint8')
00062         #subrect = subrect_cpy
00063 
00064         if resize_to != None:
00065            rescaled = np.zeros((resize_to*2+1, resize_to*2+1, subrect.shape[2]), dtype='uint8')
00066            cv.Resize(cv.fromarray(subrect), cv.fromarray(rescaled), cv.CV_INTER_LINEAR)
00067            subrect = rescaled
00068 
00069         if flatten:
00070             #try:
00071             #    subrect = np.array(subrect.tolist(), copy=True, order='C')
00072             #except TypeError, e:
00073             #    print 'typeerror:', e
00074             #    pdb.set_trace()
00075             #    print 'error'
00076             try:
00077                 intensity = np.matrix(np.reshape(subrect, (subrect.shape[0]*subrect.shape[1]*subrect.shape[2], 1))) / 255.
00078             except TypeError, e:
00079                 #print 'TypeError:', e, 'retrying anyway?'
00080                 intensity = np.matrix(np.reshape(subrect, (subrect.shape[0]*subrect.shape[1]*subrect.shape[2], 1))) / 255.
00081                 #print intensity.shape
00082             #try:
00083             #    intensity = np.matrix(subrect.flatten()) / 255.
00084             #except TypeError, e:
00085             #    print 'TypeError:', e, '!!!!!!!!!!!!!!!!!!!!!!!!!!!'
00086             #    return None
00087         else:
00088             intensity = subrect
00089 
00090         return intensity
00091 
00092 
00093 ##
00094 # Combines a point cloud with an intensity image
00095 #
00096 # @param points_in_laser_frame 3d points in laser frame
00097 # @param image numpy image (ex: np.asarray(cvimage))
00098 # @param cal_obj camera calibration object
00099 # @return 3xn int matrix of 3d points that are visible in the camera's frame
00100 # @return 3xn int matrix of rgb values of those points in range [0,1]
00101 def combine_scan_and_image_laser_frame(points_in_laser_frame, image_T_laser, image, cal_obj):
00102     points_in_image_frame = tfu.transform_points(image_T_laser, points_in_laser_frame)
00103     return combine_scan_and_image(points_in_image_frame, image, cal_obj)
00104 
00105 ##
00106 # Combines a point cloud with an intensity image
00107 #
00108 # @param points_in_image_frame 3d points in image frame
00109 # @param imagea numpy image (ex: np.asarray(cvimage))
00110 # @param cal_obj camera calibration object
00111 # @return 3xn int matrix of 3d points that are visible in the camera's frame
00112 # @return 3xn int matrix of rgb values of those points in range [0,1]
00113 def combine_scan_and_image(points_in_image_frame, imagea, cal_obj):
00114     p2d = cal_obj.project(points_in_image_frame)
00115     valid_indicies = indices_of_points_in_frame(p2d, cal_obj)
00116 
00117     vp2d = p2d[:, valid_indicies]
00118     vp2d = np.matrix(np.round(vp2d), dtype='int')
00119     #vpoints = points_in_laser_frame[:, valid_indicies]
00120     vpoints = points_in_image_frame[:, valid_indicies]
00121 
00122     # imagea = np.asarray(image)
00123     intensity_channels = imagea[vp2d[1,:].A1, vp2d[0,:].A1, :]
00124     #pdb.set_trace()
00125     return vpoints, (np.matrix(intensity_channels).T / 255.), vp2d
00126 
00127 ##
00128 # Given a group of points, select the ones within rectangular volume
00129 #
00130 # @param center
00131 # @param w
00132 # @param h
00133 # @param depth
00134 # @param points 3xn mat
00135 def select_rect(center, w, h, depth, points):
00136     limits = [[center[0,0]-w, center[0,0]+w], 
00137                  [center[1,0]-h, center[1,0]+h], 
00138                  [center[2,0]-depth, center[2,0]+depth]]
00139     return select_volume(limits, points), limits
00140 
00141 
00142 ##
00143 # Given a group of points and rectangular limits return points within limits
00144 #
00145 # @param limits [[xmin, xmax], [ymin, ymax], [...]]
00146 # @param points 3xn mat
00147 def select_volume(limits, points):
00148     xlim, ylim, zlim = limits
00149     xlim_sat = np.multiply(points[0, :] > xlim[0], points[0, :] < xlim[1])
00150     ylim_sat = np.multiply(points[1, :] > ylim[0], points[1, :] < ylim[1])
00151     zlim_sat = np.multiply(points[2, :] > zlim[0], points[2, :] < zlim[1])
00152     selected = np.multiply(np.multiply(xlim_sat, ylim_sat), zlim_sat)
00153     if np.sum(selected) <= 0:
00154         return None
00155     return points[:, np.where(selected)[1].A1]
00156 
00157     #points_x   = points[:, np.where(np.multiply(points[0, :] > xlim[0], points[0, :] < xlim[1]))[1].A1]
00158     #points_xy  = points_x[:, np.where(np.multiply(points_x[1, :] > ylim[0], points_x[1, :] < ylim[1]))[1].A1]
00159     #points_xyz = points_xy[:, np.where(np.multiply(points_xy[2, :] > zlim[0], points_xy[2, :] < zlim[1]))[1].A1]
00160     #return points_xyz
00161 
00162 


hrl_opencv
Author(s): Hai Nguyen, Advait Jain (Healthcare Robotics Lab, Georgia Tech)
autogenerated on Wed Nov 27 2013 11:36:49