def _isArrowHead(stroke, matcher): numPts = 11 sNorm = GeomUtils.strokeNormalizeSpacing(stroke, numpoints = numPts) curvatures = GeomUtils.strokeGetPointsCurvature(sNorm) maxCurv = max(curvatures) maxCurvIdx = curvatures.index(maxCurv) #Make sure the max curvature is roughly in the middle of the stroke before even bothering # with more complicated checks if maxCurvIdx > (numPts / 5.0) and maxCurvIdx < ( 4 * numPts / 5.0): strkLen = GeomUtils.strokeLength(stroke) arrowHeadStroke = GeomUtils.strokeNormalizeSpacing(Stroke([sNorm.Points[0], sNorm.Points[maxCurvIdx], sNorm.Points[-1]]), numpoints = strkLen) #What would the approximated arrowhead look like? origStroke = GeomUtils.strokeNormalizeSpacing(stroke, numpoints = strkLen) approxAcc = GeomUtils.strokeDTWDist(sNorm, arrowHeadStroke) #logger.debug("Stroke approximates arrowhead with %s accuracy" % (approxAcc)) return approxAcc < 500000 #_isArrowHead_Template(stroke, matcher) or _isArrowHead_Template(Stroke(list(reversed(stroke.Points))), matcher) return False
def tagBox(self, stroke): endPointDistPct = 0.10 #How close (as % of length) the points have to be to each other boxApproxThresh = 50000 #The DTW distance between the stroke and how it best fits a box stkLen = GeomUtils.strokeLength(stroke) ep1, ep2 = stroke.Points[0], stroke.Points[-1] epDistSqr = GeomUtils.pointDistanceSquared(ep1.X, ep1.Y, ep2.X, ep2.Y) if epDistSqr > (endPointDistPct * stkLen) ** 2: print "Endpoints aren't close enough to be a box" return overshoot = max(1, len(stroke.Points)/10) norm_stroke = GeomUtils.strokeSmooth(GeomUtils.strokeNormalizeSpacing(Stroke(stroke.Points + stroke.Points[0:overshoot]), numpoints = 70)) #D.strokeCurvatureHistogram(norm_stroke) curvatures = GeomUtils.strokeGetPointsCurvature(norm_stroke) corners = set([]) curvatures_cpy = list(curvatures) while len(corners) < 4: crnr_idx = curvatures_cpy.index(max(curvatures_cpy)) crnr = curvatures_cpy[crnr_idx] * 57.295 for nBor in range(crnr_idx -2, crnr_idx + 3): if nBor < len(curvatures_cpy) and nBor > 0: curvatures_cpy[nBor] = 0 if crnr > 0: #30 and crnr < 150: #Have a curvature, and we haven't already classified its immed neighbors as a corner corners.add(crnr_idx) else: break if len(corners) != 4: return else: c_list = [norm_stroke.Points[c_idx] for c_idx in sorted(list(corners))] cornerStroke = Stroke(c_list + c_list[:2]) boxStroke = GeomUtils.strokeNormalizeSpacing(Stroke(c_list + [c_list[0]])) origStroke = GeomUtils.strokeNormalizeSpacing(Stroke(stroke.Points + [stroke.Points[0]])) approxAcc = GeomUtils.strokeDTWDist(boxStroke, origStroke) print "Box approximates original with %s accuracy" % (approxAcc) if approxAcc < boxApproxThresh: self.getBoard().AnnotateStrokes([stroke], BoxAnnotation(c_list))