Using facexlib, Low Quality Faces (blurry) after detecting and cv2.warpaffine faces using Facexlib

0

I am using Facexlib library to detect, crop (warpalign) and resize (512x512) the faces from photographic images (high resolutions 4K or above). In some cases, the output images are low quality even though faces is bigger in size more than 1Kx1K resolutions. Here is code in Facexlib library for detecting and cv2.warpalign the faces:

self.face_helper.read_image(img)
# get face landmarks for each face
self.face_helper.get_face_landmarks_5(only_center_face=only_center_face, eye_dist_threshold=5)
# eye_dist_threshold=5: skip faces whose eye distance is smaller than 5 pixels
# align and warp each face
self.face_helper.align_warp_face()

Face Detection using Facexlib library.

Below is Detected Image. (https://i.stack.imgur.com/VNNky.png)

Original Image is here (can not upload here as size is bigger)

How can I detect and crop (warp and align) faces from high resolution images ? I tried different interpolation method, but there is no difference in image quality. I tried following interpolation methods: cv2.INTER_NEAREST cv2.INTER_LINEAR cv2.INTER_AREA cv2.INTER_CUBIC cv2.INTER_LANCZOS4

I tried multiple interpolation techniques in cv2.warpalign method as flags, but no difference in image quality.

there is no such thing in opencv’s api

@berak the code for face crop and align is here:

def align_warp_face(self, save_cropped_path=None, border_mode='constant'):
        """Align and warp faces with face template.
        """
        if self.pad_blur:
            assert len(self.pad_input_imgs) == len(
                self.all_landmarks_5), f'Mismatched samples: {len(self.pad_input_imgs)} and {len(self.all_landmarks_5)}'
        for idx, landmark in enumerate(self.all_landmarks_5):
            # use 5 landmarks to get affine matrix
            # use cv2.LMEDS method for the equivalence to skimage transform
            # ref: https://blog.csdn.net/yichxi/article/details/115827338
            affine_matrix = cv2.estimateAffinePartial2D(landmark, self.face_template, method=cv2.LMEDS)[0]
            self.affine_matrices.append(affine_matrix)
            # warp and crop faces
            if border_mode == 'constant':
                border_mode = cv2.BORDER_CONSTANT
            elif border_mode == 'reflect101':
                border_mode = cv2.BORDER_REFLECT101
            elif border_mode == 'reflect':
                border_mode = cv2.BORDER_REFLECT
            if self.pad_blur:
                input_img = self.pad_input_imgs[idx]
            else:
                input_img = self.input_img
            cropped_face = cv2.warpAffine(
                input_img, affine_matrix, self.face_size, borderMode=border_mode, borderValue=(135, 133, 132))  # gray
            self.cropped_faces.append(cropped_face)
            # save the cropped face
            if save_cropped_path is not None:
                path = os.path.splitext(save_cropped_path)[0]
                save_path = f'{path}_{idx:02d}.{self.save_ext}'
                imwrite(cropped_face, save_path)

please file a bug with that library instead of OpenCV. it’s their issue to investigate.

you did not show us the “blurry” image either, so that’s where my investigation of your issue ends.

also: crosspost: