def downsampleShape(shape): #downsample user-drawn shape so appropriate size for shapeLearner numPointsInShape = len(shape) / 2 x_shape = shape[0:numPointsInShape] y_shape = shape[numPointsInShape:] if isinstance(x_shape, numpy.ndarray): #convert arrays to lists for interp1d x_shape = (x_shape.T).tolist()[0] y_shape = (y_shape.T).tolist()[0] #make shape have the same number of points as the shape_modeler t_current = numpy.linspace(0, 1, numPointsInShape) t_desired = numpy.linspace(0, 1, NUMPOINTS_SHAPEMODELER) f = interpolate.interp1d(t_current, x_shape, kind='linear') x_shape = f(t_desired) f = interpolate.interp1d(t_current, y_shape, kind='linear') y_shape = f(t_desired) shape = [] shape[0:NUMPOINTS_SHAPEMODELER] = x_shape shape[NUMPOINTS_SHAPEMODELER:] = y_shape shape = ShapeModeler.normaliseShapeHeight(numpy.array(shape)) shape = numpy.reshape( shape, (-1, 1)) #explicitly make it 2D array with only one column return shape
def downsampleShape(shape): #downsample user-drawn shape so appropriate size for shapeLearner numPointsInShape = len(shape)/2 x_shape = shape[0:numPointsInShape] y_shape = shape[numPointsInShape:] if isinstance(x_shape,numpy.ndarray): #convert arrays to lists for interp1d x_shape = (x_shape.T).tolist()[0] y_shape = (y_shape.T).tolist()[0] #make shape have the same number of points as the shape_modeler t_current = numpy.linspace(0, 1, numPointsInShape) t_desired = numpy.linspace(0, 1, NUMPOINTS_SHAPEMODELER) f = interpolate.interp1d(t_current, x_shape, kind='linear') x_shape = f(t_desired) f = interpolate.interp1d(t_current, y_shape, kind='linear') y_shape = f(t_desired) shape = [] shape[0:NUMPOINTS_SHAPEMODELER] = x_shape shape[NUMPOINTS_SHAPEMODELER:] = y_shape shape = ShapeModeler.normaliseShapeHeight(numpy.array(shape)) shape = numpy.reshape(shape, (-1, 1)) #explicitly make it 2D array with only one column return shape
def shapeWord(word, downsampling_factor=None): """Assembles the paths of the letters of the given word into a global shape. :param word: a ShapeLearnerManager instance for the current word :param downsampling_factor: if provided, the final shape of each letter is (independantly) resampled to (nb_pts / downsampling_factor) points :returns: a ShapedWord that contains the path of individual letters """ paths = [] offset_x = offset_y = 0 for shape in word.shapesOfCurrentCollection(): path = [] w, ah, bh = LETTER_BOUNDINGBOXES[shape.shapeType] scale_factor = ah + bh # height ratio between this letter and a 'a' #no need for a width scaling since the shape are only *height*-normalized (cf below) glyph = ShapeModeler.normaliseShapeHeight(shape.path) numPointsInShape = len(glyph)/2 x_shape = glyph[0:numPointsInShape].flatten().tolist() y_shape = glyph[numPointsInShape:].flatten().tolist() if offset_x != 0 or offset_y != 0: # not the first letter offset_x -= x_shape[0] * SIZESCALE_WIDTH * scale_factor offset_y += y_shape[0] * SIZESCALE_HEIGHT * scale_factor for i in range(numPointsInShape): x = x_shape[i] * SIZESCALE_WIDTH * scale_factor y = -y_shape[i] * SIZESCALE_HEIGHT * scale_factor x += offset_x y += offset_y path.append((x,y)) paths.append(path) if shape.shapeType in ['i', 'j']: # HACK: waiting for proper multi-stroke learning logger.info("Adding a 'dot' to the letter") dot_path = [ (offset_x + 0.0 * SIZESCALE_WIDTH * scale_factor, offset_y + 0.8 * SIZESCALE_WIDTH * scale_factor), (offset_x + 0.05 * SIZESCALE_WIDTH * scale_factor, offset_y + 0.85 * SIZESCALE_HEIGHT * scale_factor), (offset_x + 0.0 * SIZESCALE_WIDTH * scale_factor, offset_y + 0.85 * SIZESCALE_HEIGHT * scale_factor), (offset_x + 0.0 * SIZESCALE_WIDTH * scale_factor, offset_y + 0.8 * SIZESCALE_HEIGHT * scale_factor) ] paths.append(dot_path) # connect the letter to the ending point of the previous one offset_x = path[-1][0] offset_y = path[-1][1] return ShapedWord(word.currentCollection, paths)
def downsampleShape(shape): #downsample user-drawn shape so appropriate size for shapeLearner numPointsInShape = len(shape)/2; x_shape = shape[0:numPointsInShape]; y_shape = shape[numPointsInShape:]; if isinstance(x_shape,numpy.ndarray): #convert arrays to lists for interp1d x_shape = (x_shape.T).tolist()[0]; y_shape = (y_shape.T).tolist()[0]; #make shape have the same number of points as the shape_modeler t_current = numpy.linspace(0, 1, numPointsInShape); t_desired = numpy.linspace(0, 1, numPoints_shapeModeler); f = interpolate.interp1d(t_current, x_shape, kind='cubic'); x_shape = f(t_desired); f = interpolate.interp1d(t_current, y_shape, kind='cubic'); y_shape = f(t_desired); shape = []; shape[0:numPoints_shapeModeler] = x_shape; shape[numPoints_shapeModeler:] = y_shape; shape = ShapeModeler.normaliseShapeHeight(numpy.array(shape)); shape = numpy.reshape(shape, (-1, 1)); #explicitly make it 2D array with only one column return shape
def on_touch_up(self, touch): global userShape wordToLearn = wordManager.getCurrentCollection() if len(userShape) < 5: closeFigures(figuresToClose = range(1,len(wordToLearn)+1)) wordToLearn = raw_input("Next word:\n") newWord(wordToLearn) userInputCapture.display_grid(numColumns = len(wordToLearn)) else: userShape = downsampleShape(userShape,numPoints_shapeModeler,xyxyFormat=True) shapeCentre = ShapeModeler.getShapeCentre(userShape) for i in range(len(wordToLearn)): if(shapeCentre[0] > (self.width/len(wordToLearn))*i): shapeIndex_demoFor = i shapeType = wordManager.shapeAtIndexInCurrentCollection(shapeIndex_demoFor) print('Received demo for letter ' + shapeType) userShape = numpy.reshape(userShape, (-1, 1)); #explicitly make it 2D array with only one column userShape = ShapeModeler.normaliseShapeHeight(numpy.array(userShape)) shape = wordManager.respondToDemonstration(shapeType, userShape) userShape = [] self.canvas.remove(touch.ud['line']) if shape != -1: showShape(shape, shapeIndex_demoFor)
def make_traj_msg(shape, shapeCentre, headerString, startTime, downsample, deltaT): if(startTime!=t0): penUpToFirst = True; else: penUpToFirst = False; traj = Path(); traj.header.frame_id = FRAME#headerString; traj.header.stamp = rospy.Time.now()+rospy.Duration(delayBeforeExecuting); shape = ShapeModeler.normaliseShapeHeight(shape); numPointsInShape_orig = len(shape)/2; x_shape = shape[0:numPointsInShape_orig]; y_shape = shape[numPointsInShape_orig:]; if(downsample): #make shape have the appropriate number of points t_current = numpy.linspace(0, 1, numPointsInShape_orig); t_desired = numpy.linspace(0, 1, numDesiredShapePoints); f = interpolate.interp1d(t_current, x_shape[:,0], kind='cubic'); x_shape = f(t_desired); f = interpolate.interp1d(t_current, y_shape[:,0], kind='cubic'); y_shape = f(t_desired); numPointsInShape = len(x_shape); downsampleFactor = numPointsInShape_orig/float(numPointsInShape); else: numPointsInShape = numPointsInShape_orig; for i in range(numPointsInShape): point = PoseStamped(); point.pose.position.x = x_shape[i]*sizeScale_width; point.pose.position.y = -y_shape[i]*sizeScale_height; point.pose.position.x+= + shapeCentre[0]; point.pose.position.y+= + shapeCentre[1]; point.header.frame_id = FRAME; point.header.stamp = rospy.Time(startTime+i*deltaT+t0); #@TODO allow for variable time between points for now if(penUpToFirst and i==0): point.header.seq = 1; traj.poses.append(deepcopy(point)); if(downsample): return traj, downsampleFactor else: return traj
def on_touch_up(self, touch): global userShape touch.ud['line'].points userShape = downsampleShape(userShape,numPoints_shapeModeler,xyxyFormat=True) shapeCentre = ShapeModeler.getShapeCentre(userShape) shapeType = letter print('Received reference for letter ' + shapeType) userShape = numpy.reshape(userShape, (-1, 1)); userShape = ShapeModeler.normaliseShapeHeight(numpy.array(userShape)) filename = dataSetFile print('saving in'+filename) # scan the dataset : lines = [] try: with open(filename, 'r') as f: lines.append(f.readline()) nb_samples = int(lines[0].strip()) for i in range(nb_samples+1): lines.append(f.readline()) except IOError: raise RuntimeError("no reading permission for file"+filename) nb_samples+=1 # past the dataset : try: with open(filename, 'w') as f: f.write('nb_sample:\n') f.write('%i\n'%nb_samples) f.write('nb_pts:\n') f.write('70\n') f.write('ref:\n') f.write(' '.join(map(str,userShape.T[0]))+'\n') f.write('...\n') for i in range(nb_samples-1): f.write(lines[i+2]) except IOError: raise RuntimeError("no writing permission for file"+filename) userShape = [] self.canvas.remove(touch.ud['line'])
def respondToDemonstration(self, shape): """ Algo: 1) takes the shape of the demonstration 2) takes the curent learned shape 3) re-performs PCA taking in account the domonstrated shape, then obtains a new space with new eigen vectors 4) projects demonstrated and learned shapes into this new space and gets their new parameters 5) updates the learned parameters as the algebric middle between demonstrated parameters and curent learned parameters. """ demo_shape = ShapeModeler.normaliseShapeHeight(numpy.array(shape)) # take the shape corresponding to the curent learned parameters in the curent space learned_shape = self.shapeModeler.makeShape(self.params) # add the demo shape to the matrix for PCA and re-compute reference-shape params self.shapeModeler.extendDataMat(demo_shape) ref_params = self.shapeModeler.refParams # re-compute parameters of the learned shape and the demo shape in the new PCA-space params_demo, _ = self.shapeModeler.decomposeShape(demo_shape) self.params, _ = self.shapeModeler.decomposeShape(learned_shape) # learning : diff_params = params_demo - self.params self.params += diff_params/2 #go towards the demonstrated shape #self.params[self.paramsToVary[0]-1] = params_demo[self.paramsToVary[0]-1] #ONLY USE FIRST PARAM #store it as an attempt (this isn't super appropriate but whatever) if (self.doGroupwiseComparison): newParamValue = self.params[ self.paramsToVary[0] - 1, 0] #USE ONLY FIRST PARAM FOR SELF-LEARNING ALGORITHM ATM #print('Demo params: '+str(self.params)) bisect.insort(self.params_sorted, newParamValue) self.shapeToParamsMapping.append(self.params) #self.respondToFeedback(len(self.params_sorted)-3) # give feedback of most recent shape so bounds modify return self.shapeModeler.makeShape(self.params), self.params, params_demo
def on_touch_up(self, touch): global userShape word = [] total_score = 0 rest = userShape scan = downsampleShape(userShape, numPoints_shapeModeler, xyxyFormat=True) shapeCentre = ShapeModeler.getShapeCentre(scan) scan = np.reshape(scan, (-1, 1)) #explicitly make it 2D array with only one column scan = ShapeModeler.normaliseShapeHeight(np.array(scan)) scores = np.array(separator(scan)) scores = scores / np.max(scores) scores = scores * np.abs(scores) scores[scores < 0.1] = 0 indices = np.array(range(len(scores))) sep = indices[scores > 0] #print zip(sep[:-1],sep[1:]) for i in sep: x = scan[i] if len(scan[scan[i:numPoints_shapeModeler] < x]) > 0: scores[i] = 0 if len(scan[scan[:i] > x]) > 0: scores[i] = 0 u = True while u: u = False sep = indices[scores > 0] for i, j in zip(sep[:-1], sep[1:]): if j - i < 5: u = True if scores[i] > scores[j]: scores[j] = 0 else: scores[i] = 0 plt.clf() ShapeModeler.showShape_score(scan, scores) word = [] sep = indices[scores > 0] for i, j in zip(sep[:-1], sep[1:]): shape = scan[i:j + 1].T.tolist()[0] + scan[numPoints_shapeModeler + i:numPoints_shapeModeler + j + 1].T.tolist()[0] shape = downsampleShape(shape, numPoints_shapeModeler) shape = np.reshape(shape, (-1, 1)) shape = ShapeModeler.normaliseShapeHeight(np.array(shape)) best_letter = '?' errors = {} values = [] for letter in abc: space = spaces[letter] error = space.getMinDist(shape) errors[letter] = error values.append(error) best_letter = min(errors, key=errors.get) word.append(best_letter) print 'found ' + str(word) print '######################' print '' userShape = [] self.canvas.remove(touch.ud['line'])
def on_touch_up(self, touch): global userShape word = [] total_score =0 rest = userShape scan = downsampleShape(userShape, numPoints_shapeModeler,xyxyFormat=True) shapeCentre = ShapeModeler.getShapeCentre(scan) scan = np.reshape(scan, (-1, 1)); #explicitly make it 2D array with only one column scan = ShapeModeler.normaliseShapeHeight(np.array(scan)) scores = np.array(separator(scan)) scores = scores/np.max(scores) scores = scores*np.abs(scores) scores[scores<0.1]=0 indices = np.array(range(len(scores))) sep = indices[scores>0] #print zip(sep[:-1],sep[1:]) for i in sep: x = scan[i] if len(scan[scan[i:numPoints_shapeModeler]<x])>0: scores[i]=0 if len(scan[scan[:i]>x])>0: scores[i]=0 u = True while u: u = False sep = indices[scores>0] for i,j in zip(sep[:-1],sep[1:]): if j-i<5: u = True if scores[i]>scores[j]: scores[j] = 0 else: scores[i] = 0 plt.clf() ShapeModeler.showShape_score(scan,scores) word = [] sep = indices[scores>0] for i,j in zip(sep[:-1],sep[1:]): shape = scan[i:j+1].T.tolist()[0] + scan[numPoints_shapeModeler+i:numPoints_shapeModeler+j+1].T.tolist()[0] shape = downsampleShape(shape, numPoints_shapeModeler) shape = np.reshape(shape,(-1,1)) shape = ShapeModeler.normaliseShapeHeight(np.array(shape)) best_letter = '?' errors = {} values = [] for letter in abc: space = spaces[letter] error = space.getMinDist(shape) errors[letter] = error values.append(error) best_letter = min(errors, key = errors.get) word.append(best_letter) print 'found ' + str(word) print '######################' print '' userShape = [] self.canvas.remove(touch.ud['line'])