Skip to content

Commit 0ed1af0

Browse files
committed
updates the bugs of evaluators, adjusts parameters, and adds workplace to solve corner case.
1 parent 4a871a5 commit 0ed1af0

File tree

1 file changed

+44
-23
lines changed

1 file changed

+44
-23
lines changed

demos/smartlab_demo/python/evaluator.py

Lines changed: 44 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,9 @@ def __init__(self):
3131
self.rider_portion = 6 # [IS_rider & MS_rider] divide the distance between 2 roundscrew1 into rider_portion portion, if rider falls in the first portion mean rider at zeroth position
3232
self.rider_move_threshold = 20 # [MS_rider_tweezers] if rider moves more than this value, check if tweezers or hand is used to move rider
3333
self.buffer_rider_size_limit = 30 # [MS_rider_tweezers]
34-
self.use_tweezers_threshold = 350 # [MS_rider_tweezers & MS_weights_tweezers] if tweezer and rider/weight distance more than tweezer treshold, consider use hand instead of use tweezer
34+
self.use_tweezers_threshold = 100 # [MS_rider_tweezers & MS_weights_tweezers] if tweezer and rider/weight distance more than tweezer treshold, consider use hand instead of use tweezer
3535
self.tweezers_warning_duration = 60 # [MS_rider_tweezers & MS_weights_tweezers] if score related to tweezers is 0 more than this duration/frames, score is 0 and unrevertible; else still revertible
36+
self.battery_aspect_ratio = 1.9
3637
self.reset()
3738

