示例#1
0
def _isSingleStrokeArrow(stroke):
    "Input: Single stroke for evaluation. Returns a tuple of points (tip, tail) if the stroke is an arrow, (None, None) otherwise"
    logger.debug("stroke len %d", stroke.length() )
    if len(stroke.Points) < 10:
        return (None, None)# too small to be arrow

    norm_len = len(stroke.Points)
    points = GeomUtils.strokeNormalizeSpacing( stroke, numpoints=norm_len).Points

    points.reverse() # start from end
    # find the first 90 degree turn in the stroke
    orilist = GeomUtils.strokeLineSegOrientations( Stroke(points) )
    logger.debug("stroke ori %s", str(orilist) )
    prev = None
    i = 0
    for i,ori in enumerate(orilist):
        if prev is None:
            prev = ori
            continue
        if GeomUtils.angleDiff(ori,prev)>90: break  # found the first turn at index i
    first_corner = i
    # now we know the scale of the arrow head if there is one
    # if the first corner is more than 1/4 of the way from the end of the stroke
    if first_corner > norm_len/5:
        return (None, None) # scale is wrong for an arrowhead        

    tail = stroke.Points[0] # first of the original points
    tip = points[i] # reverse point

    # create a list of the monoticity of all substrokes from the first corner to some dist after
    m_list = [ GeomUtils.strokeMonotonicity(Stroke(points[first_corner:x])) for x in range(first_corner+2,first_corner*3) ]
    if len(m_list) == 0:
        return (None, None)
    m_min = min(m_list) 
    logger.debug("stroke mon (%f)", m_min )
    if m_min>0.65:
        return (None, None)# too monotonic after the first corner, need to double back
    
    return (tip, tail)
示例#2
0
def _isSingleStrokeArrow(stroke):
    "Input: Single stroke for evaluation. Returns a tuple of points (tip, tail) if the stroke is an arrow, (None, None) otherwise"
    if len(stroke.Points) < 10:
        logger.debug("Not a single-stroke arrow: stroke too short")
        return (None, None)# too small to be arrow

    """
    #Starting code for line curvature classification
    #points = GeomUtils.strokeNormalizeSpacing( stroke, numpoints=50).Points
    for gran in range(1, 10):
        norm_len = max(len(stroke.Points) / gran, 5)
        points = GeomUtils.strokeNormalizeSpacing( stroke, numpoints=norm_len).Points

        points.reverse() # start from end
        # find the first 90 degree turn in the stroke
        curvatures = GeomUtils.strokeGetPointsCurvature( Stroke(points) )
        gran = 0.1
        for idx, ori in enumerate(curvatures):
            print "%s:\t|" % (idx),
            quantity = ori 
            while quantity > 0:
                quantity -= gran
                print "X",
            print "\t\t%s" % (ori)
        print "_______________________________"
        print "Max:%s, Avg%s" % (max(curvatures), sum(curvatures)/float(len(curvatures)))
        print "_______________________________"
    #/EndCurvature classification
    """

    norm_len = max(len(stroke.Points) / 10, 15)
    points = GeomUtils.strokeNormalizeSpacing( stroke, numpoints=norm_len).Points
    orilist = GeomUtils.strokeLineSegOrientations( Stroke(points) )


        
    
    #logger.debug("stroke ori %s", str(orilist) )
    prev = None
    i = 0
    for i,ori in enumerate(orilist):
        if prev is None:
            prev = ori
            continue
        if GeomUtils.angleDiff(ori,prev)>90: break  # found the first turn at index i
    first_corner = i
    # now we know the scale of the arrow head if there is one
    # if the first corner is more than 1/4 of the way from the end of the stroke
    if first_corner > norm_len/5:
        logger.debug("Not a ss arrow: First right angle too far from endpoint")
        return (None, None) # scale is wrong for an arrowhead        

    tail = stroke.Points[0] # first of the original points
    tip = points[i] # reverse point

    # create a list of the monoticity of all substrokes from the first corner to some dist after
    m_list = [ GeomUtils.strokeMonotonicity(Stroke(points[first_corner:x])) for x in range(first_corner+2,first_corner*3) ]
    if len(m_list) == 0:
        logger.debug("Not a ss arrow: Stroke monotonicity list zero length")
        return (None, None)
    m_min = min(m_list) 
    #logger.debug("stroke mon (%f)", m_min )
    if m_min>0.65:
        logger.debug("Not a ss arrow: Stroke too monotonic")
        return (None, None)# too monotonic after the first corner, need to double back
    
    logger.debug("Single Stroke Arrow found!")
    return (tip, tail)