Esempio n. 1
0
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
Esempio n. 3
0
    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
Esempio n. 5
0
    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'])
Esempio n. 8
0
    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
Esempio n. 9
0
    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'])
Esempio n. 10
0
    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'])