Beispiel #1
0
    def __init__(self,
                 img,
                 mask=None,
                 ie_polys=None,
                 get_status_lines_func=None):
        self.img = imagelib.normalize_channels(img, 3)
        h, w, c = img.shape
        ph, pw = h // 4, w // 4

        if mask is not None:
            self.mask = imagelib.normalize_channels(mask, 3)
        else:
            self.mask = np.zeros((h, w, 3))
        self.get_status_lines_func = get_status_lines_func

        self.state_prop = self.STATE_NONE

        self.w, self.h = w, h
        self.pw, self.ph = pw, ph
        self.pwh = np.array([self.pw, self.ph])
        self.pwh2 = np.array([self.pw * 2, self.ph * 2])
        self.sw, self.sh = w + pw * 2, h + ph * 2

        if ie_polys is None:
            ie_polys = IEPolys()
        self.ie_polys = ie_polys

        self.polys_mask = None

        self.mouse_x = self.mouse_y = 9999
        self.screen_status_block = None
        self.screen_status_block_dirty = True
        self.screen_changed = True
Beispiel #2
0
def ConvertMasked(cfg, frame_info):
    img_bgr_uint8 = cv2_imread(frame_info.filename)
    img_bgr_uint8 = imagelib.normalize_channels(img_bgr_uint8, 3)
    img_bgr = img_bgr_uint8.astype(np.float32) / 255.0

    outs = []
    for face_num, img_landmarks in enumerate(frame_info.landmarks_list):
        out_img, out_img_merging_mask = ConvertMaskedFace(
            cfg, frame_info, img_bgr_uint8, img_bgr, img_landmarks)
        outs += [(out_img, out_img_merging_mask)]

    #Combining multiple face outputs
    final_img = None
    for img, merging_mask in outs:
        h, w, c = img.shape

        if final_img is None:
            final_img = img
        else:
            merging_mask = merging_mask[..., 0:1]
            if c == 3:
                final_img = final_img * (1 - merging_mask) + img * merging_mask
            elif c == 4:
                final_img_bgr = final_img[..., 0:3] * (
                    1 - merging_mask) + img[..., 0:3] * merging_mask
                final_img_mask = np.clip(final_img[..., 3:4] + img[..., 3:4],
                                         0, 1)
                final_img = np.concatenate([final_img_bgr, final_img_mask], -1)

    return (final_img * 255).astype(np.uint8)
Beispiel #3
0
def ConvertMasked(predictor_func, predictor_input_shape, cfg, frame_info):
    img_bgr_uint8 = cv2_imread(frame_info.filename)
    img_bgr_uint8 = imagelib.normalize_channels(img_bgr_uint8, 3)
    img_bgr = img_bgr_uint8.astype(np.float32) / 255.0

    outs = []
    for face_num, img_landmarks in enumerate(frame_info.landmarks_list):
        out_img, out_img_merging_mask = ConvertMaskedFace(
            predictor_func, predictor_input_shape, cfg, frame_info,
            img_bgr_uint8, img_bgr, img_landmarks)
        outs += [(out_img, out_img_merging_mask)]

    #Combining multiple face outputs
    final_img = None
    final_mask = None
    for img, merging_mask in outs:
        h, w, c = img.shape

        if final_img is None:
            final_img = img
            final_mask = merging_mask
        else:
            final_img = final_img * (1 - merging_mask) + img * merging_mask
            final_mask = np.clip(final_mask + merging_mask, 0, 1)

    if cfg.export_mask_alpha:
        final_img = np.concatenate([final_img, final_mask], -1)

    return (final_img * 255).astype(np.uint8)
Beispiel #4
0
    def __init__(self,
                 img,
                 prev_images,
                 next_images,
                 mask=None,
                 ie_polys=None,
                 get_status_lines_func=None):
        self.img = imagelib.normalize_channels(img, 3)
        h, w, c = img.shape

        if h != w and w != 256:
            #to support any square res, scale img,mask and ie_polys to 256, then scale ie_polys back on .get_ie_polys()
            raise Exception(
                "MaskEditor does not support image size != 256x256")

        ph, pw = h // 4, w // 4  #pad wh

        self.prev_images = prev_images
        self.next_images = next_images

        if mask is not None:
            self.mask = imagelib.normalize_channels(mask, 3)
        else:
            self.mask = np.zeros((h, w, 3))
        self.get_status_lines_func = get_status_lines_func

        self.state_prop = self.STATE_NONE

        self.w, self.h = w, h
        self.pw, self.ph = pw, ph
        self.pwh = np.array([self.pw, self.ph])
        self.pwh2 = np.array([self.pw * 2, self.ph * 2])
        self.sw, self.sh = w + pw * 2, h + ph * 2
        self.prwh = 64  #preview wh

        if ie_polys is None:
            ie_polys = IEPolys()
        self.ie_polys = ie_polys

        self.polys_mask = None
        self.preview_images = None

        self.mouse_x = self.mouse_y = 9999
        self.screen_status_block = None
        self.screen_status_block_dirty = True
        self.screen_changed = True
Beispiel #5
0
def process_frame_info(frame_info, inp_sh):
    img_uint8 = cv2_imread (frame_info.filename)
    img_uint8 = imagelib.normalize_channels (img_uint8, 3)        
    img = img_uint8.astype(np.float32) / 255.0        

    img_mat = LandmarksProcessor.get_transform_mat (frame_info.landmarks_list[0], inp_sh[0], face_type=FaceType.FULL_NO_ALIGN)
    img = cv2.warpAffine( img, img_mat, inp_sh[0:2], borderMode=cv2.BORDER_REPLICATE, flags=cv2.INTER_CUBIC )
    return img
Beispiel #6
0
    def combine_screens(self, screens):

        screens_len = len(screens)

        new_screens = []
        for screen, padded_overlay in screens:
            screen_img = np.zeros((self.sh, self.sw, 3), dtype=np.float32)

            screen = imagelib.normalize_channels(screen, 3)
            h, w, c = screen.shape

            screen_img[self.ph:-self.ph, self.pw:-self.pw, :] = screen

            if padded_overlay is not None:
                screen_img = screen_img + padded_overlay

            screen_img = np.clip(screen_img * 255, 0, 255).astype(np.uint8)
            new_screens.append(screen_img)

        return np.concatenate(new_screens, axis=1)
Beispiel #7
0
def sort_by_vggface(input_path):
    io.log_info("Sorting by face similarity using VGGFace model...")

    model = VGGFace()

    final_img_list = []
    trash_img_list = []

    image_paths = Path_utils.get_image_paths(input_path)
    img_list = [(x, ) for x in image_paths]
    img_list_len = len(img_list)
    img_list_range = [*range(img_list_len)]

    feats = [None] * img_list_len
    for i in io.progress_bar_generator(img_list_range, "Loading"):
        img = cv2_imread(img_list[i][0]).astype(np.float32)
        img = imagelib.normalize_channels(img, 3)
        img = cv2.resize(img, (224, 224))
        img = img[..., ::-1]
        img[..., 0] -= 93.5940
        img[..., 1] -= 104.7624
        img[..., 2] -= 129.1863
        feats[i] = model.predict(img[None, ...])[0]

    tmp = np.zeros((img_list_len, ))
    float_inf = float("inf")
    for i in io.progress_bar_generator(range(img_list_len - 1), "Sorting"):
        i_feat = feats[i]

        for j in img_list_range:
            tmp[j] = npla.norm(i_feat - feats[j]) if j >= i + 1 else float_inf

        idx = np.argmin(tmp)

        img_list[i + 1], img_list[idx] = img_list[idx], img_list[i + 1]
        feats[i + 1], feats[idx] = feats[idx], feats[i + 1]

    return img_list, trash_img_list
Beispiel #8
0
        def process_data(self, data):
            idx, filename = data
            filename_path = Path(filename)
            files_processed = 1
            faces_processed = 0

            output_filename_path = self.output_path / (filename_path.stem +
                                                       '.png')

            if (self.converter.type == Converter.TYPE_FACE or self.converter.type == Converter.TYPE_FACE_AVATAR ) \
                   and filename_path.stem not in self.alignments.keys():
                if not self.debug:
                    self.log_info(
                        'no faces found for %s, copying without faces' %
                        (filename_path.name))

                    if filename_path.suffix == '.png':
                        shutil.copy(str(filename_path),
                                    str(output_filename_path))
                    else:
                        image = cv2_imread(str(filename_path))
                        cv2_imwrite(str(output_filename_path), image)
            else:
                image = (cv2_imread(str(filename_path)) / 255.0).astype(
                    np.float32)
                image = normalize_channels(image, 3)

                if self.converter.type == Converter.TYPE_IMAGE:
                    image = self.converter.cli_convert_image(
                        image, None, self.debug)

                    if self.debug:
                        return (1, image)

                    faces_processed = 1

                elif self.converter.type == Converter.TYPE_IMAGE_WITH_LANDMARKS:
                    #currently unused
                    if filename_path.suffix == '.png':
                        dflimg = DFLPNG.load(str(filename_path))
                    elif filename_path.suffix == '.jpg':
                        dflimg = DFLJPG.load(str(filename_path))
                    else:
                        dflimg = None

                    if dflimg is not None:
                        image_landmarks = dflimg.get_landmarks()

                        image = self.converter.convert_image(
                            image, image_landmarks, self.debug)

                        if self.debug:
                            raise NotImplementedError
                            #for img in image:
                            #    io.show_image ('Debug convert', img )
                            #    cv2.waitKey(0)
                        faces_processed = 1
                    else:
                        self.log_err("%s is not a dfl image file" %
                                     (filename_path.name))

                elif self.converter.type == Converter.TYPE_FACE or self.converter.type == Converter.TYPE_FACE_AVATAR:

                    ava_face = None
                    if self.converter.type == Converter.TYPE_FACE_AVATAR:
                        ava_filename_path = self.avatar_image_paths[idx]
                        ava_face = (cv2_imread(str(ava_filename_path)) /
                                    255.0).astype(np.float32)
                        ava_face = normalize_channels(ava_face, 3)
                    faces = self.alignments[filename_path.stem]

                    if self.debug:
                        debug_images = []

                    for face_num, image_landmarks in enumerate(faces):
                        try:
                            if self.debug:
                                self.log_info(
                                    '\nConverting face_num [%d] in file [%s]' %
                                    (face_num, filename_path))

                            if self.debug:
                                debug_images += self.converter.cli_convert_face(
                                    image,
                                    image_landmarks,
                                    self.debug,
                                    avaperator_face_bgr=ava_face)
                            else:
                                image = self.converter.cli_convert_face(
                                    image,
                                    image_landmarks,
                                    self.debug,
                                    avaperator_face_bgr=ava_face)

                        except Exception as e:
                            e_str = traceback.format_exc()
                            if 'MemoryError' in e_str:
                                raise Subprocessor.SilenceException
                            else:
                                raise Exception(
                                    'Error while converting face_num [%d] in file [%s]: %s'
                                    % (face_num, filename_path, e_str))

                    if self.debug:
                        return (1, debug_images)

                    faces_processed = len(faces)

                if not self.debug:
                    cv2_imwrite(str(output_filename_path),
                                (image * 255).astype(np.uint8))

            return (0, files_processed, faces_processed)
Beispiel #9
0
    def make_screen(self):
        screen_overlay = self.get_screen_overlay()
        final_mask = self.get_mask()

        masked_img = self.img * final_mask * 0.5 + self.img * (1 - final_mask)

        pink = np.full((self.h, self.w, 3), (1, 0, 1))
        pink_masked_img = self.img * final_mask + pink * (1 - final_mask)

        screens = [
            (self.img, screen_overlay),
            (masked_img, screen_overlay),
            (pink_masked_img, screen_overlay),
        ]
        screens = self.combine_screens(screens)

        if self.preview_images is None:
            sh, sw, sc = screens.shape

            prh, prw = self.prwh, self.prwh

            total_w = sum ([ img.shape[1] for (t,img) in self.prev_images ]) + \
                      sum ([ img.shape[1] for (t,img) in self.next_images ])

            total_images_len = len(self.prev_images) + len(self.next_images)

            max_hor_images_count = sw // prw
            max_side_images_count = (max_hor_images_count - 1) // 2

            prev_images = self.prev_images[-max_side_images_count:]
            next_images = self.next_images[:max_side_images_count]

            border = 2

            max_wh_bordered = (prw - border * 2, prh - border * 2)

            prev_images = [(t,
                            cv2.resize(imagelib.normalize_channels(img, 3),
                                       max_wh_bordered))
                           for t, img in prev_images]
            next_images = [(t,
                            cv2.resize(imagelib.normalize_channels(img, 3),
                                       max_wh_bordered))
                           for t, img in next_images]

            for images in [prev_images, next_images]:
                for i, (t, img) in enumerate(images):
                    new_img = np.zeros((prh, prw, sc))
                    new_img[border:-border, border:-border] = img

                    if t == 2:
                        cv2.line(new_img, (prw // 2, int(prh // 1.5)),
                                 (int(prw / 1.5), prh), (0, 1, 0),
                                 thickness=2)
                        cv2.line(new_img, (int(prw / 1.5), prh),
                                 (prw, prh // 2), (0, 1, 0),
                                 thickness=2)
                    elif t == 1:
                        cv2.line(new_img, (prw // 2, prh // 2), (prw, prh),
                                 (0, 0, 1),
                                 thickness=2)
                        cv2.line(new_img, (prw // 2, prh), (prw, prh // 2),
                                 (0, 0, 1),
                                 thickness=2)

                    images[i] = new_img

            preview_images = []
            if len(prev_images) > 0:
                preview_images += [np.concatenate(prev_images, axis=1)]

            img = np.full((prh, prw, sc), (0, 0, 1), dtype=np.float)
            img[border:-border,
                border:-border] = cv2.resize(self.img, max_wh_bordered)

            preview_images += [img]

            if len(next_images) > 0:
                preview_images += [np.concatenate(next_images, axis=1)]

            preview_images = np.concatenate(preview_images, axis=1)

            left_pad = sw // 2 - len(prev_images) * prw - prw // 2
            right_pad = sw // 2 - len(next_images) * prw - prw // 2

            preview_images = np.concatenate([
                np.zeros((preview_images.shape[0], left_pad,
                          preview_images.shape[2])), preview_images,
                np.zeros((preview_images.shape[0], right_pad,
                          preview_images.shape[2]))
            ],
                                            axis=1)
            self.preview_images = np.clip(preview_images * 255, 0,
                                          255).astype(np.uint8)

        status_img = self.get_screen_status_block(screens.shape[1],
                                                  screens.shape[2])

        result = np.concatenate([self.preview_images, screens, status_img],
                                axis=0)

        return result
Beispiel #10
0
    def get_data(self, host_dict):
        if not self.manual:
            if len(self.input_data) > 0:
                return self.input_data.pop(0)
        else:
            need_remark_face = False
            redraw_needed = False
            while len(self.input_data) > 0:
                data = self.input_data[0]
                filename, data_rects, data_landmarks = data.filename, data.rects, data.landmarks
                is_frame_done = False

                if need_remark_face:  # need remark image from input data that already has a marked face?
                    need_remark_face = False
                    if len(
                            data_rects
                    ) != 0:  # If there was already a face then lock the rectangle to it until the mouse is clicked
                        self.rect = data_rects.pop()
                        self.landmarks = data_landmarks.pop()
                        data_rects.clear()
                        data_landmarks.clear()
                        redraw_needed = True
                        self.rect_locked = True
                        self.rect_size = (self.rect[2] - self.rect[0]) / 2
                        self.x = (self.rect[0] + self.rect[2]) / 2
                        self.y = (self.rect[1] + self.rect[3]) / 2

                if len(data_rects) == 0:
                    if self.cache_original_image[0] == filename:
                        self.original_image = self.cache_original_image[1]
                    else:
                        self.original_image = imagelib.normalize_channels(
                            cv2_imread(filename), 3)

                        self.cache_original_image = (filename,
                                                     self.original_image)

                    (h, w, c) = self.original_image.shape
                    self.view_scale = 1.0 if self.manual_window_size == 0 else self.manual_window_size / (
                        h * (16.0 / 9.0))

                    if self.cache_image[0] == (h, w, c) + (self.view_scale,
                                                           filename):
                        self.image = self.cache_image[1]
                    else:
                        self.image = cv2.resize(self.original_image, (int(
                            w * self.view_scale), int(h * self.view_scale)),
                                                interpolation=cv2.INTER_LINEAR)
                        self.cache_image = ((h, w, c) +
                                            (self.view_scale, filename),
                                            self.image)

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

                    sh = (0, 0, w, min(100, h))
                    if self.cache_text_lines_img[0] == sh:
                        self.text_lines_img = self.cache_text_lines_img[1]
                    else:
                        self.text_lines_img = (imagelib.get_draw_text_lines(
                            self.image, sh, [
                                '[Mouse click] - lock/unlock selection',
                                '[Mouse wheel] - change rect',
                                '[Enter] / [Space] - confirm / skip frame',
                                '[,] [.]- prev frame, next frame. [Q] - skip remaining frames',
                                '[a] - accuracy on/off (more fps)',
                                '[h] - hide this help'
                            ], (1, 1, 1)) * 255).astype(np.uint8)

                        self.cache_text_lines_img = (sh, self.text_lines_img)

                    while True:
                        io.process_messages(0.0001)

                        new_x = self.x
                        new_y = self.y
                        new_rect_size = self.rect_size

                        mouse_events = io.get_mouse_events(self.wnd_name)
                        for ev in mouse_events:
                            (x, y, ev, flags) = ev
                            if ev == io.EVENT_MOUSEWHEEL and not self.rect_locked:
                                mod = 1 if flags > 0 else -1
                                diff = 1 if new_rect_size <= 40 else np.clip(
                                    new_rect_size / 10, 1, 10)
                                new_rect_size = max(5,
                                                    new_rect_size + diff * mod)
                            elif ev == io.EVENT_LBUTTONDOWN:
                                self.rect_locked = not self.rect_locked
                                self.extract_needed = True
                            elif not self.rect_locked:
                                new_x = np.clip(x, 0, w - 1) / self.view_scale
                                new_y = np.clip(y, 0, h - 1) / self.view_scale

                        key_events = io.get_key_events(self.wnd_name)
                        key, chr_key, ctrl_pressed, alt_pressed, shift_pressed = key_events[
                            -1] if len(key_events) > 0 else (0, 0, False,
                                                             False, False)

                        if key == ord('\r') or key == ord('\n'):
                            #confirm frame
                            is_frame_done = True
                            data_rects.append(self.rect)
                            data_landmarks.append(self.landmarks)
                            break
                        elif key == ord(' '):
                            #confirm skip frame
                            is_frame_done = True
                            break
                        elif key == ord(',') and len(self.result) > 0:
                            #go prev frame

                            if self.rect_locked:
                                self.rect_locked = False
                                # Only save the face if the rect is still locked
                                data_rects.append(self.rect)
                                data_landmarks.append(self.landmarks)

                            self.input_data.insert(0, self.result.pop())
                            io.progress_bar_inc(-1)
                            need_remark_face = True

                            break
                        elif key == ord('.'):
                            #go next frame

                            if self.rect_locked:
                                self.rect_locked = False
                                # Only save the face if the rect is still locked
                                data_rects.append(self.rect)
                                data_landmarks.append(self.landmarks)

                            need_remark_face = True
                            is_frame_done = True
                            break
                        elif key == ord('q'):
                            #skip remaining

                            if self.rect_locked:
                                self.rect_locked = False
                                data_rects.append(self.rect)
                                data_landmarks.append(self.landmarks)

                            while len(self.input_data) > 0:
                                self.result.append(self.input_data.pop(0))
                                io.progress_bar_inc(1)

                            break

                        elif key == ord('h'):
                            self.hide_help = not self.hide_help
                            break
                        elif key == ord('a'):
                            self.landmarks_accurate = not self.landmarks_accurate
                            break

                        if self.x != new_x or \
                           self.y != new_y or \
                           self.rect_size != new_rect_size or \
                           self.extract_needed or \
                           redraw_needed:
                            self.x = new_x
                            self.y = new_y
                            self.rect_size = new_rect_size
                            self.rect = (int(self.x - self.rect_size),
                                         int(self.y - self.rect_size),
                                         int(self.x + self.rect_size),
                                         int(self.y + self.rect_size))

                            if redraw_needed:
                                redraw_needed = False
                                return ExtractSubprocessor.Data(
                                    filename,
                                    landmarks_accurate=self.landmarks_accurate)
                            else:
                                return ExtractSubprocessor.Data(
                                    filename,
                                    rects=[self.rect],
                                    landmarks_accurate=self.landmarks_accurate)

                else:
                    is_frame_done = True

                if is_frame_done:
                    self.result.append(data)
                    self.input_data.pop(0)
                    io.progress_bar_inc(1)
                    self.extract_needed = True
                    self.rect_locked = False

        return None
Beispiel #11
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,
                    )
Beispiel #12
0
        def process_data(self, data):
            files_processed = 1
            faces_processed = 0
            
            idx, = data
            filename = self.input_data[idx][0]
            filename_path = Path(filename)

            output_filename_path = self.output_path / (filename_path.stem + '.png')
            image = None
            
            if self.converter.type == Converter.TYPE_FACE:
                if filename_path.stem not in self.alignments.keys():
                    if not self.debug:
                        self.log_info ( 'no faces found for %s, copying without faces' % (filename_path.name) )

                        if filename_path.suffix == '.png':
                            shutil.copy ( str(filename_path), str(output_filename_path) )
                        else:
                            image = cv2_imread(str(filename_path))
                            cv2_imwrite ( str(output_filename_path), image )
                else:
                    image = (cv2_imread(str(filename_path)) / 255.0).astype(np.float32)
                    image = normalize_channels (image, 3)
                
                    faces = self.alignments[filename_path.stem]

                    if self.debug:
                        debug_images = []

                    for face_num, image_landmarks in enumerate(faces):
                        try:
                            if self.debug:
                                self.log_info ( '\nConverting face_num [%d] in file [%s]' % (face_num, filename_path) )

                            if self.debug:
                                debug_images += self.converter.cli_convert_face(image, image_landmarks, self.debug)
                            else:
                                image = self.converter.cli_convert_face(image, image_landmarks, self.debug)

                        except Exception as e:
                            e_str = traceback.format_exc()
                            if 'MemoryError' in e_str:
                                raise Subprocessor.SilenceException
                            else:
                                raise Exception( 'Error while converting face_num [%d] in file [%s]: %s' % (face_num, filename_path, e_str) )

                    if self.debug:
                        return (1, debug_images)

                    faces_processed = len(faces)
            elif self.converter.type == Converter.TYPE_IMAGE:
                image = (cv2_imread(str(filename_path)) / 255.0).astype(np.float32)
                image = normalize_channels (image, 3)
                image = self.converter.cli_convert_image(image, None, self.debug)

                if self.debug:
                    return (1, image)
                    
                faces_processed = 1  
            elif self.converter.type == Converter.TYPE_FACE_AVATAR:
                max_idx = len(self.input_data)-1
                
                i0 = max (idx-1, 0)
                i1 = idx
                i2 = min (max_idx, idx+1)
                
                f0 = (cv2_imread( self.input_data[i0][0] ) / 255.0).astype(np.float32)
                f0_lmrk = self.input_data[i0][1]
                f1 = (cv2_imread( self.input_data[i1][0] ) / 255.0).astype(np.float32)
                f1_lmrk = self.input_data[i1][1]
                f2 = (cv2_imread( self.input_data[i2][0] ) / 255.0).astype(np.float32)
                f2_lmrk = self.input_data[i2][1]
                
                f0, f1, f2 = [ normalize_channels (f, 3) for f in [f0,f1,f2] ]
                
                image = self.converter.cli_convert_face(f0, f0_lmrk, f1, f1_lmrk, f2, f2_lmrk,  self.debug)
                
                output_filename_path = self.output_path / self.input_data[idx][2] 

                if self.debug:
                    return (1, image)

                faces_processed = 1
                
            if image is not None and not self.debug:
                cv2_imwrite (str(output_filename_path), (image*255).astype(np.uint8) )

            return (0, files_processed, faces_processed)