Ejemplo n.º 1
0
def feature_writer(img_path):
    img_name = os.path.basename(img_path)
    source_img = im.open(img_path)

    af_obj = af.detect(source_img)

    # if the image has no face or you don't choose any key to detect, it will stop

    if not af_obj:
        print('{} has no face'.format(img_name))
        return False

    af_dict = af_obj[0]

    hair_color = af_dict.hair.color
    eye_color = af_dict.right_eye.color
    skin_color = af_dict.skin.color

    feat_list = [
        skin_color.r, skin_color.g, skin_color.b, hair_color.r, hair_color.g,
        hair_color.b, eye_color.r, eye_color.g, eye_color.b
    ]

    feat_list_norm = [value / 256 for value in feat_list]

    return feat_list
Ejemplo n.º 2
0
def cleanImagesFolder(curPath,
                      newPath,
                      res=None,
                      searchFaces=False,
                      faceThreshold=0.5):
    """
    Creates a new folder containing all the images
    from the current folder with anime faces on them, using the
    animeface library
    """
    createDir(newPath)

    images = glob(os.path.join(curPath, '*.jpg'))

    for image in images:
        try:
            im = Image.open(image)
            if res != None:
                if min(im.size) < res: continue
            if searchFaces:
                faces = animeface.detect(im)
                if not faces: continue  #Get rid of garbage
                if (faces[0].likelihood < faceThreshold):
                    continue  #Get rid of garbage

            imName = image.split('/')[-1]
            newImage = os.path.join(newPath, imName)
            copyfile(image, newImage)

        except OSError:
            continue
Ejemplo n.º 3
0
def find_face(img_path, parts=['face', 'eye']):
    img_name = os.path.basename(img_path)
    source_img = im.open(img_path)

    af_obj = af.detect(source_img)

    # if the image has no face or you don't choose any key to detect, it will stop
    if not af_obj or not parts:
        print('{} has no face'.format(img_name))
        return 1

    af_dict = af_obj[0]
    x, y, width, height = af_dict.face.pos.x, af_dict.face.pos.y, af_dict.face.pos.width, af_dict.face.pos.height
    draw = dr.Draw(source_img)

    if af_dict.likelihood < 0.9:
        return 1

    draw.rectangle(((x - 1, y - 1), (x + width - 1, y + height - 1)),
                   outline="rgb(160, 240, 60)")
    draw.rectangle(((x, y), (x + width, y + height)),
                   outline="rgb(160, 240, 60)")
    draw.rectangle(((x + 1, y + 1), (x + width + 1, y + height + 1)),
                   outline="rgb(160, 240, 60)")
    draw.text((x, y), 'face')

    draw.text((2, 0), 'L={0:03f}'.format(af_dict.likelihood))

    b_x, b_y = 0, 10
    hair_color = af_dict.hair.color
    draw.rectangle(((b_x, b_y), (b_x + 10, b_y + 10)),
                   fill=(hair_color.r, hair_color.g, hair_color.b),
                   outline='white')
    draw.text((b_x + 12, b_y), 'hair_color')

    eye_color = af_dict.right_eye.color
    draw.rectangle(((b_x, b_y + 10), (b_x + 10, b_y + 20)),
                   fill=(eye_color.r, eye_color.g, eye_color.b),
                   outline='white')
    draw.text((b_x + 12, b_y + 10), 'eye_color')

    if 'eye' in parts:
        eye_pos = af_dict.right_eye.pos
        x, y, width, height = af_dict.right_eye.pos.x, af_dict.right_eye.pos.y, af_dict.right_eye.pos.width, af_dict.right_eye.pos.height
        draw.rectangle(((x, y), (x + width, y + height)),
                       outline="rgb(160, 240, 60)")
        eye_pos = af_dict.left_eye.pos
        x, y, width, height = af_dict.left_eye.pos.x, af_dict.left_eye.pos.y, af_dict.left_eye.pos.width, af_dict.left_eye.pos.height
        draw.rectangle(((x, y), (x + width, y + height)),
                       outline="rgb(160, 240, 60)")
        #text shadows the face too much
        #draw.text((x,y), 'right_eye')

    if not os.path.exists(config.save_path):
        os.mkdir(config.save_path)

    source_img.save(os.path.join(config.save_path, '{}'.format(img_name)),
                    'JPEG')
    return 0
Ejemplo n.º 4
0
def face_detect(img):
    """
        Returns an animeface object.
        If more than one face detected, only the largest and most plausible face will be used.
        Returns one face object. If no face objects found, returns false. 

        Parameters:
            img: cv2 image
    """
    faces = animeface.detect(util.convert_cv2_to_pil_image(img))
    if (len(faces) == 0):
        return False
    return faces[0]
Ejemplo n.º 5
0
def mlp_anime_face_detect(image_path):
    img = cv2.imread(image_path) if type(image_path)==str else image_path  # 读取图片
    img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  # 图片灰度化
    img_gray = cv2.equalizeHist(img_gray)  # 直方图均衡化
    faces = animeface.detect(Image.fromarray(img_gray))  # 人脸检测
    for each in faces:  # 遍历所有检测到的动漫脸
        temp = each.face.pos
        x = temp.x
        y = temp.y
        w = temp.width
        h = temp.height
        img = cv2.rectangle(img, (x, y), (x+w, y+h), (255, 0, 255), 5)  # 绘制矩形框
    # cv2.imwrite(f'../result/mlp_anime_face_detect_{image_path[-5]}.jpg', img)  # 保存检测结果
    return img
Ejemplo n.º 6
0
def run_face_detection_with_python_animeface(input_image_path):
    res = []
    im = PIL.Image.open(input_image_path)
    faces = animeface.detect(im)
    for ff in faces:
        with tempfile.NamedTemporaryFile(delete=False) as temp_ff:
            temp_im = im.crop((
                ff.face.pos.x,
                ff.face.pos.y,
                ff.face.pos.x + ff.face.pos.width,
                ff.face.pos.y + ff.face.pos.height,
            ))
            name = '{}.jpg'.format(temp_ff.name)
            temp_im.save(name)
            res.append(name)
    return res
Ejemplo n.º 7
0
def get_face_landmarks(image):
    faceboxes = animeface.detect(image)
    assert len(faceboxes) == 1, "Face detector couldn't find one and only one face on the image."

    facebox = faceboxes[0]

    left_eye_center = (int(facebox.left_eye.pos.x + facebox.left_eye.pos.width / 2), int(facebox.left_eye.pos.y + facebox.left_eye.pos.height / 2))
    right_eye_center = (int(facebox.right_eye.pos.x + facebox.right_eye.pos.width / 2), int(facebox.right_eye.pos.y + facebox.right_eye.pos.height / 2))
    eye_center = tuple(np.average([left_eye_center, right_eye_center], axis=0).astype(int))

    return {
        'left-eye-center-pos': left_eye_center,
        'right-eye-center-pos': right_eye_center,
        'eye-center-pos': eye_center,
        'face-box': (facebox.face.pos.x, facebox.face.pos.y, facebox.face.pos.width, facebox.face.pos.height)
    }
Ejemplo n.º 8
0
def load_detect(img_path):
    """Read original image file, return the cropped face image in the size 96x96
    Input: A string indicates the image path
    Output: Detected face image in the size 96x96
    Note that there might be multiple faces in one image, 
    the output crossponding to the face with highest probability
    """
    im = Image.open(img_path)
    faces = animeface.detect(im)
    prob_list = []
    len_f = len(faces)
    if len_f == 0:
        return 0
    for i in range(len_f):
        prob_list.append(faces[i].likelihood)
    prob_array = np.array(prob_list)
    idx = np.argmax(prob_array)
    face_pos = faces[idx].face.pos
    im = faceCrop(im, face_pos, 0.5)
    return min_resize_crop(im, 96)
def split_fp(im):
    '''
    This function take image array: im(np.array).
    In detail, animeface API was applied to extract the coordinates of the four corners of anime face inside of this image.
    
    Return value(np.array): coordinates of the four corners of anime face inside of this image.
    '''
    faces = animeface.detect(im)
    if faces == []:
        return False
    else:
        fp = faces[0].face.pos
        list_1 = str(fp).split(';')
        list_1_1 = str(list_1[0]).split('(')
        list_1_2 = str(list_1[1]).split(')')
        list_1_1_1 = str(list_1_1[1]).split(',')
        list_1_2_1 = str(list_1_2[0]).split(',')
        list_final = [int(list_1_1_1[1]), int(list_1_1_1[1])+int(list_1_2_1[1]), int(list_1_1_1[0]), int(list_1_1_1[0])+int(list_1_2_1[0])]

        return np.array(list_final)
def load_detect(img_path):
    """Read original image file, return the cropped face image in the size 96x96

    Input: A string indicates the image path
    Output: Detected face image in the size 96x96

    Note that there might be multiple faces in one image, 
    the output crossponding to the face with highest probability
    """
    im = Image.open(img_path)
    faces = animeface.detect(im)
    prob_list = []
    len_f = len(faces)
    if len_f == 0:
        return 0
    for i in range(len_f):
        prob_list.append(faces[i].likelihood)
    prob_array = np.array(prob_list)
    idx = np.argmax(prob_array)
    face_pos = faces[idx].face.pos
    im = faceCrop(im, face_pos, 0.5)
    return min_resize_crop(im, 96)
Ejemplo n.º 11
0
def crop_face(fn):
    filename = os.path.join(IMG_PATH, fn)
    im = PIL.Image.open(filename)

    faces = animeface.detect(im)

    if len(faces) != 1:
        return None

    image = cv2.imread(filename, cv2.IMREAD_COLOR)

    def imcrop(img, bbox):
        x1, y1, x2, y2 = bbox
        if x1 < 0 or y1 < 0 or x2 > img.shape[1] or y2 > img.shape[0]:
            img, x1, x2, y1, y2 = pad_img_to_fit_bbox(img, x1, x2, y1, y2)
        return img[y1:y2, x1:x2, :]

    def pad_img_to_fit_bbox(img, x1, x2, y1, y2):
        img = np.pad(
            img,
            ((np.abs(np.minimum(0, y1)), np.maximum(y2 - img.shape[0], 0)),
             (np.abs(np.minimum(0, x1)), np.maximum(x2 - img.shape[1], 0)),
             (0, 0)),
            mode="constant",
            constant_values=255)
        y1 += np.abs(np.minimum(0, y1))
        y2 += np.abs(np.minimum(0, y1))
        x1 += np.abs(np.minimum(0, x1))
        x2 += np.abs(np.minimum(0, x1))
        return img, x1, x2, y1, y2

    for face in faces:
        L_x = face.left_eye.pos.x + face.left_eye.pos.height // 2
        L_y = face.left_eye.pos.y + face.left_eye.pos.width // 2
        R_x = face.right_eye.pos.x + face.right_eye.pos.height // 2
        R_y = face.right_eye.pos.y + face.right_eye.pos.width // 2

        dx = L_x - R_x
        dy = L_y - R_y

        deg = math.atan(dy / dx) * 360 / (2 * math.pi)
        if math.fabs(deg) > 60:
            deg = 0.0  # something wrong???

        print(dx, dy, deg)

        x = face.face.pos.x
        y = face.face.pos.y
        w = face.face.pos.width
        h = face.face.pos.height

        cx = x + h // 2
        cy = y + w // 2

        image = np.pad(image, ((2 * x, 2 * x), (2 * y, 2 * y), (0, 0)),
                       mode="constant",
                       constant_values=255)
        rows, cols, _ = image.shape

        M = cv2.getRotationMatrix2D((0 / 2, 0 / 2), deg, 1)
        image = cv2.warpAffine(image,
                               M, (cols, rows),
                               borderValue=(255, 255, 255),
                               flags=cv2.INTER_CUBIC)

        faces = animeface.detect(PIL.Image.fromarray(image))
        if len(faces) != 1:
            continue

        face = faces[0]

        x = face.face.pos.x
        y = face.face.pos.y
        w = face.face.pos.width + 10
        h = face.face.pos.height + 10

        chinx = face.chin.pos.x
        chiny = face.chin.pos.y

        cx = x + h // 2
        cy = y + w // 2

        d = h

        cy = chiny - d + d // 3

        if cy - d < 0:
            cy -= (cy - d) // 2

        image = imcrop(image, (cx - d, cy - d, cx + d, cy + d))

        cv2.imwrite(os.path.join(FINAL_IMG_PATH, fn), image)
# data scraping from the web , install the data below packages and run the commands to download the data 

!pip install --upgrade gallery-dl
!pip install animeface
!gallery-dl https://danbooru.donmai.us/posts?tags=face

import animeface

total_num_faces = 0

for index,filename in enumerate(glob.glob('your data path')):
  print(filename)

  try:
    im = Image.open(filename)
    faces = animeface.detect(im)
  except Exception as e:
    print("Exception:{}".format(e))

    continue
    if len(faces) == 0:
      print("no faces found")
      continue

      fp = faces[0].face.pos
      coordinates = (fp.x,fp.y,fp.x+fp.width,fp.y+fp.height)
      cropped_image = im.crop(coordinates)
      cropped_image = cropped_image.resize((64,64),Image.ANTIALIAS)

  cropped_image.save("{}".format(filename))
Ejemplo n.º 13
0
face_cascade = cv2.CascadeClassifier(
    r"/code/cascaders/lbpcascade_animeface.xml")

i = 1
for file in files:
    if os.path.isdir(file): continue
    print(path + file)
    img = cv2.imread(path + file)
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    face_rects = face_cascade.detectMultiScale(gray,
                                               scaleFactor=1.1,
                                               minNeighbors=3,
                                               minSize=(100, 100))

    for (x, y, w, h) in face_rects:
        cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2)

    im = PIL.Image.open(path + file)
    gray = ImageOps.grayscale(im)
    faces = animeface.detect(gray)

    for face in faces:
        x = face.face.pos.x
        y = face.face.pos.y
        w = face.face.pos.width
        h = face.face.pos.height
        cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)

    cv2.imwrite(r"/code/data/face/" + str(i) + ".jpg", img)
    i += 1
Ejemplo n.º 14
0
def get_faces(img, db_session=None, c_model=None):
    detector_name = 'python_animeface'
    create_a_new_face_model = False
    af_faces = animeface.detect(img)
    for ff in af_faces:
        face_model = None
        pos = vars(ff.face.pos)  # NOQA
        color_tags = {
            key: value.color
            for key, value in vars(ff).items() if hasattr(value, 'color')
        }
        face_dict = {
            'detector': detector_name,
            'pos': ff.face.pos,
            'likelihood': ff.likelihood,
            'colors': color_tags,
        }
        if db_session and c_model and c_model.faces:
            # search any existing faces
            for ff_model in c_model.faces:
                same_coordinate = [x for x in pos.values()
                                   ] == list(ff_model.pos())
                if same_coordinate and ff_model.method == detector_name:
                    face_model = ff_model
                    break
            #  update or create face_model
            if face_model:
                face_model.likelihood = ff.likelihood
                # update color tags on face
                # by removing existing color vlaue
                c_tag_list = []
                for color_m in face_model.color_tags:
                    if color_m.value not in color_tags.values():
                        c_tag_list.append(color_m)
                for key, value in color_tags.items():
                    color_m, _ = models.get_or_create(
                        db_session,
                        models.ColorTag,
                        value=key,
                        color_value=get_hex_value(value.r, value.g, value.b))
                    db_session.add(color_m)
                    c_tag_list.append(color_m)
                db_session.add(face_model)
                face_model.color_tags = c_tag_list
            else:
                create_a_new_face_model = True
        elif db_session and c_model:
            create_a_new_face_model = True
        if create_a_new_face_model:
            face_model = models.Face(checksum=c_model,
                                     method=detector_name,
                                     likelihood=ff.likelihood)
            for key, value in pos.items():
                setattr(face_model, 'pos_{}'.format(key), value)
            for key, value in color_tags.items():
                color_m, _ = models.get_or_create(db_session,
                                                  models.ColorTag,
                                                  value=key,
                                                  color_value=get_hex_value(
                                                      value.r, value.g,
                                                      value.b))
                face_model.color_tags.append(color_m)
                db_session.add(color_m)
            db_session.add(face_model)
        yield [face_dict, face_model]