def find_wrist(self, hull_geo): """ Given as geo the convex_hull, in relation to its center ----------- there are more points above center (open palm...) than below 1. Find the start and end indices defining the wrist, which is an almost horizontal line (deltaY < 5, deltaX > 50) + correct for being the longest line (if three points) one point... correction not fool proof :param self: :param hull_geo: :return: Point, Point (NONE if not found) """ #curve_pts = Curve.convert_np_array2curve(hull_geo.curve) curve_pts = Curve(hull_geo.curve) wrist_hull_index1, wrist_hull_index2 = Curve.indices_of_lowest_horizontal( curve_pts, hull_geo.center, Hand.WRIST_DELTA_Y) # does this work? CK if Hand.PREVIOUS_PROMPT is None and wrist_hull_index1 != -1: Hand.PREVIOUS_PROMPT = self return curve_pts[wrist_hull_index1], curve_pts[wrist_hull_index2]
def find_defect_pts(curve): """ in = are far of the curve in bw fingers defect points; out = are close to the curve (usually HULL) wrist and finger tips :param curve (contour) :return: Curve, Curve """ def format_defect_info(defect): f_s, f_e, f_f, fixpt_depth = defect # convexityDefects 4th element integer, 'fixpt_depth' fixed-point approximation # (with 8 fractional bits) of the distance bw farthest contour point and the hull. # - to get floating-point value of depth --> fixpt_depth/256.0 return Point(curve[f_s][0]), Point(curve[f_e][0]), Point(curve[f_f][0]), \ fixpt_depth / 256.0 # hull_indices (not the earlier hull): # returnPoints is False so that indices (not coord) are returned hull_indices = cv2.convexHull(curve, clockwise=False, returnPoints=False) defects = cv2.convexityDefects(curve, hull_indices) inside_defect_pts = [] outside_defect_pts = [] for i in range(defects.shape[0]): start, end, far, depth = format_defect_info(defects[i, 0]) # print "depth", depth if depth > 2: inside_defect_pts += [far] else: outside_defect_pts += [far] return Curve(inside_defect_pts), Curve(outside_defect_pts)
def get_defect_pts(fingers): all_defects = [] for idx in range(Finger.THUMB, len(fingers)): first, second = fingers[idx].palm_pt1, fingers[idx].palm_pt2, if first not in all_defects: all_defects += [first] if second not in all_defects: all_defects += [second] return Curve(all_defects)
def create_poly_curve(self, defect_pts, start_pt, next_pt, extreme_pt): if self.g_type == constants.GEO_POLY: approx = Curve(self.curve) #print "length before", len(approx) # TODO: very small d for fist # TODO: FIX BUG self.pts_to_add = Curve.filter_different_pts(approx, defect_pts) # copy to display pts_to_add = Curve(self.pts_to_add) approx.insert_pts(pts_to_add) # orient curve wrt param points (wrist and thumb) #self.poly_curve = \ Geometry.align(approx, defect_pts, start_pt, next_pt, extreme_pt) self.poly_curve = approxukanT1/2t00
def are_geo_centers_distinct(onion): """ the centers with one off form a triangle (not true for Chris' hand) :param onion: :return: """ area = Curve.triangle_area([ onion[constants.GEO_HULL].center, onion[constants.GEO_POLY].center, onion[constants.GEO_BBOX].center ]) # print "area", area min_prop = onion[ constants. GEO_HULL].area / constants.GEO_CENTERS_AREA_PROMPT_GREATER max_prop = onion[ constants. GEO_HULL].area / constants.GEO_CENTERS_AREA_PROMPT_SMALLER # print "min", min_prop, "max", max_prop if max_prop > area > min_prop: # print area return True return False
def draw_thumb(poly): line = Curve([poly.center, self.thumb_point]) line.draw(image, constants.COLOR_GREEN, close=False, circle=True)
def remove_extra_points(self): """ :return: """ def in_between(def1, def2): if def2 - def1 == 2: return def1 + 1 # to widen the range -> most exterior point wanted # due to orientation, seems to be the first one for thumb, index, major elif digit_num < Finger.MAJOR: return def1 + 1 else: return def2 - 1 #defect here! ref = self.onion_geometry[constants.GEO_POLY].poly_curve defects_copy = Curve(self.in_defects) print "curve\n", ref if len(ref) >= Finger.PTS_LEN: # copy the wrist known to be three points new_curve = Curve(ref[:Finger.PTS_LEN]) #print "defects\n", defects, "\nnew_curve\n", new_curve idx = Finger.PTS_LEN #print "next points", defects_copy first_idx = ref.index(defects_copy[0]) defects_copy.remove(0) new_curve.append([ref[first_idx]]) digit_num = Finger.THUMB while first_idx != -1 and len(defects_copy) > 0: print "next points", defects_copy next_idx = ref.index(defects_copy[0]) print "pattern index", first_idx, next_idx if next_idx != -1: tip = in_between(first_idx, next_idx) print "pattern points ", ref[first_idx+1], ref[next_idx] new_curve.append([ref[tip], ref[next_idx]]) #insert tip and second defect defects_copy.remove(0) digit_num += 1 first_idx = next_idx self.onion_geometry[constants.GEO_POLY].poly_curve = new_curve
def get_finger_tips(fingers): all_tips = [] for idx in range(Finger.THUMB, len(fingers)): all_tips += [fingers[idx].tip] return Curve(all_tips)
def draw(self, image, color): Curve.draw_line(image, color, self.palm_pt1, self.tip) Curve.draw_line(image, color, self.palm_pt2, self.tip)