Lipstick ain't enough: Beyond Color-Matching for In-the-Wild Makeup Transfer (CVPR 2021)

Overview
Table of Content
  1. Introduction
  2. Datasets
  3. Getting Started
  4. Training & Evaluation

CPM: Color-Pattern Makeup Transfer

  • CPM is a holistic makeup transfer framework that outperforms previous state-of-the-art models on both light and extreme makeup styles.
  • CPM consists of an improved color transfer branch (based on BeautyGAN) and a novel pattern transfer branch.
  • We also introduce 4 new datasets (both real and synthesis) to train and evaluate CPM.
teaser.png
CPM can replicate both colors and patterns from a reference makeup style to another image.

Details of the dataset construction, model architecture, and experimental results can be found in our following paper:

@inproceedings{m_Nguyen-etal-CVPR21,
  author = {Thao Nguyen and Anh Tran and Minh Hoai},
  title = {Lipstick ain't enough: Beyond Color Matching for In-the-Wild Makeup Transfer},
  year = {2021},
  booktitle = {Proceedings of the {IEEE} Conference on Computer Vision and Pattern Recognition (CVPR)}
}

Please CITE our paper whenever our datasets or model implementation is used to help produce published results or incorporated into other software.

Open In Colab - arXiv - project page


Datasets

We introduce 4 new datasets: CPM-Real, CPM-Synt-1, CPM-Synt-2, and Stickers datasets. Besides, we also use published LADN's Dataset & Makeup Transfer Dataset.

CPM-Real and Stickers are crawled from Google Image Search, while CPM-Synt-1 & 2 are built on Makeup Transfer and Stickers. (Click on dataset name to download)

Name #imgs Description -
CPM-Real 3895 real - makeup styles CPM-Real.png
CPM-Synt-1 5555 synthesis - makeup images with pattern segmentation mask ./imgs/CPM-Synt-1.png
CPM-Synt-2 1625 synthesis - triplets: makeup, non-makeup, ground-truth ./imgs/CPM-Synt-2.png
Stickers 577 high-quality images with alpha channel Stickers.png

Dataset Folder Structure can be found here.

By downloading these datasets, USER agrees:

  • to use these datasets for research or educational purposes only
  • to not distribute or part of these datasets in any original or modified form.
  • and to cite our paper whenever these datasets are employed to help produce published results.

Getting Started

Requirements
Installation
# clone the repo
git clone https://github.com/VinAIResearch/CPM.git
cd CPM

# install dependencies
conda env create -f environment.yml
Download pre-trained models
mkdir checkpoints
cd checkpoints
wget https://public.vinai.io/CPM_checkpoints/color.pth
wget https://public.vinai.io/CPM_checkpoints/pattern.pth
  • Download [PRNet pre-trained model] from Drive. Put it in PRNet/net-data
Usage

➡️ You can now try it in Google Colab Open in Colab

# Color+Pattern: 
CUDA_VISIBLE_DEVICES=0 python main.py --style ./imgs/style-1.png --input ./imgs/non-makeup.png

# Color Only: 
CUDA_VISIBLE_DEVICES=0 python main.py --style ./imgs/style-1.png --input ./imgs/non-makeup.png --color_only

# Pattern Only: 
CUDA_VISIBLE_DEVICES=0 python main.py --style ./imgs/style-1.png --input ./imgs/non-makeup.png --pattern_only

Result image will be saved in result.png

result
From left to right: Style, Input & Output

Training and Evaluation

As stated in the paper, the Color Branch and Pattern Branch are totally independent. Yet, they shared the same workflow:

  1. Data preparation: Generating texture_map of faces.

  2. Training

Please redirect to Color Branch or Pattern Branch for further details.


🌿 If you have trouble running the code, please read Trouble Shooting before creating an issue. Thank you 🌿

Trouble Shooting
  1. [Solved] ImportError: libGL.so.1: cannot open shared object file: No such file or directory:

    sudo apt update
    sudo apt install libgl1-mesa-glx
    
  2. [Solved] RuntimeError: Expected tensor for argument #1 'input' to have the same device as tensor for argument #2 'weight'; but device 1 does not equal 0 (while checking arguments for cudnn_convolution) Add CUDA VISIBLE DEVICES before .py. Ex:

    CUDA_VISIBLE_DEVICES=0 python main.py
    
  3. [Solved] RuntimeError: cuda runtime error (999) : unknown error at /opt/conda/conda-bld/pytorch_1595629403081/work/aten/src/THC/THCGeneral.cpp:47

    sudo rmmod nvidia_uvm
    sudo modprobe nvidia_uvm
    
Comments
  • About the Makeup Transfer dataset.

    About the Makeup Transfer dataset.

    Thank you for releasing your nice work.

    It seems the link to the MT-Dataset is not available. Could you please share your downloaded one or any accessible link?

    opened by BIGJUN777 4
  • Training on new dataset

    Training on new dataset

    Hi, I really appreciate the work you have done and I want to train your color module on new dataset. In CPM/Color/Readme.md, it says to re-train model on new dataset, one should follow the the instruction on BeautyGAN. I am wondering whether this means I should use the BeautyGAN network to train on new dataset and use the checkpoints from this as the new color module checkpoints, or I can simply train the color module in this CPM network?

    opened by Lightingning 3
  • Setup throwing error

    Setup throwing error

    Was trying to setup in on local system but conda is throwing error:

    Solving environment: failed
    
    ResolvePackageNotFound:
      - libstdcxx-ng=9.3.0
      - gmp=6.2.1
      - openh264=2.1.1
      - _openmp_mutex=4.5
      - jasper=1.900.1
      - readline=8.1
      - graphite2=1.3.14
      - libuuid=1.0.3
      - libxcb=1.14
      - ncurses=6.2
      - libxkbcommon=1.0.3
      - libedit=3.1.20210216
      - ld_impl_linux-64=2.33.1
      - libnghttp2=1.43.0
      - nspr=4.30
      - lame=3.100
      - cupti=10.1.168
      - nss=3.63
      - libev=4.33
      - libgcc-ng=9.3.0
      - gnutls=3.6.13
      - dbus=1.13.18
      - nettle=3.6
      - libgfortran-ng=7.3.0
    

    Also what should be the ideal architecture to deploy this model over cloud?

    opened by abhibhaw 3
  • Suggest to loosen the dependency on albumentations

    Suggest to loosen the dependency on albumentations

    Hi, your project CPM requires "albumentations==0.5.2" in its dependency. After analyzing the source code, we found that the following versions of albumentations can also be suitable without affecting your project, i.e., albumentations 0.5.1. Therefore, we suggest to loosen the dependency on albumentations from "albumentations==0.5.2" to "albumentations>=0.5.1,<=0.5.2" to avoid any possible conflict for importing more packages or for downstream projects that may use CPM.

    May I pull a request to further loosen the dependency on albumentations?

    By the way, could you please tell us whether such dependency analysis may be potentially helpful for maintaining dependencies easier during your development?



    We also give our detailed analysis as follows for your reference:

    Your project CPM directly uses 17 APIs from package albumentations.

    albumentations.augmentations.transforms.MotionBlur.__init__, albumentations.augmentations.transforms.CLAHE.__init__, albumentations.imgaug.transforms.IAASharpen.__init__, albumentations.augmentations.transforms.RandomContrast.__init__, albumentations.imgaug.transforms.IAAPerspective.__init__, albumentations.augmentations.transforms.PadIfNeeded.__init__, albumentations.augmentations.transforms.Lambda.__init__, albumentations.core.composition.OneOf.__init__, albumentations.augmentations.transforms.RandomCrop.__init__, albumentations.core.composition.Compose.__init__, albumentations.augmentations.transforms.RandomBrightness.__init__, albumentations.imgaug.transforms.IAAAdditiveGaussianNoise.__init__, albumentations.augmentations.transforms.RandomGamma.__init__, albumentations.augmentations.transforms.HueSaturationValue.__init__, albumentations.augmentations.transforms.ShiftScaleRotate.__init__, albumentations.augmentations.transforms.Blur.__init__, albumentations.augmentations.transforms.HorizontalFlip.__init__
    
    

    Beginning from the 17 APIs above, 14 functions are then indirectly called, including 13 albumentations's internal APIs and 1 outsider APIs. The specific call graph is listed as follows (neglecting some repeated function occurrences).

    [/VinAIResearch/CPM]
    +--albumentations.augmentations.transforms.MotionBlur.__init__
    |      +--albumentations.augmentations.transforms.Blur.__init__
    |      |      +--albumentations.core.transforms_interface.BasicTransform.__init__
    |      |      +--albumentations.core.transforms_interface.to_tuple
    +--albumentations.augmentations.transforms.CLAHE.__init__
    |      +--albumentations.core.transforms_interface.BasicTransform.__init__
    |      +--albumentations.core.transforms_interface.to_tuple
    +--albumentations.imgaug.transforms.IAASharpen.__init__
    |      +--albumentations.core.transforms_interface.BasicTransform.__init__
    |      +--albumentations.core.transforms_interface.to_tuple
    +--albumentations.augmentations.transforms.RandomContrast.__init__
    |      +--albumentations.augmentations.transforms.RandomBrightnessContrast.__init__
    |      |      +--albumentations.core.transforms_interface.BasicTransform.__init__
    |      |      +--albumentations.core.transforms_interface.to_tuple
    |      +--warnings.warn
    +--albumentations.imgaug.transforms.IAAPerspective.__init__
    |      +--albumentations.core.transforms_interface.BasicTransform.__init__
    |      +--albumentations.core.transforms_interface.to_tuple
    +--albumentations.augmentations.transforms.PadIfNeeded.__init__
    |      +--albumentations.core.transforms_interface.BasicTransform.__init__
    +--albumentations.augmentations.transforms.Lambda.__init__
    |      +--albumentations.core.transforms_interface.BasicTransform.__init__
    |      +--warnings.warn
    +--albumentations.core.composition.OneOf.__init__
    |      +--albumentations.core.composition.BaseCompose.__init__
    |      |      +--albumentations.core.composition.Transforms.__init__
    |      |      |      +--albumentations.core.composition.Transforms._find_dual_start_end
    |      |      |      |      +--albumentations.core.composition.Transforms._find_dual_start_end
    +--albumentations.augmentations.transforms.RandomCrop.__init__
    |      +--albumentations.core.transforms_interface.BasicTransform.__init__
    +--albumentations.core.composition.Compose.__init__
    |      +--albumentations.core.composition.BaseCompose.__init__
    |      +--albumentations.augmentations.bbox_utils.BboxProcessor.__init__
    |      |      +--albumentations.core.utils.DataProcessor.__init__
    |      +--albumentations.core.composition.BboxParams.__init__
    |      |      +--albumentations.core.utils.Params.__init__
    |      +--albumentations.augmentations.keypoints_utils.KeypointsProcessor.__init__
    |      |      +--albumentations.core.utils.DataProcessor.__init__
    |      +--albumentations.core.composition.KeypointParams.__init__
    |      |      +--albumentations.core.utils.Params.__init__
    |      +--albumentations.core.composition.BaseCompose.add_targets
    +--albumentations.augmentations.transforms.RandomBrightness.__init__
    |      +--albumentations.augmentations.transforms.RandomBrightnessContrast.__init__
    |      +--warnings.warn
    +--albumentations.imgaug.transforms.IAAAdditiveGaussianNoise.__init__
    |      +--albumentations.core.transforms_interface.BasicTransform.__init__
    |      +--albumentations.core.transforms_interface.to_tuple
    +--albumentations.augmentations.transforms.RandomGamma.__init__
    |      +--albumentations.core.transforms_interface.BasicTransform.__init__
    |      +--albumentations.core.transforms_interface.to_tuple
    +--albumentations.augmentations.transforms.HueSaturationValue.__init__
    |      +--albumentations.core.transforms_interface.BasicTransform.__init__
    |      +--albumentations.core.transforms_interface.to_tuple
    +--albumentations.augmentations.transforms.ShiftScaleRotate.__init__
    |      +--albumentations.core.transforms_interface.BasicTransform.__init__
    |      +--albumentations.core.transforms_interface.to_tuple
    +--albumentations.augmentations.transforms.Blur.__init__
    +--albumentations.augmentations.transforms.HorizontalFlip.__init__
    |      +--albumentations.core.transforms_interface.BasicTransform.__init__
    

    We scan albumentations's versions and observe that during its evolution between any version from [0.5.1] and 0.5.2, the changing functions (diffs being listed below) have none intersection with any function or API we mentioned above (either directly or indirectly called by this project).

    diff: 0.5.2(original) 0.5.1
    ['albumentations.augmentations.transforms.MedianBlur', 'albumentations.augmentations.transforms.CropNonEmptyMaskIfExists.targets_as_params', 'albumentations.augmentations.transforms.GaussianBlur', 'albumentations.augmentations.transforms.CropNonEmptyMaskIfExists.update_params', 'albumentations.pytorch.transforms.ToTensorV2', 'albumentations.pytorch.transforms.ToTensorV2.apply', 'albumentations.augmentations.transforms.CropNonEmptyMaskIfExists.get_params_dependent_on_targets', 'albumentations.augmentations.transforms.CropNonEmptyMaskIfExists', 'albumentations.augmentations.transforms.CropNonEmptyMaskIfExists._preprocess_mask']
    
    

    As for other packages, the APIs of warnings are called by albumentations in the call graph and the dependencies on these packages also stay the same in our suggested versions, thus avoiding any outside conflict.

    Therefore, we believe that it is quite safe to loose your dependency on albumentations from "albumentations==0.5.2" to "albumentations>=0.5.1,<=0.5.2". This will improve the applicability of CPM and reduce the possibility of any further dependency conflict with other projects.

    opened by Agnes-U 2
  • ValueError: The passed save_path is not a valid checkpoint: ./PRNet/net-data/256_256_resfcn256_weight

    ValueError: The passed save_path is not a valid checkpoint: ./PRNet/net-data/256_256_resfcn256_weight

    Dear Author: I follow your running steps, but it raises an erros "ValueError: The passed save_path is not a valid checkpoint: ./PRNet/net-data/256_256_resfcn256_weight"

    color.pth, pattern.pth and 256_256_resfcn256_weight.data-00000-of-00001 are in the correct files. Can you give me some advice? Thank you!

    opened by JoJoliking 2
  • Unsatisfied results tested on customized images

    Unsatisfied results tested on customized images

    Hello

    I got some non-ideal results when testing the model on other images.

    1. As shown in the following image, there are some distinct boundaries on the resulting image. Any idea on this?

      image

      When diving into the code, I found you applied Face Detection before PRNet (See here). Because the image I input has been cropped, I commented those codes related to Face Detection in process() function (See below). However, the result turned out to be worse. It seems this Face Detection is necessary. Would you provide me with more explanation on this?

      image

      image

    2. When testing on my device (Tesla V100), it took several seconds to process an image, which is really time-consuming. Is this normal? If so, why will it be such time-consuming (it seems the model is not really complex)?

    Looking forward to your reply. Thanks.

    opened by BIGJUN777 2
  • Color Training

    Color Training

    When i try to train the Color Branch,there is a error occurred.Could you give me a suggestion when you have time. The error message is as follows: Traceback (most recent call last): File "create_beautygan_uv.py", line 51, in uv_texture, uv_seg = generator.get_texture(image, seg) File "/data/run01/scv0004/CPM-main/Color/texture_generator.py", line 23, in get_texture pos[:, :, :2].astype(np.float32), TypeError: 'NoneType' object is not subscriptable image

    opened by pirate-zhang 2
  • Read-only CPM folder preventing me from running Colab example - Read-only file system: './result.png'

    Read-only CPM folder preventing me from running Colab example - Read-only file system: './result.png'

    Hello, As in your Colab instruction, I added a shortcut of CPM-Shared-Folder to my Drive. However, I don't have the permission to write to your Drive, so I see the following error when running your instruction:

    Traceback (most recent call last):
      File "main.py", line 54, in <module>
        Image.fromarray((output).astype("uint8")).save(save_path)
      File "/usr/local/lib/python3.7/dist-packages/PIL/Image.py", line 2131, in save
        fp = builtins.open(filename, "w+b")
    OSError: [Errno 30] Read-only file system: './result.png'
    

    Suggested solutions: Point savedir to another directory:

    # Pattern + Color: Image will be saved in 'result.png'
    os.chdir(path)
    !python -W ignore main.py --style ./imgs/style-1.png --input ./imgs/non-makeup.png --savedir=/content/
    

    You should also update other commands.

    opened by vietanhdev 2
  • AttributeError: module 'segmentation_models_pytorch' has no attribute 'utils'

    AttributeError: module 'segmentation_models_pytorch' has no attribute 'utils'

    After following the install instructions and running the main.py script as instructed both locally and in colab...

    os.chdir(path) !python -W ignore main.py --style ./imgs/style-1.png --input ./imgs/non-makeup.png

    I get the following error:

    Traceback (most recent call last): File "main.py", line 28, in model = Makeup(args) File "/content/gdrive/.shortcut-targets-by-id/1rZyAvaAtqZ9a0okVcv4OFaq9aiVvKg5Q/CPM/makeup.py", line 18, in init self.pattern = Segmentor(args) File "/content/gdrive/.shortcut-targets-by-id/1rZyAvaAtqZ9a0okVcv4OFaq9aiVvKg5Q/CPM/utils/models.py", line 15, in init self.loss = smp.utils.losses.DiceLoss() AttributeError: module 'segmentation_models_pytorch' has no attribute 'utils'

    opened by trproto 1
  • Include docker file

    Include docker file

    Due to the fact that some complaints regarding running the code and neither works the colab version, I have provided docker file which you may add at your liesure. Thanks again for sharing your code.

    opened by hniksoleimani 0
  • RuntimeError: cuDNN error: CUDNN_STATUS_EXECUTION_FAILED

    RuntimeError: cuDNN error: CUDNN_STATUS_EXECUTION_FAILED

    Hello, I am trying to reimplementing the pattern branch and have this issue. There is also a warning saying that "GeForce RTX 3070 with CUDA capability sm_86 is not compatible with the current PyTorch installation. The current PyTorch install supports CUDA capabilities sm_37 sm_50 sm_60 sm_61 sm_70 sm_75 compute_37." I am using Ubuntu 21.04 and CUDA of version 11.2. I this the error is due to incompatibility between my rtx3070 and pytorch 1.6. I think I need a combination of pytorch=1.8, torchvision=0.9 to get it work. Do you have an alternative environment for this? ty!

    opened by cyanling2 3
Official pytorch code for SSAT: A Symmetric Semantic-Aware Transformer Network for Makeup Transfer and Removal

SSAT: A Symmetric Semantic-Aware Transformer Network for Makeup Transfer and Removal This is the official pytorch code for SSAT: A Symmetric Semantic-

ForeverPupil 57 Dec 13, 2022
Adversarial Color Enhancement: Generating Unrestricted Adversarial Images by Optimizing a Color Filter

ACE Please find the preliminary version published at BMVC 2020 in the folder BMVC_version, and its extended journal version in Journal_version. Datase

null 28 Dec 25, 2022
Robust Partial Matching for Person Search in the Wild

APNet for Person Search Introduction This is the code of Robust Partial Matching for Person Search in the Wild accepted in CVPR2020. The Align-to-Part

Yingji Zhong 36 Dec 18, 2022
CVPR '21: In the light of feature distributions: Moment matching for Neural Style Transfer

In the light of feature distributions: Moment matching for Neural Style Transfer (CVPR 2021) This repository provides code to recreate results present

Nikolai Kalischek 49 Oct 13, 2022
Official Pytorch implementation of "Beyond Static Features for Temporally Consistent 3D Human Pose and Shape from a Video", CVPR 2021

TCMR: Beyond Static Features for Temporally Consistent 3D Human Pose and Shape from a Video Qualtitative result Paper teaser video Introduction This r

Hongsuk Choi 215 Jan 6, 2023
Beyond Image to Depth: Improving Depth Prediction using Echoes (CVPR 2021)

Beyond Image to Depth: Improving Depth Prediction using Echoes (CVPR 2021) Kranti Kumar Parida, Siddharth Srivastava, Gaurav Sharma. We address the pr

Kranti Kumar Parida 33 Jun 27, 2022
An official TensorFlow implementation of “CLCC: Contrastive Learning for Color Constancy” accepted at CVPR 2021.

CLCC: Contrastive Learning for Color Constancy (CVPR 2021) Yi-Chen Lo*, Chia-Che Chang*, Hsuan-Chao Chiu, Yu-Hao Huang, Chia-Ping Chen, Yu-Lin Chang,

Yi-Chen (Howard) Lo 58 Dec 17, 2022
Reference code for the paper CAMS: Color-Aware Multi-Style Transfer.

CAMS: Color-Aware Multi-Style Transfer Mahmoud Afifi1, Abdullah Abuolaim*1, Mostafa Hussien*2, Marcus A. Brubaker1, Michael S. Brown1 1York University

Mahmoud Afifi 36 Dec 4, 2022
[CVPR'21] Learning to Recommend Frame for Interactive Video Object Segmentation in the Wild

IVOS-W Paper Learning to Recommend Frame for Interactive Video Object Segmentation in the Wild Zhaoyun Yin, Jia Zheng, Weixin Luo, Shenhan Qian, Hanli

SVIP Lab 38 Dec 12, 2022
Official Pytorch implementation of "Learning to Estimate Robust 3D Human Mesh from In-the-Wild Crowded Scenes", CVPR 2022

Learning to Estimate Robust 3D Human Mesh from In-the-Wild Crowded Scenes / 3DCrowdNet News ?? 3DCrowdNet achieves the state-of-the-art accuracy on 3D

Hongsuk Choi 113 Dec 21, 2022
This is the code for the paper "Jinkai Zheng, Xinchen Liu, Wu Liu, Lingxiao He, Chenggang Yan, Tao Mei: Gait Recognition in the Wild with Dense 3D Representations and A Benchmark. (CVPR 2022)"

Gait3D-Benchmark This is the code for the paper "Jinkai Zheng, Xinchen Liu, Wu Liu, Lingxiao He, Chenggang Yan, Tao Mei: Gait Recognition in the Wild

null 82 Jan 4, 2023
《Single Image Reflection Removal Beyond Linearity》(CVPR 2019)

Single-Image-Reflection-Removal-Beyond-Linearity Paper Single Image Reflection Removal Beyond Linearity. Qiang Wen, Yinjie Tan, Jing Qin, Wenxi Liu, G

Qiang Wen 51 Jun 24, 2022
Code for C2-Matching (CVPR2021). Paper: Robust Reference-based Super-Resolution via C2-Matching.

C2-Matching (CVPR2021) This repository contains the implementation of the following paper: Robust Reference-based Super-Resolution via C2-Matching Yum

Yuming Jiang 151 Dec 26, 2022
A Python implementation of the Locality Preserving Matching (LPM) method for pruning outliers in image matching.

LPM_Python A Python implementation of the Locality Preserving Matching (LPM) method for pruning outliers in image matching. The code is established ac

AoxiangFan 11 Nov 7, 2022
Official code for the paper: Deep Graph Matching under Quadratic Constraint (CVPR 2021)

QC-DGM This is the official PyTorch implementation and models for our CVPR 2021 paper: Deep Graph Matching under Quadratic Constraint. It also contain

Quankai Gao 55 Nov 14, 2022
Code for "LoFTR: Detector-Free Local Feature Matching with Transformers", CVPR 2021

LoFTR: Detector-Free Local Feature Matching with Transformers Project Page | Paper LoFTR: Detector-Free Local Feature Matching with Transformers Jiami

ZJU3DV 1.4k Jan 4, 2023
the code for our CVPR 2021 paper Bilateral Grid Learning for Stereo Matching Network [BGNet]

BGNet This repository contains the code for our CVPR 2021 paper Bilateral Grid Learning for Stereo Matching Network [BGNet] Environment Python 3.6.* C

3DCV developer 87 Nov 29, 2022
LoFTR:Detector-Free Local Feature Matching with Transformers CVPR 2021

LoFTR-with-train-script LoFTR:Detector-Free Local Feature Matching with Transformers CVPR 2021 (with train script --- unofficial ---). About Megadepth

Nan Xiaohu 15 Nov 4, 2022
Official PyTorch Implementation of Convolutional Hough Matching Networks, CVPR 2021 (oral)

Convolutional Hough Matching Networks This is the implementation of the paper "Convolutional Hough Matching Network" by J. Min and M. Cho. Implemented

Juhong Min 70 Nov 22, 2022