Skip to content

Commit f38aeb0

Browse files
huangsiyuhuangsiyu
authored andcommitted
create
0 parents  commit f38aeb0

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+4164
-0
lines changed

.DS_Store

10 KB
Binary file not shown.

LICENSE

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
BSD 3-Clause License
2+
3+
Copyright (c) 2020, Siyu Huang
4+
All rights reserved.
5+
6+
Redistribution and use in source and binary forms, with or without
7+
modification, are permitted provided that the following conditions are met:
8+
9+
1. Redistributions of source code must retain the above copyright notice, this
10+
list of conditions and the following disclaimer.
11+
12+
2. Redistributions in binary form must reproduce the above copyright notice,
13+
this list of conditions and the following disclaimer in the documentation
14+
and/or other materials provided with the distribution.
15+
16+
3. Neither the name of the copyright holder nor the names of its
17+
contributors may be used to endorse or promote products derived from
18+
this software without specific prior written permission.
19+
20+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30+
31+
--------------------------- LICENSE FOR pytorch-CycleGAN-and-pix2pix --------------------------------
32+
For pytorch-CycleGAN-and-pix2pix software
33+
34+
Copyright (c) 2017, Jun-Yan Zhu and Taesung Park
35+
All rights reserved.
36+
37+
Redistribution and use in source and binary forms, with or without
38+
modification, are permitted provided that the following conditions are met:
39+
40+
* Redistributions of source code must retain the above copyright notice, this
41+
list of conditions and the following disclaimer.
42+
43+
* Redistributions in binary form must reproduce the above copyright notice,
44+
this list of conditions and the following disclaimer in the documentation
45+
and/or other materials provided with the distribution.
46+
47+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
48+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
49+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
50+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
51+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
52+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
53+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
54+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
55+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
56+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
57+
58+
59+
--------------------------- LICENSE FOR pix2pix --------------------------------
60+
BSD License
61+
62+
For pix2pix software
63+
Copyright (c) 2016, Phillip Isola and Jun-Yan Zhu
64+
All rights reserved.
65+
66+
Redistribution and use in source and binary forms, with or without
67+
modification, are permitted provided that the following conditions are met:
68+
69+
* Redistributions of source code must retain the above copyright notice, this
70+
list of conditions and the following disclaimer.
71+
72+
* Redistributions in binary form must reproduce the above copyright notice,
73+
this list of conditions and the following disclaimer in the documentation
74+
and/or other materials provided with the distribution.
75+
76+
----------------------------- LICENSE FOR DCGAN --------------------------------
77+
BSD License
78+
79+
For dcgan.torch software
80+
81+
Copyright (c) 2015, Facebook, Inc. All rights reserved.
82+
83+
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
84+
85+
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
86+
87+
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
88+
89+
Neither the name Facebook nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
90+
91+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
92+

README.md

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
# PoseStylizer
2+
PyTorch implementation of "**Generating Person Images with Appearance-aware Pose Stylizer**" published in **IJCAI 2020**.
3+
4+
<p align="center"><img src='figs/framework.png' width="500"/></p>
5+
6+
The code is written by [Siyu Huang](https://siyuhuang.github.io/). Contact [Siyu Huang](https://siyuhuang.github.io/) for questions on this project.
7+
8+
<p align="center"><img src='figs/fig1.png' width="600"/></p>
9+
10+
11+
## Getting Started
12+
### Requirement
13+
* Python3
14+
* PyTorch 1.0.1
15+
16+
### Installation
17+
- Clone this repo:
18+
```bash
19+
git clone https://github.com/siyuhuang/PoseStylizer.git
20+
cd PoseStylizer
21+
```
22+
23+
### Data Preperation
24+
1. Download the Market-1501 dataset ```dataset/market_data.zip``` and the DeepFashion dataset ```dataset/fashion_data.zip``` from [Google Drive](https://drive.google.com/open?id=13EzWg6tW8a_DBabBbzCgTFuBqiuHahnu) / [Baidu Disk](https://pan.baidu.com/s/1PwO5yFhonDTtWdPLGgPrRw) (Password: jl0s). The zip files include images ```/train``` ```/test```, keypoint annotations ```annotation.csv```, and pose transfer pairs ```pairs.csv```.
25+
```bash
26+
cd dataset
27+
unzip market_data.zip
28+
unzip fashion_data.zip
29+
cd ..
30+
```
31+
2. Generate the pose heatmaps. Note, the disk space of generated heatmaps are extremely large (~18GB for Market-1501 and ~160GB for DeepFashion).
32+
```bash
33+
python tool/generate_pose_map_market.py
34+
python tool/generate_pose_map_fashion.py
35+
```
36+
37+
## Test with Pretrained Models
38+
39+
Download our pretrained checkpoints from [Google Drive](https://drive.google.com/open?id=1LKFYZvwizRpDxslWoyUePC9XG0cpqLzT) / [Baidu Disk](https://pan.baidu.com/s/1PwO5yFhonDTtWdPLGgPrRw) (Password: jl0s).
40+
* **Market-1501**
41+
42+
```bash
43+
bash test_market.sh
44+
```
45+
46+
* **DeepFashion**
47+
48+
```bash
49+
bash test_fashion.sh
50+
```
51+
52+
53+
## Training
54+
* **Market-1501**
55+
```bash
56+
bash train_market.sh
57+
```
58+
59+
* **DeepFashion**
60+
```bash
61+
bash train_fashion.sh
62+
```
63+
**Note:** We use 8 GPUs for training by default. If you have less GPUs, change ```--gpu_ids``` and ```--batchSize``` accordingly. The results are competitive to the results in our paper.
64+
65+
## Evaluation
66+
67+
### SSIM, IS, L1, mask-SSIM, mask-IS, mask-L1
68+
69+
* *Tensorflow 1.14.1 (Python3)* is required.
70+
71+
* **Market-1501**
72+
```bash
73+
python tool/getMetrics_market.py
74+
```
75+
76+
* **DeepFashion**
77+
```bash
78+
python tool/getMetrics_fashion.py
79+
```
80+
81+
82+
### PCKh
83+
* Download OpenPose pose estimator from [Google Drive](https://drive.google.com/open?id=1nqZ8xSXBXdL1F3WFHTJJwm4rXYCCVy0y) / [Baidu Disk](https://pan.baidu.com/s/1PwO5yFhonDTtWdPLGgPrRw) (Password: jl0s). Put ``
84+
pose_estimator.h5`` under the root folder ``PoseStylizer``.
85+
* *Tensorflow 1.14.1 (Python2)* is required.
86+
1. **Crop generated images from ```/results``` folder.**
87+
```bash
88+
python tool/crop_market.py
89+
```
90+
&nbsp; &nbsp; or
91+
```bash
92+
python tool/crop_fashion.py
93+
```
94+
2. **Compute keypoints coordinates.** Change the paths ``input_folder`` and ``output_path`` in ``tool/compute_coordinates.py``.
95+
```bash
96+
python2 tool/compute_coordinates.py
97+
```
98+
3. **Compute PCKh score.**
99+
```bash
100+
python tool/calPCKH_market.py
101+
```
102+
&nbsp; &nbsp; or
103+
```bash
104+
python tool/calPCKH_fashion.py
105+
```
106+
107+
108+
## Citation
109+
If you use this code for your research, please kindly cite our paper.
110+
```
111+
@inproceedings{huang2020generating,
112+
title={Generating Person Images with Appearance-aware Pose Stylizer},
113+
author={Huang, Siyu and Xiong, Haoyi and Cheng, Zhi-Qi and Wang, Qingzhong and Zhou, Xingran and Wen, Bihan and Huan, Jun and Dou Dejing},
114+
booktitle={IJCAI},
115+
year={2020}
116+
}
117+
```
118+
119+
## Acknowledgments
120+
The code is written based on [pytorch-CycleGAN-and-pix2pix](https://github.com/junyanz/pytorch-CycleGAN-and-pix2pix) and [Pose-Transfer](https://github.com/tengteng95/Pose-Transfer).

data/__init__.py

Whitespace-only changes.

data/base_data_loader.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
2+
class BaseDataLoader():
3+
def __init__(self):
4+
pass
5+
6+
def initialize(self, opt):
7+
self.opt = opt
8+
pass
9+
10+
def load_data():
11+
return None
12+
13+
14+

data/base_dataset.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import torch.utils.data as data
2+
from PIL import Image
3+
import torchvision.transforms as transforms
4+
5+
class BaseDataset(data.Dataset):
6+
def __init__(self):
7+
super(BaseDataset, self).__init__()
8+
9+
def name(self):
10+
return 'BaseDataset'
11+
12+
def initialize(self, opt):
13+
pass
14+
15+
def get_transform(opt):
16+
transform_list = []
17+
if opt.resize_or_crop == 'resize_and_crop':
18+
osize = [opt.loadSize, opt.loadSize]
19+
transform_list.append(transforms.Scale(osize, Image.BICUBIC))
20+
transform_list.append(transforms.RandomCrop(opt.fineSize))
21+
elif opt.resize_or_crop == 'crop':
22+
transform_list.append(transforms.RandomCrop(opt.fineSize))
23+
elif opt.resize_or_crop == 'scale_width':
24+
transform_list.append(transforms.Lambda(
25+
lambda img: __scale_width(img, opt.fineSize)))
26+
elif opt.resize_or_crop == 'scale_width_and_crop':
27+
transform_list.append(transforms.Lambda(
28+
lambda img: __scale_width(img, opt.loadSize)))
29+
transform_list.append(transforms.RandomCrop(opt.fineSize))
30+
31+
transform_list += [transforms.ToTensor(),
32+
transforms.Normalize((0.5, 0.5, 0.5),
33+
(0.5, 0.5, 0.5))]
34+
return transforms.Compose(transform_list)
35+
36+
def __scale_width(img, target_width):
37+
ow, oh = img.size
38+
if (ow == target_width):
39+
return img
40+
w = target_width
41+
h = int(target_width * oh / ow)
42+
return img.resize((w, h), Image.BICUBIC)
43+

data/custom_dataset_data_loader.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import torch.utils.data
2+
from data.base_data_loader import BaseDataLoader
3+
4+
5+
def CreateDataset(opt):
6+
dataset = None
7+
8+
if opt.dataset_mode == 'keypoint':
9+
from data.keypoint import KeyDataset
10+
dataset = KeyDataset()
11+
elif opt.dataset_mode == 'keypoint_segmentation':
12+
from data.keypoint_segmentation import KeySegDataset
13+
dataset = KeySegDataset()
14+
else:
15+
raise ValueError("Dataset [%s] not recognized." % opt.dataset_mode)
16+
17+
print("dataset [%s] was created" % (dataset.name()))
18+
dataset.initialize(opt)
19+
return dataset
20+
21+
22+
class CustomDatasetDataLoader(BaseDataLoader):
23+
def name(self):
24+
return 'CustomDatasetDataLoader'
25+
26+
def initialize(self, opt):
27+
BaseDataLoader.initialize(self, opt)
28+
self.dataset = CreateDataset(opt)
29+
self.dataloader = torch.utils.data.DataLoader(
30+
self.dataset,
31+
batch_size=opt.batchSize,
32+
shuffle=not opt.serial_batches,
33+
num_workers=int(opt.nThreads))
34+
35+
def load_data(self):
36+
return self
37+
38+
def __len__(self):
39+
return min(len(self.dataset), self.opt.max_dataset_size)
40+
41+
def __iter__(self):
42+
for i, data in enumerate(self.dataloader):
43+
if i >= self.opt.max_dataset_size:
44+
break
45+
yield data

data/data_loader.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
2+
def CreateDataLoader(opt):
3+
from data.custom_dataset_data_loader import CustomDatasetDataLoader
4+
data_loader = CustomDatasetDataLoader()
5+
print(data_loader.name())
6+
data_loader.initialize(opt)
7+
return data_loader

data/image_folder.py

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
###############################################################################
2+
# Code from
3+
# https://github.com/pytorch/vision/blob/master/torchvision/datasets/folder.py
4+
# Modified the original code so that it also loads images from the current
5+
# directory as well as the subdirectories
6+
###############################################################################
7+
8+
import torch.utils.data as data
9+
10+
from PIL import Image
11+
import os
12+
import os.path
13+
14+
IMG_EXTENSIONS = [
15+
'.jpg', '.JPG', '.jpeg', '.JPEG',
16+
'.png', '.PNG', '.ppm', '.PPM', '.bmp', '.BMP',
17+
]
18+
19+
20+
def is_image_file(filename):
21+
return any(filename.endswith(extension) for extension in IMG_EXTENSIONS)
22+
23+
24+
def make_dataset(dir):
25+
images = []
26+
assert os.path.isdir(dir), '%s is not a valid directory' % dir
27+
28+
for root, _, fnames in sorted(os.walk(dir)):
29+
for fname in fnames:
30+
if is_image_file(fname):
31+
path = os.path.join(root, fname)
32+
images.append(path)
33+
34+
return images
35+
36+
37+
def default_loader(path):
38+
return Image.open(path).convert('RGB')
39+
40+
41+
class ImageFolder(data.Dataset):
42+
43+
def __init__(self, root, transform=None, return_paths=False,
44+
loader=default_loader):
45+
imgs = make_dataset(root)
46+
if len(imgs) == 0:
47+
raise(RuntimeError("Found 0 images in: " + root + "\n"
48+
"Supported image extensions are: " +
49+
",".join(IMG_EXTENSIONS)))
50+
51+
self.root = root
52+
self.imgs = imgs
53+
self.transform = transform
54+
self.return_paths = return_paths
55+
self.loader = loader
56+
57+
def __getitem__(self, index):
58+
path = self.imgs[index]
59+
img = self.loader(path)
60+
if self.transform is not None:
61+
img = self.transform(img)
62+
if self.return_paths:
63+
return img, path
64+
else:
65+
return img
66+
67+
def __len__(self):
68+
return len(self.imgs)

0 commit comments

Comments
 (0)