Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

inference problem #21

Open
flynnamy opened this issue Aug 30, 2019 · 11 comments
Open

inference problem #21

flynnamy opened this issue Aug 30, 2019 · 11 comments

Comments

@flynnamy
Copy link

It shows that the results is good in dataset,but it depends on scale, center_w, center_h.If I want to do inference of an image without information of scale, center_w, center_h, how do I get scale and center_w,center_h accurately.if these variable are not accurate,the landmark is not good.So I must get accurate scale, center_w and center_h. Any suggestions?

@flynnamy
Copy link
Author

flynnamy commented Sep 1, 2019

It calculates scale, center_w, center_h depends groudth of points.But if we just want to do inference an image without groundth info, this algorithm how to work?Because we can not get scale, center_w, center_h.

@lfxx
Copy link

lfxx commented Sep 6, 2019

Maybe you need a face detector to locate the target face and then feed its location into network

@flynnamy
Copy link
Author

flynnamy commented Sep 6, 2019

@lfxx It can not do like this way.You can try use a detector to get box and scale.Then you can find the points of landmark is not right.

@lfxx
Copy link

lfxx commented Sep 6, 2019

Do you mean that inference single image in wild?Use a detector to get the target face's location is useful.Here is my scrpts ,let me know if it works!@flynnamy

# ------------------------------------------------------------------------------
# Created by Gaofeng(lfxx1994@gmail.com)
# ------------------------------------------------------------------------------

import os
import argparse

import torch
import torch.nn as nn
import torch.backends.cudnn as cudnn
import sys
import cv2

sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
import lib.models as models
from lib.config import config, update_config
from PIL import Image
import numpy as np
from lib.utils.transforms import crop
from lib.core.evaluation import decode_preds


def parse_args():
    parser = argparse.ArgumentParser(description='Train Face Alignment')

    parser.add_argument('--cfg',
                        default='experiments/300w/face_alignment_300w_hrnet_w18.yaml',
                        help='experiment configuration filename', type=str)
    parser.add_argument('--model-file', help='model parameters',
                        default='HR18-300W.pth', type=str)
    parser.add_argument('--imagepath', help='Path of the image to be detected', default='111.jpg',
                        type=str)
    parser.add_argument('--face', nargs='+', type=float, default=[911, 1281, 1254, 1731],
                        help='The coordinate [x1,y1,x2,y2] of a face')
    args = parser.parse_args()
    update_config(config, args)
    return args


def prepare_input(image, bbox, image_size):
    """

    :param image:The path to the image to be detected
    :param bbox:The bbox of target face
    :param image_size: refers to config file
    :return:
    """
    scale = max(bbox[2] - bbox[0], bbox[3] - bbox[1]) / 200
    center_w = (bbox[0] + bbox[2]) / 2
    center_h = (bbox[1] + bbox[3]) / 2
    center = torch.Tensor([center_w, center_h])
    scale *= 1.25
    img = np.array(Image.open(image).convert('RGB'), dtype=np.float32)
    mean = np.array([0.485, 0.456, 0.406], dtype=np.float32)
    std = np.array([0.229, 0.224, 0.225], dtype=np.float32)
    img = crop(img, center, scale, image_size, rot=0)
    img = img.astype(np.float32)
    img = (img / 255.0 - mean) / std
    img = img.transpose([2, 0, 1])
    img = torch.Tensor(img)
    img = img.unsqueeze(0)
    return img, center, scale


def main():
    args = parse_args()
    cudnn.benchmark = config.CUDNN.BENCHMARK
    cudnn.determinstic = config.CUDNN.DETERMINISTIC
    cudnn.enabled = config.CUDNN.ENABLED

    config.defrost()
    config.MODEL.INIT_WEIGHTS = False
    config.freeze()
    model = models.get_face_alignment_net(config)
    if config.GPUS is list:
        gpus = list(config.GPUS)
    else:
        gpus = [config.GPUS]
    model = nn.DataParallel(model, device_ids=gpus).cuda()

    # load model
    state_dict = torch.load(args.model_file)
    model.load_state_dict(state_dict)
    model.eval()
    inp, center, scale = prepare_input(args.imagepath, args.face, config.MODEL.IMAGE_SIZE)
    output = model(inp)
    score_map = output.data.cpu()
    preds = decode_preds(score_map, center, scale, [64, 64])
    preds = preds.numpy()
    cv2.namedWindow('test', 0)
    img_once = cv2.imread(args.imagepath)
    for i in preds[0, :, :]:
        cv2.circle(img_once, tuple(list(int(p) for p in i.tolist())), 2, (255, 255, 0), 1)
    cv2.imshow('test', img_once)
    if cv2.waitKey(0) == 27:
        cv2.destroyAllWindows()


if __name__ == '__main__':
    main()

At the same time,modify the line 79 of evaluation.py as follows:

    if scale is list:
        for i in range(coords.size(0)):
            preds[i] = transform_preds(coords[i], center[i], scale[i], res)
    else:
        for i in range(coords.size(0)):
            preds[i] = transform_preds(coords[i], center, scale, res)

@flynnamy
Copy link
Author

flynnamy commented Sep 6, 2019

@lfxx Yes,I mean inference an image in wild.In you scripts, you use box and scale depends on points groudtruth I know it works well.But if you do not know the information of box and scale,how to get accurate box and scale?If you use a detetcor to get these,Which detector d you use?

@flynnamy
Copy link
Author

flynnamy commented Sep 6, 2019

@lfxx Any solutions to do inference without know accurate box and scale?Even using detector,it will get large difference and I have tried.

@lfxx
Copy link

lfxx commented Sep 6, 2019

@lfxx Yes,I mean inference an image in wild.In you scripts, you use box and scale depends on points groudtruth I know it works well.But if you do not know the information of box and scale,how to get accurate box and scale?If you use a detetcor to get these,Which detector d you use?

I use RetinaFace to detect face,then feed the result into net ,it works well!

@flynnamy
Copy link
Author

flynnamy commented Sep 6, 2019

@lfxx Please try wflw model,I tried this with retinaface and a wild image.It failed! Please let me you know if it works!

@lfxx
Copy link

lfxx commented Sep 6, 2019

@lfxx Please try wflw model,I tried this with retinaface and a wild image.It failed! Please let me you know if it works!

Fix this BUG,have a try~

# ------------------------------------------------------------------------------
# Created by Gaofeng(lfxx1994@gmail.com)
# ------------------------------------------------------------------------------

import os
import argparse

import torch
import torch.nn as nn
import torch.backends.cudnn as cudnn
import sys
import cv2

sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
import lib.models as models
from lib.config import config, update_config
from PIL import Image
import numpy as np
from lib.utils.transforms import crop
from lib.core.evaluation import decode_preds


def parse_args():
    parser = argparse.ArgumentParser(description='Train Face Alignment')

    parser.add_argument('--cfg',
                        default='experiments/wflw/face_alignment_wflw_hrnet_w18.yaml',
                        help='experiment configuration filename', type=str)
    parser.add_argument('--model_file', help='model parameters',
                        default='HR18-WFLW.pth', type=str)
    parser.add_argument('--model_300W', help='if model is 300W,SET TRUE else FALSE',
                        default=False, type=bool)
    parser.add_argument('--imagepath', help='Path of the image to be detected', default='111.jpg',
                        type=str)
    parser.add_argument('--face', nargs='+', type=float, default=[930, 1314,1251,1727],
                        help='The coordinate [x1,y1,x2,y2] of a face')
    args = parser.parse_args()
    update_config(config, args)
    return args


def prepare_input(image, bbox, image_size):
    """

    :param image:The path of the image to be detected
    :param bbox:The bbox of target face
    :param image_size: refers to config file
    :return:
    """
    scale = max(bbox[2] - bbox[0], bbox[3] - bbox[1]) / 200
    center_w = (bbox[0] + bbox[2]) / 2
    center_h = (bbox[1] + bbox[3]) / 2
    center = torch.Tensor([center_w, center_h])
    scale *= 1.25
    img = np.array(Image.open(image).convert('RGB'), dtype=np.float32)
    mean = np.array([0.485, 0.456, 0.406], dtype=np.float32)
    std = np.array([0.229, 0.224, 0.225], dtype=np.float32)
    img = crop(img, center, scale, image_size, rot=0)
    img = img.astype(np.float32)
    img = (img / 255.0 - mean) / std
    img = img.transpose([2, 0, 1])
    img = torch.Tensor(img)
    img = img.unsqueeze(0)
    return img, center, scale


def main():
    args = parse_args()
    cudnn.benchmark = config.CUDNN.BENCHMARK
    cudnn.determinstic = config.CUDNN.DETERMINISTIC
    cudnn.enabled = config.CUDNN.ENABLED

    config.defrost()
    config.MODEL.INIT_WEIGHTS = False
    config.freeze()
    model = models.get_face_alignment_net(config)
    if config.GPUS is list:
        gpus = list(config.GPUS)
    else:
        gpus = [config.GPUS]
    model = nn.DataParallel(model, device_ids=gpus).cuda()

    # load model
    state_dict = torch.load(args.model_file)
    if args.model_300W:
        model.load_state_dict(state_dict)
    else:
        model.module.load_state_dict(state_dict)

    model.eval()
    inp, center, scale = prepare_input(args.imagepath, args.face, config.MODEL.IMAGE_SIZE)
    output = model(inp)
    score_map = output.data.cpu()
    preds = decode_preds(score_map, center, scale, [64, 64])
    preds = preds.numpy()
    cv2.namedWindow('test', 0)
    img_once = cv2.imread(args.imagepath)
    for i in preds[0, :, :]:
        cv2.circle(img_once, tuple(list(int(p) for p in i.tolist())), 2, (255, 255, 0), 1)
    cv2.imshow('test', img_once)
    if cv2.waitKey(0) == 27:
        cv2.destroyAllWindows()


if __name__ == '__main__':
    main()

@flynnamy
Copy link
Author

flynnamy commented Sep 7, 2019

@lfxx I made a mistake of scale calculation and it works.Thanks for your reply!

@alarafat
Copy link

@lfxx Would it be possible for you to add this as a demo or evaluation script in the project? It will be helpful for anyone who wants to try the model for quick try. However, thanks for this script :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants