33from scipy .spatial import ConvexHull
44from scipy .ndimage import distance_transform_edt
55
6+ # These are empirical values, which were found by trial and error
67pixel_no_threshold = 200
78analyzed_region_distance = 38.25
89hand_radius_error = 1.9
@@ -25,17 +26,19 @@ def _display_result(self):
2526 # =============================================================================
2627 def _depth_img_hist (self ):
2728 # hist[0] = number of elements
28- # hist[1] = distance normalized to 255
29+ # hist[1] = distance normalized to 255 (this was done in notebook.py)
2930 counts , bins = np .histogram (self .depth_img .ravel (), 512 )
3031 hist = [counts , bins ]
32+
3133 start = 1
3234 while start < (len (hist [0 ]) - 2 ) and hist [0 ][start ] < pixel_no_threshold :
3335 start += 1
3436 bin_step = hist [1 ][start + 1 ] - hist [1 ][start ]
3537
3638 stop = int ((hist [1 ][start ] + analyzed_region_distance - hist [1 ][0 ]) / bin_step )
3739
38- self .stop_distance = hist [1 ][stop ]
40+ self .stop_distance = hist [1 ][stop ]
41+ # Analyze the pixel only if it is closer than a threshold
3942 self .binary_img = (self .depth_img < self .stop_distance ) * 1
4043
4144 # =============================================================================
@@ -45,6 +48,7 @@ def _detect_hand(self):
4548 props = measure .regionprops (labels )
4649 if len (props ) == 0 :
4750 raise Exception ("No object found." )
51+
4852 props .sort (key = lambda x : x .area , reverse = True )
4953 self .max_area = props [0 ]
5054 points = props [0 ].filled_image
@@ -55,8 +59,8 @@ def _detect_hand(self):
5559
5660 # Compute the distance of non-zero points (hand) to the nearest zero point (background)
5761 self .dist_map = distance_transform_edt (points )
62+ # Indices of hand center, i.e. the point farthest from the background
5863 self .hand_center = tuple (arr [0 ] for arr in np .where (self .dist_map == np .max (self .dist_map )))
59-
6064 self .radius = hand_radius_error * np .max (self .dist_map )
6165
6266 # =============================================================================
@@ -71,21 +75,22 @@ def _count_fingers(self):
7175 [vertices [- 1 ] - vertices [0 ]], axis = 0 )
7276
7377 # distance bw 2 consecutive vertices
78+ # In cdist variables the distance units are pixels
7479 cdist = np .sqrt (dist [:, 0 ] ** 2 + dist [:, 1 ] ** 2 )
7580
7681 # This is just some formula invented by me. It is not optimal.
77- # It is used to make cdist_threshold inversely proportional to distance_threshold ,
78- # while keeping it lower than 25
82+ # It is used to make cdist_threshold inversely proportional to stop_distance ,
83+ # while keeping it between 0 and 25
7984 cdist_threshold = np .sqrt (1 - self .stop_distance / 255 ) * 25
80- cdist = (cdist <= cdist_threshold ) * 1
85+ cdist_bin = (cdist <= cdist_threshold ) * 1
8186
8287 # Used to check whether a cdist smaller than the threshold
8388 # is following a cdist bigger than the threshold
84- cdist_diff = np .append (cdist [0 :len (cdist ) - 1 ] - cdist [1 :len (cdist )],
85- [cdist [- 1 ] - cdist [0 ]], axis = 0 )
89+ cdist_diff = np .append (cdist_bin [0 :len (cdist_bin ) - 1 ] - cdist_bin [1 :len (cdist_bin )],
90+ [cdist_bin [- 1 ] - cdist_bin [0 ]], axis = 0 )
8691
8792 # Indices of vertices which correspond to fingertips
88- dist_idx = np .where ((cdist_diff == - 1 ) | ((cdist_diff == 0 ) & (cdist == 0 )))
93+ dist_idx = np .where ((cdist_diff == - 1 ) | ((cdist_diff == 0 ) & (cdist_bin == 0 )))
8994 dist_idx = np .array (dist_idx ) + 1
9095 # dist_idx is a double list
9196 dist_idx = dist_idx [0 ]
@@ -123,3 +128,4 @@ def detect_gesture(self):
123128 self .resultVar = "Found " + str (len (self .fingers [0 ])) + " extended fingers. Rock"
124129 else :
125130 self .resultVar = "Found " + str (len (self .fingers [0 ])) + " extended fingers. Unknown gesture"
131+
0 commit comments