def get_cropped_face_using_fixed_eye_pos( image_path, align_path, offset_pct, dest_size): """ Get face cropped and aligned to eyes from image file Eye positions are known and corresponds to intersection in grid :type image_path: string :param image_path: path of image to be cropped :type align_path: string :param align_path: path of directory where aligned faces are saved :type offset_pct: 2-element tuple :param offset_pct: offset given as percentage of eye-to-eye distance :type dest_size: 2-element tuple :param dest_size: size of result :rtype: OpenCV image or None :returns: face """ cropped_image = None # Open image file_check = os.path.isfile(image_path) if not file_check: print('File does not exist') return try: # Open whole image as PIL Image img = Image.open(image_path) # Align face image (width, height) = img.size eye_left = (width / c.GRID_CELLS_X, height / c.GRID_CELLS_Y) eye_right = (2 * width / c.GRID_CELLS_Y, height / c.GRID_CELLS_Y) # Create unique file path tmp_file_name = str(uuid.uuid4()) + '.png' tmp_file_path = os.path.join(align_path, tmp_file_name) CropFace( img, eye_left, eye_right, offset_pct, dest_size).save(tmp_file_path) face_image = cv2.imread(tmp_file_path, cv2.IMREAD_GRAYSCALE) if c.USE_HIST_EQ_IN_CROPPED_FACES: face_image = cv2.equalizeHist(face_image) if c.USE_NORM_IN_CROPPED_FACES: face_image = cv2.normalize( face_image, alpha=0, beta=255, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_8UC1) if c.USE_CANNY_IN_CROPPED_FACES: face_image = cv2.Canny(face_image, 0.1, 100) if c.USE_TAN_AND_TRIGG_NORM: face_image = utils.normalize_illumination(face_image) # Insert oval mask in image if c.USE_OVAL_MASK: face_image = utils.add_oval_mask(face_image) return face_image except IOError, (errno, strerror): print "I/O error({0}): {1}".format(errno, strerror)
def get_cropped_face_from_image( image, image_path, align_path, params, eye_cascade_classifier, nose_cascade_classifier, face_bbox, delete_files, return_always_face): """ Get face cropped and aligned to eyes from image :type image: openCV image :param image: image to be cropped :type image_path: string :param image_path: path of image to be analyzed :type align_path: string :param align_path: path of directory where aligned faces are saved :type params: dictionary :param params: dictionary containing the parameters to be used for the face detection :type eye_cascade_classifier: CascadeClassifier :param eye_cascade_classifier: classifier for detecting eyes :type nose_cascade_classifier: CascadeClassifier :param nose_cascade_classifier: classifier for detecting nose :type face_bbox: tuple :type face_bbox: bbox of face in original image, represented as (x, y, width, height) :type delete_files: boolean :param delete_files: delete(true) or do not delete(false) saved image files :type return_always_face: boolean :type return_always_face: if true, return face even if no eyes are detected :rtype: dictionary or None :returns: dictionary with results """ result = {} # Offset given as percentage of eye-to-eye distance offset_pct_x = c.OFFSET_PCT_X offset_pct_y = c.OFFSET_PCT_Y # Final size of cropped face cropped_face_width = c.CROPPED_FACE_WIDTH cropped_face_height = c.CROPPED_FACE_HEIGHT # If True, check eye positions check_eye_positions = c.CHECK_EYE_POSITIONS if params is not None: if c.CROPPED_FACE_WIDTH_KEY in params: cropped_face_width = params[c.CROPPED_FACE_WIDTH_KEY] if c.CROPPED_FACE_HEIGHT_KEY in params: cropped_face_height = params[c.CROPPED_FACE_HEIGHT_KEY] if c.OFFSET_PCT_X_KEY in params: offset_pct_x = params[c.OFFSET_PCT_X_KEY] if c.OFFSET_PCT_Y_KEY in params: offset_pct_y = params[c.OFFSET_PCT_Y_KEY] if c.CHECK_EYE_POSITIONS_KEY in params: check_eye_positions = params[c.CHECK_EYE_POSITIONS_KEY] offset_pct = (offset_pct_x, offset_pct_y) dest_size = (cropped_face_width, cropped_face_height) # Detect eyes in face eye_rects = utils.detect_eyes_in_image(image, eye_cascade_classifier) eye_left = None eye_right = None eye_check_ok = False if len(eye_rects) == 2: x_first_eye = eye_rects[0][0] y_first_eye = eye_rects[0][1] w_first_eye = eye_rects[0][2] h_first_eye = eye_rects[0][3] x_second_eye = eye_rects[1][0] y_second_eye = eye_rects[1][1] w_second_eye = eye_rects[1][2] h_second_eye = eye_rects[1][3] x_left_eye_center = 0 y_left_eye_center = 0 x_right_eye_center = 0 y_right_eye_center = 0 if x_first_eye < x_second_eye: x_left_eye_center = x_first_eye + w_first_eye / 2 y_left_eye_center = y_first_eye + h_first_eye / 2 x_right_eye_center = x_second_eye + w_second_eye / 2 y_right_eye_center = y_second_eye + h_second_eye / 2 else: x_right_eye_center = x_first_eye + w_first_eye / 2 y_right_eye_center = y_first_eye + h_first_eye / 2 x_left_eye_center = x_second_eye + w_second_eye / 2 y_left_eye_center = y_second_eye + h_second_eye / 2 eye_left = (int(x_left_eye_center + face_bbox[0]), int(y_left_eye_center + face_bbox[1])) eye_right = (int(x_right_eye_center + face_bbox[0]), int(y_right_eye_center + face_bbox[1])) if check_eye_positions: eye_check_ok = utils.check_eye_pos( eye_left, eye_right, face_bbox, params) else: eye_check_ok = True if eye_check_ok: # Open whole image as PIL Image img = Image.open(image_path) # Store eye positions related to whole image result[c.LEFT_EYE_POS_KEY] = eye_left result[c.RIGHT_EYE_POS_KEY] = eye_right result[c.NOSE_POSITION_KEY] = None # Align face image # Create unique file path tmp_file_name = str(uuid.uuid4()) tmp_file_name_complete = tmp_file_name + '.png' tmp_file_path = os.path.join(align_path, tmp_file_name_complete) CropFace( img, eye_left, eye_right, offset_pct, dest_size).save(tmp_file_path) face_image = cv2.imread(tmp_file_path, cv2.IMREAD_GRAYSCALE) if delete_files: os.remove(tmp_file_path) else: result[c.ALIGNED_FACE_FILE_NAME_KEY] = tmp_file_name # Check nose position nose_check_ok = True use_nose_pos_in_detection = c.USE_NOSE_POS_IN_DETECTION use_nose_pos_in_recognition = c.USE_NOSE_POS_IN_RECOGNITION if params is not None: if c.USE_NOSE_POS_IN_DETECTION_KEY in params: use_nose_pos_in_detection = params[c.USE_NOSE_POS_IN_DETECTION_KEY] if c.USE_NOSE_POS_IN_RECOGNITION_KEY in params: use_nose_pos_in_recognition = params[c.USE_NOSE_POS_IN_RECOGNITION_KEY] if use_nose_pos_in_detection or use_nose_pos_in_recognition: noses = utils.detect_nose_in_image( face_image, nose_cascade_classifier) x_right_eye = offset_pct[0] * dest_size[0] x_left_eye = dest_size[0] - x_right_eye y_eyes = offset_pct[1] * dest_size[1] good_noses = 0 for(x_nose, y_nose, w_nose, h_nose) in noses: # Coordinates of bounding box center in face image x_center = float(x_nose + w_nose / 2) y_center = float(y_nose + h_nose / 2) # Store nose position relative to face image nose_x_pct = x_center / cropped_face_width nose_y_pct = y_center / cropped_face_height nose = (nose_x_pct, nose_y_pct) result[c.NOSE_POSITION_KEY] = nose # Nose must be between eyes in horizontal direction # and below eyes in vertical direction if((x_center > x_right_eye) and(x_center < x_left_eye) and (y_center > y_eyes)): good_noses += 1 if good_noses != 1: nose_check_ok = False result[c.NOSE_POSITION_KEY] = None if nose_check_ok or not use_nose_pos_in_detection: if c.USE_HIST_EQ_IN_CROPPED_FACES: face_image = cv2.equalizeHist(face_image) if c.USE_NORM_IN_CROPPED_FACES: face_image = cv2.normalize( face_image, alpha=0, beta=255, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_8UC1) if c.USE_CANNY_IN_CROPPED_FACES: face_image = cv2.Canny(face_image, 0.1, 100) if c.USE_TAN_AND_TRIGG_NORM: face_image = utils.normalize_illumination(face_image) # Insert oval mask in image if c.USE_OVAL_MASK: face_image = utils.add_oval_mask(face_image) if not delete_files: tmp_file_name_gray = ( tmp_file_name + c.ALIGNED_FACE_GRAY_SUFFIX + '.png') tmp_file_gray_path = os.path.join( align_path, tmp_file_name_gray) cv2.imwrite(tmp_file_gray_path, face_image) return result else: result[c.FACE_KEY] = None return result else: if return_always_face: result[c.LEFT_EYE_POS_KEY] = None result[c.RIGHT_EYE_POS_KEY] = None return result else: return None