in source/backend/chalicelib/nose.py [0:0]
def nose_state(params, frame, context):
init_context(context, frame)
image_width = params['imageWidth']
image_height = params['imageHeight']
# Validating if face is inside area (with tolerance)
area_width_tolerance = params['areaWidth'] * _AREA_BOX_TOLERANCE
area_height_tolerance = params['areaHeight'] * _AREA_BOX_TOLERANCE
area_box = (params['areaLeft'] - area_width_tolerance,
params['areaTop'] - area_height_tolerance,
params['areaWidth'] + 2 * area_width_tolerance,
params['areaHeight'] + 2 * area_height_tolerance)
rek_metadata = frame['rekMetadata'][0]
rek_face_box = [
image_width * rek_metadata['BoundingBox']['Left'],
image_height * rek_metadata['BoundingBox']['Top'],
image_width * rek_metadata['BoundingBox']['Width'],
image_height * rek_metadata['BoundingBox']['Height']
]
inside_area_box = _is_inside_area_box(area_box, rek_face_box)
_log.debug('inside_area_box: %s', inside_area_box)
if not inside_area_box:
return CHALLENGE_FAIL
# Validating nose position (with tolerance)
nose_width_tolerance = params['noseWidth'] * _NOSE_BOX_TOLERANCE
nose_height_tolerance = params['noseHeight'] * _NOSE_BOX_TOLERANCE
nose_box = (params['noseLeft'] - nose_width_tolerance,
params['noseTop'] - nose_height_tolerance,
params['noseWidth'] + 2 * nose_width_tolerance,
params['noseHeight'] + 2 * nose_height_tolerance)
rek_landmarks = rek_metadata['Landmarks']
inside_nose_box = False
for landmark in rek_landmarks:
if landmark['Type'] == 'nose':
nose_left = image_width * landmark['X']
nose_top = image_height * landmark['Y']
context['nose_trajectory'].append((landmark['X'], landmark['Y']))
inside_nose_box = (nose_box[0] <= nose_left <= nose_box[0] + nose_box[2] and
nose_box[1] <= nose_top <= nose_box[1] + nose_box[3])
_log.debug('inside_nose_box: %s', inside_nose_box)
if not inside_nose_box:
return STATE_CONTINUE
# Validating continuous and linear nose trajectory
nose_trajectory_x = [nose[0] for nose in context['nose_trajectory']]
nose_trajectory_y = [nose[1] for nose in context['nose_trajectory']]
# noinspection PyTupleAssignmentBalance
_, residuals, _, _, _ = np.polyfit(nose_trajectory_x, nose_trajectory_y, 2, full=True)
trajectory_error = math.sqrt(residuals / len(context['nose_trajectory']))
if trajectory_error > _TRAJECTORY_ERROR_THRESHOLD:
_log.info('invalid_trajectory')
return CHALLENGE_FAIL
# Plotting landmarks from the first frame in a histogram
original_landmarks_x = [image_width * landmark['X'] for landmark in context['original_landmarks']]
original_landmarks_y = [image_height * landmark['Y'] for landmark in context['original_landmarks']]
original_histogram, _, _ = np.histogram2d(original_landmarks_x,
original_landmarks_y,
bins=_HISTOGRAM_BINS)
original_histogram = np.reshape(original_histogram, _HISTOGRAM_BINS ** 2) / len(
original_landmarks_x)
# Plotting landmarks from the last frame in a histogram
current_landmarks_x = [image_width * landmark['X'] for landmark in rek_landmarks]
current_landmarks_y = [image_height * landmark['Y'] for landmark in rek_landmarks]
current_histogram, _, _ = np.histogram2d(current_landmarks_x,
current_landmarks_y,
bins=_HISTOGRAM_BINS)
current_histogram = np.reshape(current_histogram, _HISTOGRAM_BINS ** 2) / len(current_landmarks_x)
# Calculating the Euclidean distance between histograms
dist = np.linalg.norm(original_histogram - current_histogram)
# Estimating left and right rotation
yaw = rek_metadata['Pose']['Yaw']
rotated_right = yaw > _ROTATION_THRESHOLD
rotated_left = yaw < - _ROTATION_THRESHOLD
rotated_face = rotated_left or rotated_right
# Validating distance according to rotation
challenge_in_the_right = params['noseLeft'] + _NOSE_BOX_SIZE / 2 > image_width / 2
if (rotated_right and challenge_in_the_right) or (rotated_left and not challenge_in_the_right):
min_dist = _MIN_DIST * _MIN_DIST_FACTOR_ROTATED
elif not rotated_face:
min_dist = _MIN_DIST * _MIN_DIST_FACTOR_NOT_ROTATED
else:
_log.info('invalid_rotation')
return CHALLENGE_FAIL
if dist > min_dist:
_log.info('valid_distance')
return CHALLENGE_SUCCESS
_log.info('invalid_distance')
return CHALLENGE_FAIL