Exemplo n.º 1
0
def add_landmarks_debug_images(input_path):
    io.log_info ("Adding landmarks debug images...")

    for filepath in io.progress_bar_generator( pathex.get_image_paths(input_path), "Processing"):
        filepath = Path(filepath)

        img = cv2_imread(str(filepath))

        dflimg = DFLIMG.load (filepath)

        if dflimg is None or not dflimg.has_data():
            io.log_err (f"{filepath.name} is not a dfl image file")
            continue
        
        if img is not None:
            face_landmarks = dflimg.get_landmarks()
            face_type = FaceType.fromString ( dflimg.get_face_type() )
            
            if face_type == FaceType.MARK_ONLY:
                rect = dflimg.get_source_rect()
                LandmarksProcessor.draw_rect_landmarks(img, rect, face_landmarks, FaceType.FULL )
            else:
                LandmarksProcessor.draw_landmarks(img, face_landmarks, transparent_mask=True )
            
            
            
            output_file = '{}{}'.format( str(Path(str(input_path)) / filepath.stem),  '_debug.jpg')
            cv2_imwrite(output_file, img, [int(cv2.IMWRITE_JPEG_QUALITY), 50] )
Exemplo n.º 2
0
    def redraw(self):
        (h,w,c) = self.image.shape

        if not self.hide_help:
            image = cv2.addWeighted (self.image,1.0,self.text_lines_img,1.0,0)
        else:
            image = self.image.copy()

        view_rect = (np.array(self.rect) * self.view_scale).astype(np.int).tolist()
        view_landmarks  = (np.array(self.landmarks) * self.view_scale).astype(np.int).tolist()

        if self.rect_size <= 40:
            scaled_rect_size = h // 3 if w > h else w // 3

            p1 = (self.x - self.rect_size, self.y - self.rect_size)
            p2 = (self.x + self.rect_size, self.y - self.rect_size)
            p3 = (self.x - self.rect_size, self.y + self.rect_size)

            wh = h if h < w else w
            np1 = (w / 2 - wh / 4, h / 2 - wh / 4)
            np2 = (w / 2 + wh / 4, h / 2 - wh / 4)
            np3 = (w / 2 - wh / 4, h / 2 + wh / 4)

            mat = cv2.getAffineTransform( np.float32([p1,p2,p3])*self.view_scale, np.float32([np1,np2,np3]) )
            image = cv2.warpAffine(image, mat,(w,h) )
            view_landmarks = LandmarksProcessor.transform_points (view_landmarks, mat)

        landmarks_color = (255,255,0) if self.rect_locked else (0,255,0)
        LandmarksProcessor.draw_rect_landmarks (image, view_rect, view_landmarks, self.face_type, self.image_size, landmarks_color=landmarks_color)
        self.extract_needed = False

        io.show_image (self.wnd_name, image)
Exemplo n.º 3
0
    def on_result(self, host_dict, data, result):
        if self.manual == True:
            filename, landmarks = result
            if landmarks is not None:
                self.landmarks = landmarks[0][1]

            (h, w, c) = self.image.shape

            if not self.hide_help:
                image = cv2.addWeighted(self.image, 1.0, self.text_lines_img,
                                        1.0, 0)
            else:
                image = self.image.copy()

            view_rect = (np.array(self.rect) * self.view_scale).astype(
                np.int).tolist()
            view_landmarks = (np.array(self.landmarks) *
                              self.view_scale).astype(np.int).tolist()

            if self.rect_size <= 40:
                scaled_rect_size = h // 3 if w > h else w // 3

                p1 = (self.x - self.rect_size, self.y - self.rect_size)
                p2 = (self.x + self.rect_size, self.y - self.rect_size)
                p3 = (self.x - self.rect_size, self.y + self.rect_size)

                wh = h if h < w else w
                np1 = (w / 2 - wh / 4, h / 2 - wh / 4)
                np2 = (w / 2 + wh / 4, h / 2 - wh / 4)
                np3 = (w / 2 - wh / 4, h / 2 + wh / 4)

                mat = cv2.getAffineTransform(
                    np.float32([p1, p2, p3]) * self.view_scale,
                    np.float32([np1, np2, np3]))
                image = cv2.warpAffine(image, mat, (w, h))
                view_landmarks = LandmarksProcessor.transform_points(
                    view_landmarks, mat)

            landmarks_color = (255, 255, 0) if self.rect_locked else (0, 255,
                                                                      0)
            LandmarksProcessor.draw_rect_landmarks(
                image,
                view_rect,
                view_landmarks,
                self.image_size,
                self.face_type,
                landmarks_color=landmarks_color)
            self.extract_needed = False

            io.show_image(self.wnd_name, image)
        else:
            if self.type == 'rects':
                self.result.append(result)
            elif self.type == 'landmarks':
                self.result.append(result)
            elif self.type == 'final':
                self.result += result

            io.progress_bar_inc(1)
Exemplo n.º 4
0
    def onHostResult(self, host_dict, data, result):
        if self.manual == True:
            self.landmarks = result[1][0][1]

            (h, w, c) = self.original_image.shape
            image = cv2.addWeighted(self.original_image, 1.0,
                                    self.text_lines_img, 1.0, 0)
            view_rect = (np.array(self.rect) * self.view_scale).astype(
                np.int).tolist()
            view_landmarks = (np.array(self.landmarks) *
                              self.view_scale).astype(np.int).tolist()

            if self.param_rect_size <= 25:
                scaled_rect_size = h // 3 if w > h else w // 3

                p1 = (self.param_x - self.param_rect_size,
                      self.param_y - self.param_rect_size)
                p2 = (self.param_x + self.param_rect_size,
                      self.param_y - self.param_rect_size)
                p3 = (self.param_x - self.param_rect_size,
                      self.param_y + self.param_rect_size)

                np1 = (self.param_x - scaled_rect_size,
                       self.param_y - scaled_rect_size)
                np2 = (self.param_x + scaled_rect_size,
                       self.param_y - scaled_rect_size)
                np3 = (self.param_x - scaled_rect_size,
                       self.param_y + scaled_rect_size)

                mat = cv2.getAffineTransform(
                    np.float32([p1, p2, p3]) * self.view_scale,
                    np.float32([np1, np2, np3]) * self.view_scale)
                image = cv2.warpAffine(image, mat, (w, h))
                view_landmarks = LandmarksProcessor.transform_points(
                    view_landmarks, mat)

            LandmarksProcessor.draw_rect_landmarks(image, view_rect,
                                                   view_landmarks,
                                                   self.image_size,
                                                   self.face_type)

            if self.param['rect_locked']:
                LandmarksProcessor.draw_landmarks(image, view_landmarks,
                                                  (255, 255, 0))
            self.param['redraw_needed'] = False

            cv2.imshow(self.wnd_name, image)
            return 0
        else:
            if self.type == 'rects':
                self.result.append(result)
            elif self.type == 'landmarks':
                self.result.append(result)
            elif self.type == 'final':
                self.result += result

            return 1
Exemplo n.º 5
0
    def onClientProcessData(self, data):
        filename_path = Path( data[0] )

        image = cv2_imread( str(filename_path) )
        if image is None:
            print ( 'Failed to extract %s, reason: cv2_imread() fail.' % ( str(filename_path) ) )
        else:
            if self.type == 'rects':
                rects = self.e.extract_from_bgr (image)
                return [str(filename_path), rects]

            elif self.type == 'landmarks':
                rects = data[1]   
                landmarks = self.e.extract_from_bgr (image, rects)                    
                return [str(filename_path), landmarks]

            elif self.type == 'final':     
                result = []
                faces = data[1]
                
                if self.debug:
                    debug_output_file = '{}{}'.format( str(Path(str(self.output_path) + '_debug') / filename_path.stem),  '.jpg')
                    debug_image = image.copy()
                    
                for (face_idx, face) in enumerate(faces):         
                    output_file = '{}_{}{}'.format(str(self.output_path / filename_path.stem), str(face_idx), '.jpg')
                    
                    rect = face[0]
                    image_landmarks = np.array(face[1])

                    if self.debug:
                        LandmarksProcessor.draw_rect_landmarks (debug_image, rect, image_landmarks, self.image_size, self.face_type)

                    if self.face_type == FaceType.MARK_ONLY:                        
                        face_image = image
                        face_image_landmarks = image_landmarks
                    else:
                        image_to_face_mat = LandmarksProcessor.get_transform_mat (image_landmarks, self.image_size, self.face_type)       
                        face_image = cv2.warpAffine(image, image_to_face_mat, (self.image_size, self.image_size), cv2.INTER_LANCZOS4)
                        face_image_landmarks = LandmarksProcessor.transform_points (image_landmarks, image_to_face_mat)
                    
                    cv2_imwrite(output_file, face_image, [int(cv2.IMWRITE_JPEG_QUALITY), 85] )

                    DFLJPG.embed_data(output_file, face_type = FaceType.toString(self.face_type),
                                                   landmarks = face_image_landmarks.tolist(),
                                                   source_filename = filename_path.name,
                                                   source_rect=  rect,
                                                   source_landmarks = image_landmarks.tolist()
                                        )  
                        
                    result.append (output_file)
                    
                if self.debug:
                    cv2_imwrite(debug_output_file, debug_image, [int(cv2.IMWRITE_JPEG_QUALITY), 50] )
                    
                return result       
        return None
Exemplo n.º 6
0
        def final_stage(
            data,
            image,
            face_type,
            image_size,
            extract_from_dflimg=False,
            output_debug_path=None,
            final_output_path=None,
        ):
            data.final_output_files = []
            filepath = data.filepath
            rects = data.rects
            landmarks = data.landmarks

            if output_debug_path is not None:
                debug_image = image.copy()

            if extract_from_dflimg and len(rects) != 1:
                #if re-extracting from dflimg and more than 1 or zero faces detected - dont process and just copy it
                print("extract_from_dflimg and len(rects) != 1", filepath)
                output_filepath = final_output_path / filepath.name
                if filepath != str(output_file):
                    shutil.copy(str(filepath), str(output_filepath))
                data.final_output_files.append(output_filepath)
            else:
                face_idx = 0
                for rect, image_landmarks in zip(rects, landmarks):

                    if extract_from_dflimg and face_idx > 1:
                        #cannot extract more than 1 face from dflimg
                        break

                    if image_landmarks is None:
                        continue

                    rect = np.array(rect)

                    if face_type == FaceType.MARK_ONLY:
                        image_to_face_mat = None
                        face_image = image
                        face_image_landmarks = image_landmarks
                    else:
                        image_to_face_mat = LandmarksProcessor.get_transform_mat(
                            image_landmarks, image_size, face_type)

                        face_image = cv2.warpAffine(image, image_to_face_mat,
                                                    (image_size, image_size),
                                                    cv2.INTER_LANCZOS4)
                        face_image_landmarks = LandmarksProcessor.transform_points(
                            image_landmarks, image_to_face_mat)

                        landmarks_bbox = LandmarksProcessor.transform_points(
                            [(0, 0), (0, image_size - 1),
                             (image_size - 1, image_size - 1),
                             (image_size - 1, 0)], image_to_face_mat, True)

                        rect_area = mathlib.polygon_area(
                            np.array(rect[[0, 2, 2, 0]]),
                            np.array(rect[[1, 1, 3, 3]]))
                        landmarks_area = mathlib.polygon_area(
                            landmarks_bbox[:, 0], landmarks_bbox[:, 1])

                        if not data.manual and face_type <= FaceType.FULL_NO_ALIGN and landmarks_area > 4 * rect_area:  #get rid of faces which umeyama-landmark-area > 4*detector-rect-area
                            continue

                        if output_debug_path is not None:
                            LandmarksProcessor.draw_rect_landmarks(
                                debug_image,
                                rect,
                                image_landmarks,
                                image_size,
                                face_type,
                                transparent_mask=True)

                    output_path = final_output_path
                    if data.force_output_path is not None:
                        output_path = data.force_output_path

                    if extract_from_dflimg and filepath.suffix == '.jpg':
                        #if extracting from dflimg and jpg copy it in order not to lose quality
                        output_filepath = output_path / filepath.name
                        if filepath != output_filepath:
                            shutil.copy(str(filepath), str(output_filepath))
                    else:
                        output_filepath = output_path / f"{filepath.stem}_{face_idx}.jpg"
                        cv2_imwrite(output_filepath, face_image,
                                    [int(cv2.IMWRITE_JPEG_QUALITY), 100])

                    DFLJPG.embed_data(
                        output_filepath,
                        face_type=FaceType.toString(face_type),
                        landmarks=face_image_landmarks.tolist(),
                        source_filename=filepath.name,
                        source_rect=rect,
                        source_landmarks=image_landmarks.tolist(),
                        image_to_face_mat=image_to_face_mat)

                    data.final_output_files.append(output_filepath)
                    face_idx += 1
                data.faces_detected = face_idx

            if output_debug_path is not None:
                cv2_imwrite(output_debug_path / (filepath.stem + '.jpg'),
                            debug_image, [int(cv2.IMWRITE_JPEG_QUALITY), 50])

            return data
Exemplo n.º 7
0
        def process_data(self, data):
            filename_path = Path(data[0])

            filename_path_str = str(filename_path)
            if self.cached_image[0] == filename_path_str:
                image = self.cached_image[1]
            else:
                image = cv2_imread(filename_path_str)
                self.cached_image = (filename_path_str, image)

            if image is None:
                self.log_err(
                    'Failed to extract %s, reason: cv2_imread() fail.' %
                    (str(filename_path)))
            else:
                if self.type == 'rects':
                    rects = self.e.extract_from_bgr(image)
                    return [str(filename_path), rects]

                elif self.type == 'landmarks':
                    rects = data[1]
                    landmarks = self.e.extract_from_bgr(image, rects)
                    return [str(filename_path), landmarks]

                elif self.type == 'final':
                    src_dflimg = None
                    (h, w, c) = image.shape
                    if h == w:
                        #extracting from already extracted jpg image?
                        if filename_path.suffix == '.jpg':
                            src_dflimg = DFLJPG.load(str(filename_path))

                    result = []
                    faces = data[1]

                    if self.debug:
                        debug_output_file = '{}{}'.format(
                            str(
                                Path(str(self.output_path) + '_debug') /
                                filename_path.stem), '.jpg')
                        debug_image = image.copy()

                    for (face_idx, face) in enumerate(faces):
                        output_file = '{}_{}{}'.format(
                            str(self.output_path / filename_path.stem),
                            str(face_idx), '.jpg')

                        rect = face[0]
                        image_landmarks = np.array(face[1])

                        if self.debug:
                            LandmarksProcessor.draw_rect_landmarks(
                                debug_image, rect, image_landmarks,
                                self.image_size, self.face_type)

                        if self.face_type == FaceType.MARK_ONLY:
                            face_image = image
                            face_image_landmarks = image_landmarks
                        else:
                            image_to_face_mat = LandmarksProcessor.get_transform_mat(
                                image_landmarks, self.image_size,
                                self.face_type)
                            face_image = cv2.warpAffine(
                                image, image_to_face_mat,
                                (self.image_size, self.image_size),
                                cv2.INTER_LANCZOS4)
                            face_image_landmarks = LandmarksProcessor.transform_points(
                                image_landmarks, image_to_face_mat)

                        if src_dflimg is not None:
                            #if extracting from dflimg just copy it in order not to lose quality
                            shutil.copy(str(filename_path), str(output_file))
                        else:
                            cv2_imwrite(output_file, face_image,
                                        [int(cv2.IMWRITE_JPEG_QUALITY), 85])

                        DFLJPG.embed_data(
                            output_file,
                            face_type=FaceType.toString(self.face_type),
                            landmarks=face_image_landmarks.tolist(),
                            source_filename=filename_path.name,
                            source_rect=rect,
                            source_landmarks=image_landmarks.tolist())

                        result.append(output_file)

                    if self.debug:
                        cv2_imwrite(debug_output_file, debug_image,
                                    [int(cv2.IMWRITE_JPEG_QUALITY), 50])

                    return result
            return None
Exemplo n.º 8
0
        def process_data(self, data):
            filename_path = Path(data.filename)

            filename_path_str = str(filename_path)
            if self.cached_image[0] == filename_path_str:
                image = self.cached_image[
                    1]  #cached image for manual extractor
            else:
                image = cv2_imread(filename_path_str)

                if image is None:
                    self.log_err(
                        'Failed to extract %s, reason: cv2_imread() fail.' %
                        (str(filename_path)))
                    return data

                image = imagelib.normalize_channels(image, 3)
                h, w, ch = image.shape

                wm, hm = w % 2, h % 2
                if wm + hm != 0:  #fix odd image
                    image = image[0:h - hm, 0:w - wm, :]
                self.cached_image = (filename_path_str, image)

            src_dflimg = None
            h, w, ch = image.shape
            if h == w:
                #extracting from already extracted jpg image?
                if filename_path.suffix == '.png':
                    src_dflimg = DFLPNG.load(str(filename_path))
                if filename_path.suffix == '.jpg':
                    src_dflimg = DFLJPG.load(str(filename_path))

            if 'rects' in self.type:
                if min(w, h) < 128:
                    self.log_err('Image is too small %s : [%d, %d]' %
                                 (str(filename_path), w, h))
                    data.rects = []
                else:
                    for rot in ([0, 90, 270, 180]):
                        data.rects_rotation = rot
                        if rot == 0:
                            rotated_image = image
                        elif rot == 90:
                            rotated_image = image.swapaxes(0, 1)[:, ::-1, :]
                        elif rot == 180:
                            rotated_image = image[::-1, ::-1, :]
                        elif rot == 270:
                            rotated_image = image.swapaxes(0, 1)[::-1, :, :]

                        rects = data.rects = self.e.extract(rotated_image,
                                                            is_bgr=True)
                        if len(rects) != 0:
                            break

                    if self.max_faces_from_image != 0 and len(data.rects) > 1:
                        data.rects = data.rects[0:self.max_faces_from_image]

                return data

            elif self.type == 'landmarks':

                if data.rects_rotation == 0:
                    rotated_image = image
                elif data.rects_rotation == 90:
                    rotated_image = image.swapaxes(0, 1)[:, ::-1, :]
                elif data.rects_rotation == 180:
                    rotated_image = image[::-1, ::-1, :]
                elif data.rects_rotation == 270:
                    rotated_image = image.swapaxes(0, 1)[::-1, :, :]

                data.landmarks = self.e.extract(
                    rotated_image,
                    data.rects,
                    self.second_pass_e if
                    (src_dflimg is None and data.landmarks_accurate) else None,
                    is_bgr=True)
                if data.rects_rotation != 0:
                    for i, (rect,
                            lmrks) in enumerate(zip(data.rects,
                                                    data.landmarks)):
                        new_rect, new_lmrks = rect, lmrks
                        (l, t, r, b) = rect
                        if data.rects_rotation == 90:
                            new_rect = (t, h - l, b, h - r)
                            if lmrks is not None:
                                new_lmrks = lmrks[:, ::-1].copy()
                                new_lmrks[:, 1] = h - new_lmrks[:, 1]
                        elif data.rects_rotation == 180:
                            if lmrks is not None:
                                new_rect = (w - l, h - t, w - r, h - b)
                                new_lmrks = lmrks.copy()
                                new_lmrks[:, 0] = w - new_lmrks[:, 0]
                                new_lmrks[:, 1] = h - new_lmrks[:, 1]
                        elif data.rects_rotation == 270:
                            new_rect = (w - b, l, w - t, r)
                            if lmrks is not None:
                                new_lmrks = lmrks[:, ::-1].copy()
                                new_lmrks[:, 0] = w - new_lmrks[:, 0]
                        data.rects[i], data.landmarks[i] = new_rect, new_lmrks

                return data

            elif self.type == 'final':
                data.final_output_files = []
                rects = data.rects
                landmarks = data.landmarks

                if self.debug_dir is not None:
                    debug_output_file = str(
                        Path(self.debug_dir) / (filename_path.stem + '.jpg'))
                    debug_image = image.copy()

                if src_dflimg is not None and len(rects) != 1:
                    #if re-extracting from dflimg and more than 1 or zero faces detected - dont process and just copy it
                    print("src_dflimg is not None and len(rects) != 1",
                          str(filename_path))
                    output_file = str(self.final_output_path /
                                      filename_path.name)
                    if str(filename_path) != str(output_file):
                        shutil.copy(str(filename_path), str(output_file))
                    data.final_output_files.append(output_file)
                else:
                    face_idx = 0
                    for rect, image_landmarks in zip(rects, landmarks):

                        if src_dflimg is not None and face_idx > 1:
                            #cannot extract more than 1 face from dflimg
                            break

                        if image_landmarks is None:
                            continue

                        rect = np.array(rect)

                        if self.face_type == FaceType.MARK_ONLY:
                            image_to_face_mat = None
                            face_image = image
                            face_image_landmarks = image_landmarks
                        else:
                            image_to_face_mat = LandmarksProcessor.get_transform_mat(
                                image_landmarks, self.image_size,
                                self.face_type)

                            face_image = cv2.warpAffine(
                                image, image_to_face_mat,
                                (self.image_size, self.image_size),
                                cv2.INTER_LANCZOS4)
                            face_image_landmarks = LandmarksProcessor.transform_points(
                                image_landmarks, image_to_face_mat)

                            landmarks_bbox = LandmarksProcessor.transform_points(
                                [(0, 0), (0, self.image_size - 1),
                                 (self.image_size - 1, self.image_size - 1),
                                 (self.image_size - 1, 0)], image_to_face_mat,
                                True)

                            rect_area = mathlib.polygon_area(
                                np.array(rect[[0, 2, 2, 0]]),
                                np.array(rect[[1, 1, 3, 3]]))
                            landmarks_area = mathlib.polygon_area(
                                landmarks_bbox[:, 0], landmarks_bbox[:, 1])

                            if landmarks_area > 4 * rect_area:  #get rid of faces which umeyama-landmark-area > 4*detector-rect-area
                                continue

                            if self.debug_dir is not None:
                                LandmarksProcessor.draw_rect_landmarks(
                                    debug_image,
                                    rect,
                                    image_landmarks,
                                    self.image_size,
                                    self.face_type,
                                    transparent_mask=True)

                        if src_dflimg is not None and filename_path.suffix == '.jpg':
                            #if extracting from dflimg and jpg copy it in order not to lose quality
                            output_file = str(self.final_output_path /
                                              filename_path.name)
                            if str(filename_path) != str(output_file):
                                shutil.copy(str(filename_path),
                                            str(output_file))
                        else:
                            output_file = '{}_{}{}'.format(
                                str(self.final_output_path /
                                    filename_path.stem), str(face_idx), '.jpg')
                            cv2_imwrite(output_file, face_image,
                                        [int(cv2.IMWRITE_JPEG_QUALITY), 85])

                        DFLJPG.embed_data(
                            output_file,
                            face_type=FaceType.toString(self.face_type),
                            landmarks=face_image_landmarks.tolist(),
                            source_filename=filename_path.name,
                            source_rect=rect,
                            source_landmarks=image_landmarks.tolist(),
                            image_to_face_mat=image_to_face_mat,
                            pitch_yaw_roll=data.pitch_yaw_roll)

                        data.final_output_files.append(output_file)
                        face_idx += 1
                    data.faces_detected = face_idx

                if self.debug_dir is not None:
                    cv2_imwrite(debug_output_file, debug_image,
                                [int(cv2.IMWRITE_JPEG_QUALITY), 50])

                return data

            elif self.type == 'fanseg':
                if src_dflimg is not None:
                    fanseg_mask = self.e.extract(image / 255.0)
                    src_dflimg.embed_and_set(
                        filename_path_str,
                        fanseg_mask=fanseg_mask,
                    )
Exemplo n.º 9
0
        def process_data(self, data):
            filename_path = Path(data[0])

            filename_path_str = str(filename_path)
            if self.cached_image[0] == filename_path_str:
                image = self.cached_image[
                    1]  #cached image for manual extractor
            else:
                image = cv2_imread(filename_path_str)

                if image is None:
                    self.log_err(
                        'Failed to extract %s, reason: cv2_imread() fail.' %
                        (str(filename_path)))
                    return None

                image_shape = image.shape
                if len(image_shape) == 2:
                    h, w = image.shape
                    ch = 1
                else:
                    h, w, ch = image.shape

                if ch == 1:
                    image = np.repeat(image[:, :, np.newaxis], 3, -1)
                elif ch == 4:
                    image = image[:, :, 0:3]

                wm = w % 2
                hm = h % 2
                if wm + hm != 0:  #fix odd image
                    image = image[0:h - hm, 0:w - wm, :]
                self.cached_image = (filename_path_str, image)

            src_dflimg = None
            h, w, ch = image.shape
            if h == w:
                #extracting from already extracted jpg image?
                if filename_path.suffix == '.jpg':
                    src_dflimg = DFLJPG.load(str(filename_path))

            if self.type == 'rects':
                if min(w, h) < 128:
                    self.log_err('Image is too small %s : [%d, %d]' %
                                 (str(filename_path), w, h))
                    rects = []
                else:
                    rects = self.e.extract_from_bgr(image)

                return [str(filename_path), rects]

            elif self.type == 'landmarks':
                rects = data[1]
                if rects is None:
                    landmarks = None
                else:
                    landmarks = self.e.extract_from_bgr(
                        image, rects,
                        self.second_pass_e if src_dflimg is None else None)

                return [str(filename_path), landmarks]

            elif self.type == 'final':

                result = []
                faces = data[1]

                if self.debug_dir is not None:
                    debug_output_file = str(
                        Path(self.debug_dir) / (filename_path.stem + '.jpg'))
                    debug_image = image.copy()

                if src_dflimg is not None and len(faces) != 1:
                    #if re-extracting from dflimg and more than 1 or zero faces detected - dont process and just copy it
                    print("src_dflimg is not None and len(faces) != 1",
                          str(filename_path))
                    output_file = str(self.output_path / filename_path.name)
                    if str(filename_path) != str(output_file):
                        shutil.copy(str(filename_path), str(output_file))
                    result.append(output_file)
                else:
                    face_idx = 0
                    for face in faces:
                        rect = np.array(face[0])
                        image_landmarks = face[1]
                        if image_landmarks is None:
                            continue
                        image_landmarks = np.array(image_landmarks)

                        if self.face_type == FaceType.MARK_ONLY:
                            face_image = image
                            face_image_landmarks = image_landmarks
                        else:
                            image_to_face_mat = LandmarksProcessor.get_transform_mat(
                                image_landmarks, self.image_size,
                                self.face_type)
                            face_image = cv2.warpAffine(
                                image, image_to_face_mat,
                                (self.image_size, self.image_size),
                                cv2.INTER_LANCZOS4)
                            face_image_landmarks = LandmarksProcessor.transform_points(
                                image_landmarks, image_to_face_mat)

                            landmarks_bbox = LandmarksProcessor.transform_points(
                                [(0, 0), (0, self.image_size - 1),
                                 (self.image_size - 1, self.image_size - 1),
                                 (self.image_size - 1, 0)], image_to_face_mat,
                                True)

                            rect_area = mathlib.polygon_area(
                                np.array(rect[[0, 2, 2, 0]]),
                                np.array(rect[[1, 1, 3, 3]]))
                            landmarks_area = mathlib.polygon_area(
                                landmarks_bbox[:, 0], landmarks_bbox[:, 1])

                            if landmarks_area > 4 * rect_area:  #get rid of faces which umeyama-landmark-area > 4*detector-rect-area
                                continue

                        if self.debug_dir is not None:
                            LandmarksProcessor.draw_rect_landmarks(
                                debug_image,
                                rect,
                                image_landmarks,
                                self.image_size,
                                self.face_type,
                                transparent_mask=True)

                        if src_dflimg is not None:
                            #if extracting from dflimg copy it in order not to lose quality
                            output_file = str(self.output_path /
                                              filename_path.name)
                            if str(filename_path) != str(output_file):
                                shutil.copy(str(filename_path),
                                            str(output_file))
                        else:
                            output_file = '{}_{}{}'.format(
                                str(self.output_path / filename_path.stem),
                                str(face_idx), '.jpg')
                            cv2_imwrite(output_file, face_image,
                                        [int(cv2.IMWRITE_JPEG_QUALITY), 85])

                        DFLJPG.embed_data(
                            output_file,
                            face_type=FaceType.toString(self.face_type),
                            landmarks=face_image_landmarks.tolist(),
                            source_filename=filename_path.name,
                            source_rect=rect,
                            source_landmarks=image_landmarks.tolist(),
                            image_to_face_mat=image_to_face_mat)

                        result.append(output_file)
                        face_idx += 1

                if self.debug_dir is not None:
                    cv2_imwrite(debug_output_file, debug_image,
                                [int(cv2.IMWRITE_JPEG_QUALITY), 50])

                return result
Exemplo n.º 10
0
        def final_stage(
            data,
            image,
            face_type,
            image_size,
            jpeg_quality,
            output_debug_path=None,
            final_output_path=None,
        ):
            data.final_output_files = []
            filepath = data.filepath
            rects = data.rects
            landmarks = data.landmarks

            if output_debug_path is not None:
                debug_image = image.copy()

            face_idx = 0
            for rect, image_landmarks in zip(rects, landmarks):
                if image_landmarks is None:
                    continue

                rect = np.array(rect)

                if face_type == FaceType.MARK_ONLY:
                    image_to_face_mat = None
                    face_image = image
                    face_image_landmarks = image_landmarks
                else:
                    image_to_face_mat = LandmarksProcessor.get_transform_mat(
                        image_landmarks, image_size, face_type)

                    face_image = cv2.warpAffine(image, image_to_face_mat,
                                                (image_size, image_size),
                                                cv2.INTER_LANCZOS4)
                    face_image_landmarks = LandmarksProcessor.transform_points(
                        image_landmarks, image_to_face_mat)

                    landmarks_bbox = LandmarksProcessor.transform_points(
                        [(0, 0), (0, image_size - 1),
                         (image_size - 1, image_size - 1),
                         (image_size - 1, 0)], image_to_face_mat, True)

                    rect_area = mathlib.polygon_area(
                        np.array(rect[[0, 2, 2, 0]]).astype(np.float32),
                        np.array(rect[[1, 1, 3, 3]]).astype(np.float32))
                    landmarks_area = mathlib.polygon_area(
                        landmarks_bbox[:, 0].astype(np.float32),
                        landmarks_bbox[:, 1].astype(np.float32))

                    if not data.manual and face_type <= FaceType.FULL_NO_ALIGN and landmarks_area > 4 * rect_area:  #get rid of faces which umeyama-landmark-area > 4*detector-rect-area
                        continue

                    if output_debug_path is not None:
                        LandmarksProcessor.draw_rect_landmarks(
                            debug_image,
                            rect,
                            image_landmarks,
                            face_type,
                            image_size,
                            transparent_mask=True)

                output_path = final_output_path
                if data.force_output_path is not None:
                    output_path = data.force_output_path

                output_filepath = output_path / f"{filepath.stem}_{face_idx}.jpg"
                cv2_imwrite(output_filepath, face_image,
                            [int(cv2.IMWRITE_JPEG_QUALITY), jpeg_quality])

                dflimg = DFLJPG.load(output_filepath)
                dflimg.set_face_type(FaceType.toString(face_type))
                dflimg.set_landmarks(face_image_landmarks.tolist())
                dflimg.set_source_filename(filepath.name)
                dflimg.set_source_rect(rect)
                dflimg.set_source_landmarks(image_landmarks.tolist())
                dflimg.set_image_to_face_mat(image_to_face_mat)
                dflimg.save()

                data.final_output_files.append(output_filepath)
                face_idx += 1
            data.faces_detected = face_idx

            if output_debug_path is not None:
                cv2_imwrite(output_debug_path / (filepath.stem + '.jpg'),
                            debug_image, [int(cv2.IMWRITE_JPEG_QUALITY), 50])

            return data
Exemplo n.º 11
0
        def process_data(self, data):
            filename_path = Path(data[0])

            filename_path_str = str(filename_path)
            if self.cached_image[0] == filename_path_str:
                image = self.cached_image[1]
            else:
                image = cv2_imread(filename_path_str)
                self.cached_image = (filename_path_str, image)

            if image is None:
                self.log_err(
                    'Failed to extract %s, reason: cv2_imread() fail.' %
                    (str(filename_path)))
            else:
                if self.type == 'rects':
                    rects = self.e.extract_from_bgr(image)
                    return [str(filename_path), rects]

                elif self.type == 'landmarks':
                    rects = data[1]
                    landmarks = self.e.extract_from_bgr(image, rects)
                    return [str(filename_path), landmarks]

                elif self.type == 'final':
                    src_dflimg = None
                    (h, w, c) = image.shape
                    if h == w:
                        #extracting from already extracted jpg image?
                        if filename_path.suffix == '.jpg':
                            src_dflimg = DFLJPG.load(str(filename_path))

                    result = []
                    faces = data[1]

                    if self.debug:
                        debug_output_file = '{}{}'.format(
                            str(
                                Path(str(self.output_path) + '_debug') /
                                filename_path.stem), '.jpg')
                        debug_image = image.copy()

                    face_idx = 0
                    for face in faces:
                        rect = np.array(face[0])
                        image_landmarks = np.array(face[1])

                        if self.face_type == FaceType.MARK_ONLY:
                            face_image = image
                            face_image_landmarks = image_landmarks
                        else:
                            image_to_face_mat = LandmarksProcessor.get_transform_mat(
                                image_landmarks, self.image_size,
                                self.face_type)
                            face_image = cv2.warpAffine(
                                image, image_to_face_mat,
                                (self.image_size, self.image_size),
                                cv2.INTER_LANCZOS4)
                            face_image_landmarks = LandmarksProcessor.transform_points(
                                image_landmarks, image_to_face_mat)

                            landmarks_bbox = LandmarksProcessor.transform_points(
                                [(0, 0), (0, self.image_size - 1),
                                 (self.image_size - 1, self.image_size - 1),
                                 (self.image_size - 1, 0)], image_to_face_mat,
                                True)

                            rect_area = mathlib.polygon_area(
                                np.array(rect[[0, 2, 2, 0]]),
                                np.array(rect[[1, 1, 3, 3]]))
                            landmarks_area = mathlib.polygon_area(
                                landmarks_bbox[:, 0], landmarks_bbox[:, 1])

                            if landmarks_area > 4 * rect_area:  #get rid of faces which umeyama-landmark-area > 4*detector-rect-area
                                continue

                        if self.debug:
                            LandmarksProcessor.draw_rect_landmarks(
                                debug_image, rect, image_landmarks,
                                self.image_size, self.face_type)

                        output_file = '{}_{}{}'.format(
                            str(self.output_path / filename_path.stem),
                            str(face_idx), '.jpg')
                        face_idx += 1

                        if src_dflimg is not None:
                            #if extracting from dflimg just copy it in order not to lose quality
                            shutil.copy(str(filename_path), str(output_file))
                        else:
                            cv2_imwrite(output_file, face_image,
                                        [int(cv2.IMWRITE_JPEG_QUALITY), 85])

                        DFLJPG.embed_data(
                            output_file,
                            face_type=FaceType.toString(self.face_type),
                            landmarks=face_image_landmarks.tolist(),
                            source_filename=filename_path.name,
                            source_rect=rect,
                            source_landmarks=image_landmarks.tolist())

                        result.append(output_file)

                    if self.debug:
                        cv2_imwrite(debug_output_file, debug_image,
                                    [int(cv2.IMWRITE_JPEG_QUALITY), 50])

                    return result
            return None