3839
def reset(self):
@@ -122,7 +123,7 @@ def inference(self,
122123
action_seg_results = self.filter_action(action_seg_results, mode=mode)
123124

124125
top_det_results, side_det_results = self.filter_object(top_det_results, side_det_results)
125-
frame_top, frame_side = self.filter_image(frame_top, frame_side)
126+
self.filter_image(frame_top, frame_side)
126127

127128
if frame_counter > self.buffer_size:
128129
self.classify_state(action_seg_results)
@@ -134,9 +135,8 @@ def inference(self,
134135
self.evaluate_scale_balance()
135136

136137
elif self.state == "Measuring":
137-
object_left_score, _ = self.evaluate_object_left_from_view(view='top')
138-
if action_seg_results == "put_take" or action_seg_results == "put_left" or action_seg_results == "put_right" or \
139-
action_seg_results == "take_left" or action_seg_results == "take_right":
138+
# self.evaluate_object_left_from_view(view='top')
139+
if action_seg_results in ["put_take", "put_left", "put_right", "take_left", "take_right"]:
140140
self.evaluate_object_left()
141141
self.evaluate_weights_right()
142142
if not self.can_tidy:
@@ -199,7 +199,7 @@ def filter_action(self, action_seg_results, mode):
199199
self.action_buffer.append(action_seg_results)
200200
return self.last_action
201201
elif mode == 'mstcn':
202-
if action_seg_results != None:
202+
if action_seg_results is not None:
203203
self.action_mstcn_buffer.extend(action_seg_results)
204204
if len(self.action_mstcn_buffer) > self.mstcn_buffer_size: # 48
205205
self.action_mstcn_buffer = self.action_mstcn_buffer[self.mstcn_batchsize:] # self.mstcn_batchsize: 24
@@ -217,6 +217,24 @@ def filter_action(self, action_seg_results, mode):
217217

218218
def filter_object(self, top_det_results, side_det_results):
219219
first_top_det_results = first_side_det_results = None
220+
# --- corner case 1, top_det_results: battery is detected as weight. Use aspect ratio to remove wrong battery
221+
battery_index = [i for i in range(len(top_det_results[2])) if top_det_results[2][i] == 'battery']
222+
if len(battery_index) > 1:
223+
removed_index = []
224+
for i in battery_index:
225+
width = top_det_results[0][i][0] - top_det_results[0][i][2]
226+
height = top_det_results[0][i][1] - top_det_results[0][i][3]
227+
ratio = max(width / height, height / width)
228+
# should remove wrong battery
229+
if ratio < self.battery_aspect_ratio:
230+
removed_index.append(i)
231+
for i in range(len(removed_index) - 1, -1, -1):
232+
for index, item in enumerate(top_det_results):
233+
if index == 2:
234+
item.pop(removed_index[i])
235+
else:
236+
np.delete(item, removed_index[i])
237+
# --- corner case 1, top_det_results: battery is detected as weight. Use aspect ratio to remove wrong battery
220238
if self.mode == 'multiview':
221239
if len(self.top_obj_buffer) < self.buffer_size:
222240
self.top_obj_buffer.append(top_det_results)
@@ -478,7 +496,6 @@ def evaluate_rider(self):
478496
"""
479497
roundscrew1_coor = self.side_object_dict['roundscrew1']
480498
rider_coor = self.side_object_dict['rider']
481-
482499
# only evaluate rider_zero if 2 roundscrew1 and 1 rider are found
483500
if len(roundscrew1_coor) == 2 and len(rider_coor) == 1:
484501
# find center coordinate of rider and roundscrew1
@@ -567,10 +584,13 @@ def evaluate_object_left(self):
567584
# change mark only if student changes direction afterward
568585
self.is_change_object_direction = False
569586
self.is_object_put = True
570-
self.scoring['measuring_score_object_left'] = object_left_score
587+
self.scoring['measuring_score_object_left'] = 1
571588
self.keyframe['measuring_score_object_left'] = self.frame_counter
572589
elif not self.is_object_put:
573590
self.keyframe['measuring_score_object_left'] = self.frame_counter
591+
elif self.is_object_put:
592+
self.scoring['measuring_score_object_left'] = object_left_score
593+
self.keyframe['measuring_score_object_left'] = self.frame_counter
574594

575595
def evaluate_object_left_from_view(self, view):
576596
object_left_score = None
@@ -621,8 +641,6 @@ def evaluate_object_left_from_view(self, view):
621641
object_left_keyframe = self.frame_counter
622642
# no matter how many battery detected, as long as
623643
# one object detected at left tray, consider get mark
624-
return object_left_score, object_left_keyframe
625-
626644
else: # if object put happens on the right, then give zero score mark
627645
self.object_direction = 'right'
628646
self.object_is_in_tray_now = True
@@ -631,12 +649,12 @@ def evaluate_object_left_from_view(self, view):
631649
self.is_change_object_direction = False
632650
object_left_score = 0
633651
object_left_keyframe = self.frame_counter
634-
635652
# if object is put at left initially, but change to right tray afterward, will reevaluate object_left mark
636653
if self.object_direction == 'left' and is_inside_right > 0:
637654
self.is_change_object_direction = True
638655
if self.object_direction == 'right' and is_inside_left > 0:
639656
self.is_change_object_direction = True
657+
return object_left_score, object_left_keyframe
640658

641659
elif len(battery_coors) > 0 and len(balance_coor) == 1:
642660
# divide balance into 2 parts, left balance and right balance
@@ -710,9 +728,9 @@ def evaluate_weights_right(self):
710728
is_inside_left = self.is_inside(weight_center_coor, left_tray)
711729

712730
if is_inside_right:
713-
weight_inside_right_tray.append(weight[0])
731+
weight_inside_right_tray.append(weight)
714732
elif is_inside_left:
715-
weight_inside_left_tray.append(weight[0])
733+
weight_inside_left_tray.append(weight)
716734

717735
# mark will be given if users put the weight at right tray, mark will be kept constant except if users change tray (eg right to left tray)
718736
# once the first weight is put in left/right tray, self.is_weights_put become True to show weights have been put
@@ -739,22 +757,21 @@ def evaluate_weights_right(self):
739757

740758
# check if students put/take weights using tweezers
741759
if self.weights_direction == 'right':
742-
self.evaluate_weights_tweezers(num_weight_inside_tray=len(weight_inside_right_tray))
760+
self.evaluate_weights_tweezers(weight_inside_right_tray)
743761
elif self.weights_direction == 'left':
744-
self.evaluate_weights_tweezers(num_weight_inside_tray=len(weight_inside_right_tray))
762+
self.evaluate_weights_tweezers(weight_inside_left_tray)
745763

746-
def evaluate_weights_tweezers(self, num_weight_inside_tray):
747-
weights_coors = self.top_object_dict['weights']
764+
def evaluate_weights_tweezers(self, weight_inside_tray):
748765
tweezers_coor = self.top_object_dict['tweezers']
749766
# if number of weights inside tray increase/decrease,
750767
# check relative position (euclidean distance) of tweezers and all weights (top_left)
751-
if self.num_weight_inside_tray != num_weight_inside_tray and len(tweezers_coor) == 1:
752-
self.num_weight_inside_tray = num_weight_inside_tray
768+
if self.num_weight_inside_tray != len(weight_inside_tray) and len(tweezers_coor) == 1:
769+
self.num_weight_inside_tray = len(weight_inside_tray)
753770

754771
if not self.is_weight_tweezers_lock_mark:
755772
use_tweezers_bool = []
756-
for weight_coor in weights_coors:
757-
a = np.array(weight_coor[1][0], weight_coor[1][1])
773+
for weight in weight_inside_tray:
774+
a = np.array(weight[1][0], weight[1][1])
758775
b = np.array(tweezers_coor[0][0], tweezers_coor[0][0])
759776
if np.linalg.norm(a - b) <= self.use_tweezers_threshold:
760777
use_tweezers_bool.append(True)
@@ -764,8 +781,12 @@ def evaluate_weights_tweezers(self, num_weight_inside_tray):
764781
if not self.tweezers_warning \
765782
or self.frame_counter - self.tweezers_warning < self.tweezers_warning_duration:
766783
self.tweezers_warning = None
767-
self.scoring['measuring_score_weights_tweezers'] = 1
768-
self.keyframe['measuring_score_weights_tweezers'] = self.frame_counter
784+
if all(use_tweezers_bool):
785+
self.scoring['measuring_score_weights_tweezers'] = 1
786+
self.keyframe['measuring_score_weights_tweezers'] = self.frame_counter
787+
else:
788+
self.scoring['measuring_score_weights_tweezers'] = 0
789+
self.keyframe['measuring_score_weights_tweezers'] = self.frame_counter
769790
else:
770791
self.is_weight_tweezers_lock_mark = True
771792
else:

0 commit comments

Comments
 (0)