├── .gitignore
├── LICENSE
├── README.md
├── README.t
├── align_faces.py
├── baidu_aip
└── test.py
├── config.py
├── data_gen.py
├── data_stats.py
├── demo.py
├── download.py
├── export.py
├── extract.py
├── get_prob.py
├── images
├── 003ac.jpg
├── 0_img.jpg
├── 0_raw.jpg
├── 1.JPG
├── 1_img.jpg
├── 1_raw.jpg
├── 2_img.jpg
├── 2_raw.jpg
├── 3_img.jpg
├── 3_raw.jpg
├── 4_img.jpg
├── 4_raw.jpg
├── 5_img.jpg
├── 5_raw.jpg
├── 6_img.jpg
├── 6_raw.jpg
├── 7_img.jpg
├── 7_raw.jpg
├── 8_img.jpg
├── 8_raw.jpg
├── 9_img.jpg
├── 9_raw.jpg
├── age_dist.png
├── angle_pitch_dist.png
├── angle_roll_dist.png
├── angle_yaw_dist.png
├── beauty_dist.png
├── euler_angles.png
├── expression_dist.png
├── face_shape_dist.png
├── face_type_dist.png
├── gender_dist.png
├── glasses_dist.png
├── img_flip_0.jpg
├── img_flip_1.jpg
├── img_flip_2.jpg
├── img_flip_3.jpg
├── img_flip_4.jpg
├── img_flip_5.jpg
├── img_flip_6.jpg
├── img_flip_7.jpg
├── img_flip_8.jpg
├── img_flip_9.jpg
├── img_norm_0.jpg
├── img_norm_1.jpg
├── img_norm_2.jpg
├── img_norm_3.jpg
├── img_norm_4.jpg
├── img_norm_5.jpg
├── img_norm_6.jpg
├── img_norm_7.jpg
├── img_norm_8.jpg
├── img_norm_9.jpg
├── learning_curve.jpg
├── race_dist.png
└── wanghong.jpg
├── img_aug.py
├── models.py
├── pre_process.py
├── replace_macros.py
├── requirements.txt
├── retinaface
├── data
│ ├── FDDB
│ │ └── img_list.txt
│ ├── __init__.py
│ ├── config.py
│ ├── data_augment.py
│ └── wider_face.py
├── detector.py
├── layers
│ ├── __init__.py
│ ├── functions
│ │ └── prior_box.py
│ └── modules
│ │ ├── __init__.py
│ │ └── multibox_loss.py
├── loader.py
├── models
│ ├── __init__.py
│ ├── net.py
│ └── retinaface.py
├── utils
│ ├── __init__.py
│ ├── box_utils.py
│ ├── nms
│ │ ├── __init__.py
│ │ └── py_cpu_nms.py
│ └── timer.py
└── weights
│ └── mobilenet0.25_Final.pth
├── rotating_cube.py
├── sample_preds.json
├── screenshot.jpg
├── test_angles.py
├── train.py
├── utils.py
└── utils_aip.py
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 | __pycache__/
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 刘杨
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Face Attributes Mobile
2 |
3 | Regress Face Attributes with MobileNetV2.
4 |
5 | ## Features
6 | 1. Estimate Gender, Age, Euler angles, Beauty, Expression, Face shape, Face type and Glasses with a single image.
7 | 2. Lightweight: Params size (MB): 2.14, FLOPs size (GB): 0.32, Total Size (MB): 9.18.
8 |
9 |
10 | ## DataSet
11 |
12 | CASIA WebFace DataSet, 479,653 faces.
13 |
14 | ### Gender
15 |
16 | 
17 |
18 | ### Age
19 |
20 | 
21 |
22 | ### Euler angles:
23 |
24 | 
25 |
26 | Pitch:
27 |
28 | 
29 |
30 | Yaw:
31 |
32 | 
33 |
34 | Roll:
35 |
36 | 
37 |
38 | ### Beauty
39 |
40 | 
41 |
42 | ### Expression
43 |
44 | 
45 |
46 | ### Face shape
47 |
48 | 
49 |
50 | ### Face type
51 |
52 | 
53 |
54 | ### Glasses
55 |
56 | 
57 |
58 | ### Race
59 |
60 | 
61 |
62 | ## Dependencies
63 | - Python 3.6.8
64 | - PyTorch 1.3.0
65 |
66 | ## Usage
67 |
68 |
69 | ### Train
70 | ```bash
71 | $ python train.py
72 | ```
73 |
74 | To visualize the training process:
75 | ```bash
76 | $ tensorboard --logdir=runs
77 | ```
78 |
79 | 
80 |
81 | Image | Aligned | Out | True |
82 | |---|---|---|---|
83 | |||age: 31
pitch: -5.58
roll: 0.83
yaw: -24.83
beauty: 47.2
expression: none
gender: female
glasses: none
race: white|age: 32
pitch: -4.77
roll: 1.15
yaw: -26.22
beauty: 57.96
expression: none
gender: female
glasses: none
race: white|
84 | |||age: 32
pitch: 10.87
roll: -4.92
yaw: -20.07
beauty: 66.32
expression: none
gender: male
glasses: none
race: white|age: 31
pitch: 13.28
roll: -5.81
yaw: -18.85
beauty: 65.91
expression: none
gender: male
glasses: none
race: white|
85 | |||age: 38
pitch: 12.82
roll: -0.2
yaw: -12.13
beauty: 35.49
expression: none
gender: male
glasses: none
race: white|age: 42
pitch: 13.01
roll: -0.03
yaw: -16.77
beauty: 50.19
expression: none
gender: male
glasses: none
race: white|
86 | |||age: 22
pitch: 4.57
roll: -7.73
yaw: 23.17
beauty: 43.42
expression: none
gender: female
glasses: none
race: white|age: 23
pitch: 5.51
roll: -7.73
yaw: 18.73
beauty: 45.36
expression: none
gender: female
glasses: sun
race: white|
87 | |||age: 34
pitch: 8.17
roll: -5.39
yaw: -0.97
beauty: 60.92
expression: none
gender: male
glasses: none
race: white|age: 37
pitch: 7.48
roll: -6.35
yaw: -0.35
beauty: 62.51
expression: none
gender: male
glasses: none
race: white|
88 | |||age: 28
pitch: 9.68
roll: 11.88
yaw: -40.47
beauty: 49.96
expression: none
gender: female
glasses: none
race: white|age: 28
pitch: 7.41
roll: 12.21
yaw: -38.69
beauty: 48.13
expression: none
gender: female
glasses: none
race: white|
89 | |||age: 35
pitch: 17.0
roll: -5.98
yaw: -3.54
beauty: 70.58
expression: none
gender: female
glasses: none
race: white|age: 37
pitch: 17.99
roll: -4.34
yaw: -7.96
beauty: 66.77
expression: none
gender: female
glasses: none
race: white|
90 | |||age: 30
pitch: 20.61
roll: 12.72
yaw: -22.68
beauty: 59.12
expression: smile
gender: male
glasses: none
race: white|age: 28
pitch: 19.27
roll: 13.28
yaw: -26.46
beauty: 58.69
expression: smile
gender: male
glasses: none
race: white|
91 | |||age: 46
pitch: 11.58
roll: -3.16
yaw: 19.05
beauty: 56.29
expression: none
gender: male
glasses: none
race: white|age: 45
pitch: 8.26
roll: -1.08
yaw: 20.05
beauty: 61.68
expression: none
gender: male
glasses: none
race: white|
92 | |||age: 34
pitch: 17.02
roll: -1.11
yaw: -3.17
beauty: 62.15
expression: none
gender: male
glasses: none
race: white|age: 34
pitch: 18.41
roll: -0.76
yaw: -5.72
beauty: 55.57
expression: none
gender: male
glasses: none
race: white|
93 |
--------------------------------------------------------------------------------
/README.t:
--------------------------------------------------------------------------------
1 | # Face Attributes Mobile
2 |
3 | Regress Face Attributes with MobileNetV2.
4 |
5 | ## Features
6 | 1. Estimate Gender, Age, Euler angles, Beauty, Expression, Face shape, Face type and Glasses with a single image.
7 | 2. Lightweight: Params size (MB): 2.14, FLOPs size (GB): 0.32, Total Size (MB): 9.18.
8 |
9 |
10 | ## DataSet
11 |
12 | CASIA WebFace DataSet, 479,653 faces.
13 |
14 | ### Gender
15 |
16 | 
17 |
18 | ### Age
19 |
20 | 
21 |
22 | ### Euler angles:
23 |
24 | 
25 |
26 | Pitch:
27 |
28 | 
29 |
30 | Yaw:
31 |
32 | 
33 |
34 | Roll:
35 |
36 | 
37 |
38 | ### Beauty
39 |
40 | 
41 |
42 | ### Expression
43 |
44 | 
45 |
46 | ### Face shape
47 |
48 | 
49 |
50 | ### Face type
51 |
52 | 
53 |
54 | ### Glasses
55 |
56 | 
57 |
58 | ### Race
59 |
60 | 
61 |
62 | ## Dependencies
63 | - Python 3.6.8
64 | - PyTorch 1.3.0
65 |
66 | ## Usage
67 |
68 |
69 | ### Train
70 | ```bash
71 | $ python train.py
72 | ```
73 |
74 | To visualize the training process:
75 | ```bash
76 | $ tensorboard --logdir=runs
77 | ```
78 |
79 | 
80 |
81 | Image | Aligned | Out | True |
82 | |---|---|---|---|
83 | |||$(result_out_0)|$(result_true_0)|
84 | |||$(result_out_1)|$(result_true_1)|
85 | |||$(result_out_2)|$(result_true_2)|
86 | |||$(result_out_3)|$(result_true_3)|
87 | |||$(result_out_4)|$(result_true_4)|
88 | |||$(result_out_5)|$(result_true_5)|
89 | |||$(result_out_6)|$(result_true_6)|
90 | |||$(result_out_7)|$(result_true_7)|
91 | |||$(result_out_8)|$(result_true_8)|
92 | |||$(result_out_9)|$(result_true_9)|
93 |
--------------------------------------------------------------------------------
/align_faces.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | """
3 | Created on Mon Apr 24 15:43:29 2017
4 | @author: zhaoy
5 | """
6 | import cv2
7 | import numpy as np
8 | from skimage import transform as trans
9 |
10 | # reference facial points, a list of coordinates (x,y)
11 | REFERENCE_FACIAL_POINTS = [
12 | [30.29459953, 51.69630051],
13 | [65.53179932, 51.50139999],
14 | [48.02519989, 71.73660278],
15 | [33.54930115, 92.3655014],
16 | [62.72990036, 92.20410156]
17 | ]
18 |
19 | DEFAULT_CROP_SIZE = (96, 112)
20 |
21 |
22 | class FaceWarpException(Exception):
23 | def __str__(self):
24 | return 'In File {}:{}'.format(
25 | __file__, super.__str__(self))
26 |
27 |
28 | def get_reference_facial_points(output_size=None,
29 | inner_padding_factor=0.0,
30 | outer_padding=(0, 0),
31 | default_square=False):
32 | tmp_5pts = np.array(REFERENCE_FACIAL_POINTS)
33 | tmp_crop_size = np.array(DEFAULT_CROP_SIZE)
34 |
35 | # 0) make the inner region a square
36 | if default_square:
37 | size_diff = max(tmp_crop_size) - tmp_crop_size
38 | tmp_5pts += size_diff / 2
39 | tmp_crop_size += size_diff
40 |
41 | # print('---> default:')
42 | # print(' crop_size = ', tmp_crop_size)
43 | # print(' reference_5pts = ', tmp_5pts)
44 |
45 | if (output_size and
46 | output_size[0] == tmp_crop_size[0] and
47 | output_size[1] == tmp_crop_size[1]):
48 | # print('output_size == DEFAULT_CROP_SIZE {}: return default reference points'.format(tmp_crop_size))
49 | return tmp_5pts
50 |
51 | if (inner_padding_factor == 0 and
52 | outer_padding == (0, 0)):
53 | if output_size is None:
54 | print('No paddings to do: return default reference points')
55 | return tmp_5pts
56 | else:
57 | raise FaceWarpException(
58 | 'No paddings to do, output_size must be None or {}'.format(tmp_crop_size))
59 |
60 | # check output size
61 | if not (0 <= inner_padding_factor <= 1.0):
62 | raise FaceWarpException('Not (0 <= inner_padding_factor <= 1.0)')
63 |
64 | if ((inner_padding_factor > 0 or outer_padding[0] > 0 or outer_padding[1] > 0)
65 | and output_size is None):
66 | output_size = tmp_crop_size * \
67 | (1 + inner_padding_factor * 2).astype(np.int32)
68 | output_size += np.array(outer_padding)
69 | print(' deduced from paddings, output_size = ', output_size)
70 |
71 | if not (outer_padding[0] < output_size[0]
72 | and outer_padding[1] < output_size[1]):
73 | raise FaceWarpException('Not (outer_padding[0] < output_size[0]'
74 | 'and outer_padding[1] < output_size[1])')
75 |
76 | # 1) pad the inner region according inner_padding_factor
77 | # print('---> STEP1: pad the inner region according inner_padding_factor')
78 | if inner_padding_factor > 0:
79 | size_diff = tmp_crop_size * inner_padding_factor * 2
80 | tmp_5pts += size_diff / 2
81 | tmp_crop_size += np.round(size_diff).astype(np.int32)
82 |
83 | # print(' crop_size = ', tmp_crop_size)
84 | # print(' reference_5pts = ', tmp_5pts)
85 |
86 | # 2) resize the padded inner region
87 | # print('---> STEP2: resize the padded inner region')
88 | size_bf_outer_pad = np.array(output_size) - np.array(outer_padding) * 2
89 | # print(' crop_size = ', tmp_crop_size)
90 | # print(' size_bf_outer_pad = ', size_bf_outer_pad)
91 |
92 | if size_bf_outer_pad[0] * tmp_crop_size[1] != size_bf_outer_pad[1] * tmp_crop_size[0]:
93 | raise FaceWarpException('Must have (output_size - outer_padding)'
94 | '= some_scale * (crop_size * (1.0 + inner_padding_factor)')
95 |
96 | scale_factor = size_bf_outer_pad[0].astype(np.float32) / tmp_crop_size[0]
97 | # print(' resize scale_factor = ', scale_factor)
98 | tmp_5pts = tmp_5pts * scale_factor
99 | # size_diff = tmp_crop_size * (scale_factor - min(scale_factor))
100 | # tmp_5pts = tmp_5pts + size_diff / 2
101 | tmp_crop_size = size_bf_outer_pad
102 | # print(' crop_size = ', tmp_crop_size)
103 | # print(' reference_5pts = ', tmp_5pts)
104 |
105 | # 3) add outer_padding to make output_size
106 | reference_5point = tmp_5pts + np.array(outer_padding)
107 | tmp_crop_size = output_size
108 | # print('---> STEP3: add outer_padding to make output_size')
109 | # print(' crop_size = ', tmp_crop_size)
110 | # print(' reference_5pts = ', tmp_5pts)
111 | #
112 | # print('===> end get_reference_facial_points\n')
113 |
114 | return reference_5point
115 |
116 |
117 | def get_affine_transform_matrix(src_pts, dst_pts):
118 | tfm = np.float32([[1, 0, 0], [0, 1, 0]])
119 | n_pts = src_pts.shape[0]
120 | ones = np.ones((n_pts, 1), src_pts.dtype)
121 | src_pts_ = np.hstack([src_pts, ones])
122 | dst_pts_ = np.hstack([dst_pts, ones])
123 |
124 | A, res, rank, s = np.linalg.lstsq(src_pts_, dst_pts_)
125 |
126 | if rank == 3:
127 | tfm = np.float32([
128 | [A[0, 0], A[1, 0], A[2, 0]],
129 | [A[0, 1], A[1, 1], A[2, 1]]
130 | ])
131 | elif rank == 2:
132 | tfm = np.float32([
133 | [A[0, 0], A[1, 0], 0],
134 | [A[0, 1], A[1, 1], 0]
135 | ])
136 |
137 | return tfm
138 |
139 |
140 | def warp_and_crop_face(src_img,
141 | facial_pts,
142 | reference_pts=None,
143 | crop_size=(96, 112),
144 | align_type='smilarity'):
145 | if reference_pts is None:
146 | if crop_size[0] == 96 and crop_size[1] == 112:
147 | reference_pts = REFERENCE_FACIAL_POINTS
148 | else:
149 | default_square = False
150 | inner_padding_factor = 0
151 | outer_padding = (0, 0)
152 | output_size = crop_size
153 |
154 | reference_pts = get_reference_facial_points(output_size,
155 | inner_padding_factor,
156 | outer_padding,
157 | default_square)
158 |
159 | ref_pts = np.float32(reference_pts)
160 | ref_pts_shp = ref_pts.shape
161 | if max(ref_pts_shp) < 3 or min(ref_pts_shp) != 2:
162 | raise FaceWarpException(
163 | 'reference_pts.shape must be (K,2) or (2,K) and K>2')
164 |
165 | if ref_pts_shp[0] == 2:
166 | ref_pts = ref_pts.T
167 |
168 | src_pts = np.float32(facial_pts)
169 | src_pts_shp = src_pts.shape
170 | if max(src_pts_shp) < 3 or min(src_pts_shp) != 2:
171 | raise FaceWarpException(
172 | 'facial_pts.shape must be (K,2) or (2,K) and K>2')
173 |
174 | if src_pts_shp[0] == 2:
175 | src_pts = src_pts.T
176 |
177 | if src_pts.shape != ref_pts.shape:
178 | raise FaceWarpException(
179 | 'facial_pts and reference_pts must have the same shape')
180 |
181 | if align_type is 'cv2_affine':
182 | tfm = cv2.getAffineTransform(src_pts[0:3], ref_pts[0:3])
183 | # print('cv2.getAffineTransform() returns tfm=\n' + str(tfm))
184 | elif align_type is 'affine':
185 | tfm = get_affine_transform_matrix(src_pts, ref_pts)
186 | # print('get_affine_transform_matrix() returns tfm=\n' + str(tfm))
187 | else:
188 | # tfm = get_similarity_transform_for_cv2(src_pts, ref_pts)
189 | tform = trans.SimilarityTransform()
190 | tform.estimate(src_pts, ref_pts)
191 | tfm = tform.params[0:2, :]
192 |
193 | face_img = cv2.warpAffine(src_img, tfm, (crop_size[0], crop_size[1]))
194 |
195 | return face_img
196 |
--------------------------------------------------------------------------------
/baidu_aip/test.py:
--------------------------------------------------------------------------------
1 | from utils_aip import get_face_attributes
2 |
3 | if __name__ == "__main__":
4 | filePath = "../images/wanghong.jpg"
5 |
6 | attr = get_face_attributes(filePath)
7 |
8 | print(attr)
9 |
--------------------------------------------------------------------------------
/config.py:
--------------------------------------------------------------------------------
1 | import torch
2 |
3 | device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') # sets device for model and PyTorch tensors
4 |
5 | # Model parameters
6 | image_w = 224
7 | image_h = 224
8 | im_size = 224
9 | channel = 3
10 |
11 | # Training parameters
12 | num_workers = 1 # for data-loading; right now, only 1 works with h5py
13 | grad_clip = 5. # clip gradients at an absolute value of
14 | print_freq = 100 # print training/validation stats every __ batches
15 | checkpoint = None # path to checkpoint, None if none
16 | loss_ratio = 100
17 |
18 | # Data parameters
19 | num_samples = 382401
20 | train_ratio = 0.9
21 | num_train = int(num_samples * train_ratio)
22 | DATA_DIR = 'data'
23 | IMG_DIR = 'data/images'
24 | pickle_file = DATA_DIR + '/' + 'CASIA-WebFace.pkl'
25 | pickle_file_aligned = DATA_DIR + '/' + 'CASIA-WebFace-aligned.pkl'
26 |
27 | # name_list = ['age', 'pitch', 'roll', 'yaw', 'beauty', 'expression', 'face_prob', 'face_shape', 'face_type',
28 | # 'gender', 'glasses', 'race']
29 | name_list = ['beauty']
30 |
31 | expression_dict = {0: 'none', 1: 'smile', 2: 'laugh'}
32 | face_shape_dict = {0: 'square', 1: 'oval', 2: 'heart', 3: 'round', 4: 'triangle'}
33 | face_type_dict = {0: 'human', 1: 'cartoon'}
34 | gender_dict = {0: 'female', 1: 'male'}
35 | glasses_dict = {0: 'none', 1: 'sun', 2: 'common'}
36 | race_dict = {0: 'yellow', 1: 'white', 2: 'black', 3: 'arabs'}
--------------------------------------------------------------------------------
/data_gen.py:
--------------------------------------------------------------------------------
1 | import os
2 | import pickle
3 |
4 | import cv2 as cv
5 | import numpy as np
6 | from torch.utils.data import Dataset
7 | from torchvision import transforms
8 |
9 | from config import im_size, pickle_file_aligned, num_train, IMG_DIR
10 | from utils import name2idx
11 |
12 | # Data augmentation and normalization for training
13 | # Just normalization for validation
14 | data_transforms = {
15 | 'train': transforms.Compose([
16 | transforms.ToTensor(),
17 | transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]),
18 | ]),
19 | 'valid': transforms.Compose([
20 | transforms.ToTensor(),
21 | transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
22 | ]),
23 | }
24 |
25 |
26 | class FaceAttributesDataset(Dataset):
27 | def __init__(self, split):
28 | with open(pickle_file_aligned, 'rb') as file:
29 | data = pickle.load(file)
30 |
31 | samples = data['samples']
32 |
33 | if split == 'train':
34 | self.samples = samples[:num_train]
35 | else:
36 | self.samples = samples[num_train:]
37 |
38 | self.transformer = data_transforms[split]
39 |
40 | def __getitem__(self, i):
41 | sample = self.samples[i]
42 | filename = sample['filename']
43 | full_path = os.path.join(IMG_DIR, filename)
44 | # full_path = sample['filename']
45 | # bbox = sample['bboxes'][0]
46 | img = cv.imread(full_path)
47 | # img = crop_image(img, bbox)
48 | img = cv.resize(img, (im_size, im_size))
49 |
50 | # img aug
51 | img = img[..., ::-1] # RGB
52 | img = transforms.ToPILImage()(img)
53 | img = self.transformer(img)
54 |
55 | age = sample['attr']['age'] / 100.
56 | pitch = (sample['attr']['angle']['pitch'] + 180) / 360
57 | roll = (sample['attr']['angle']['roll'] + 180) / 360
58 | yaw = (sample['attr']['angle']['yaw'] + 180) / 360
59 | beauty = sample['attr']['beauty'] / 100.
60 |
61 | expression = name2idx(sample['attr']['expression']['type'])
62 | gender = name2idx(sample['attr']['gender']['type'])
63 | glasses = name2idx(sample['attr']['glasses']['type'])
64 | race = name2idx(sample['attr']['race']['type'])
65 | return img, np.array([age, pitch, roll, yaw, beauty]), expression, gender, glasses, race
66 |
67 | def __len__(self):
68 | return len(self.samples)
69 |
70 |
71 | if __name__ == "__main__":
72 | dataset = FaceAttributesDataset('train')
73 | print(dataset[0])
74 |
--------------------------------------------------------------------------------
/data_stats.py:
--------------------------------------------------------------------------------
1 | import pickle
2 |
3 | import matplotlib.pyplot as plt
4 | import numpy as np
5 | import scipy.stats
6 | from tqdm import tqdm
7 |
8 | from config import pickle_file
9 |
10 |
11 | def compute_distribution(name):
12 | print('computing {}...'.format(name))
13 |
14 | x = []
15 | for sample in tqdm(samples):
16 | value = sample['attr'][name]
17 | x.append(value)
18 |
19 | bins = np.linspace(0, 100, 101)
20 |
21 | # the histogram of the data
22 | plt.hist(x, bins, density=True, alpha=0.5, label='1', facecolor='blue')
23 |
24 | mu = np.mean(x)
25 | sigma = np.std(x)
26 | y = scipy.stats.norm.pdf(bins, mu, sigma)
27 | plt.plot(bins, y, 'r--')
28 | plt.xlabel(name)
29 | plt.ylabel('{} distribution'.format(name))
30 | plt.title('Histogram: mu={:.4f}, sigma={:.4f}'.format(mu, sigma))
31 |
32 | plt.savefig('images/{}_dist.png'.format(name))
33 | plt.grid(True)
34 | plt.show()
35 |
36 |
37 | def compute_angle_distribution(name):
38 | print('computing angle-{}...'.format(name))
39 |
40 | x = []
41 | for sample in tqdm(samples):
42 | value = sample['attr']['angle'][name]
43 | x.append(value)
44 |
45 | bins = np.linspace(-180, 180, 361)
46 |
47 | # the histogram of the data
48 | plt.hist(x, bins, density=True, alpha=0.5, label='1', facecolor='blue')
49 |
50 | mu = np.mean(x)
51 | sigma = np.std(x)
52 | y = scipy.stats.norm.pdf(bins, mu, sigma)
53 | plt.plot(bins, y, 'r--')
54 | plt.xlabel('angle-{}'.format(name))
55 | plt.ylabel('angle-{} distribution'.format(name))
56 | plt.title('Histogram: mu={:.4f}, sigma={:.4f}'.format(mu, sigma))
57 |
58 | plt.savefig('images/angle_{}_dist.png'.format(name))
59 | plt.grid(True)
60 | plt.show()
61 |
62 |
63 | def compute_pmf_distribution(name):
64 | print('computing {}...'.format(name))
65 |
66 | c = dict()
67 | for sample in tqdm(samples):
68 | type = sample['attr'][name]['type']
69 | if type in c:
70 | c[type] += 1
71 | else:
72 | c[type] = 1
73 |
74 | x = c.keys()
75 | y = list(c.values())
76 | y = np.array(y)
77 | y = y / y.sum()
78 | y = list(y)
79 | plt.bar(x, y, color='blue')
80 | plt.title(name)
81 |
82 | plt.savefig('images/{}_dist.png'.format(name))
83 | plt.grid(True)
84 | plt.show()
85 |
86 |
87 | if __name__ == "__main__":
88 | with open(pickle_file, 'rb') as file:
89 | data = pickle.load(file)
90 |
91 | samples = data['samples']
92 |
93 | # compute_distribution('age')
94 | # compute_distribution('beauty')
95 |
96 | # compute_angle_distribution('pitch')
97 | # compute_angle_distribution('roll')
98 | # compute_angle_distribution('yaw')
99 |
100 | compute_pmf_distribution('expression')
101 | compute_pmf_distribution('face_shape')
102 | compute_pmf_distribution('face_type')
103 | compute_pmf_distribution('gender')
104 | compute_pmf_distribution('glasses')
105 | compute_pmf_distribution('race')
106 |
--------------------------------------------------------------------------------
/demo.py:
--------------------------------------------------------------------------------
1 | import json
2 | import os
3 | import pickle
4 | import random
5 |
6 | import cv2 as cv
7 | import torch
8 | from torchvision import transforms
9 |
10 | from config import device, im_size, pickle_file_aligned, train_ratio, IMG_DIR
11 | from data_gen import data_transforms
12 | from utils import idx2name
13 |
14 |
15 | def save_images(full_path, filename, i):
16 | raw = cv.imread(full_path)
17 | resized = cv.resize(raw, (im_size, im_size))
18 | cv.imwrite('images/{}_raw.jpg'.format(i), resized)
19 |
20 | img = cv.imread(os.path.join(IMG_DIR, filename))
21 | img = cv.resize(img, (im_size, im_size))
22 | cv.imwrite('images/{}_img.jpg'.format(i), img)
23 |
24 |
25 | if __name__ == "__main__":
26 | with open(pickle_file_aligned, 'rb') as file:
27 | data = pickle.load(file)
28 |
29 | samples = data['samples']
30 |
31 | num_samples = len(samples)
32 | num_train = int(train_ratio * num_samples)
33 | samples = samples[num_train:]
34 | samples = random.sample(samples, 10)
35 |
36 | inputs = torch.zeros([10, 3, im_size, im_size], dtype=torch.float, device=device)
37 |
38 | transformer = data_transforms['valid']
39 |
40 | sample_preds = []
41 |
42 | for i, sample in enumerate(samples):
43 | full_path = sample['full_path']
44 | filename = sample['filename']
45 | print(filename)
46 | save_images(full_path, filename, i)
47 |
48 | full_path = os.path.join(IMG_DIR, filename)
49 | # full_path = sample['filename']
50 | # bbox = sample['bboxes'][0]
51 | img = cv.imread(full_path)
52 | # img = crop_image(img, bbox)
53 | img = cv.resize(img, (im_size, im_size))
54 |
55 | img = cv.resize(img, (im_size, im_size))
56 | img = img[..., ::-1] # RGB
57 | img = transforms.ToPILImage()(img)
58 | img = transformer(img)
59 | inputs[i] = img
60 |
61 | age = sample['attr']['age']
62 | pitch = sample['attr']['angle']['pitch']
63 | roll = sample['attr']['angle']['roll']
64 | yaw = sample['attr']['angle']['yaw']
65 | beauty = sample['attr']['beauty']
66 | expression = sample['attr']['expression']['type']
67 | face_prob = sample['attr']['face_probability']
68 | face_shape = sample['attr']['face_shape']['type']
69 | face_type = sample['attr']['face_type']['type']
70 | gender = sample['attr']['gender']['type']
71 | glasses = sample['attr']['glasses']['type']
72 | race = sample['attr']['race']['type']
73 | sample_preds.append({'i': i, 'age_true': age,
74 | 'pitch_true': pitch,
75 | 'roll_true': roll,
76 | 'yaw_true': yaw,
77 | 'beauty_true': beauty,
78 | 'expression_true': expression,
79 | 'face_prob_true': face_prob,
80 | 'face_shape_true': face_shape,
81 | 'face_type_true': face_type,
82 | 'gender_true': gender,
83 | 'glasses_true': glasses,
84 | 'race_true': race})
85 |
86 | checkpoint = 'BEST_checkpoint.tar'
87 | checkpoint = torch.load(checkpoint)
88 | model = checkpoint['model']
89 | model = model.to(device)
90 | model.eval()
91 |
92 | with torch.no_grad():
93 | reg_out, expression_out, gender_out, glasses_out, race_out = model(inputs)
94 |
95 | print(reg_out.size())
96 | reg_out = reg_out.cpu().numpy()
97 | age_out = reg_out[:, 0]
98 | pitch_out = reg_out[:, 1]
99 | roll_out = reg_out[:, 2]
100 | yaw_out = reg_out[:, 3]
101 | beauty_out = reg_out[:, 4]
102 |
103 | _, expression_out = expression_out.topk(1, 1, True, True)
104 | print('expression_out.size(): ' + str(expression_out.size()))
105 | _, gender_out = gender_out.topk(1, 1, True, True)
106 | print('gender_out.size(): ' + str(gender_out.size()))
107 | _, glasses_out = glasses_out.topk(1, 1, True, True)
108 | print('glasses_out.size(): ' + str(glasses_out.size()))
109 | _, race_out = race_out.topk(1, 1, True, True)
110 | print('race_out.size(): ' + str(race_out.size()))
111 |
112 | expression_out = expression_out.cpu().numpy()
113 | print('expression_out.shape: ' + str(expression_out.shape))
114 | gender_out = gender_out.cpu().numpy()
115 | print('gender_out.shape: ' + str(gender_out.shape))
116 | glasses_out = glasses_out.cpu().numpy()
117 | print('glasses_out.shape: ' + str(glasses_out.shape))
118 | race_out = race_out.cpu().numpy()
119 | print('race_out.shape: ' + str(race_out.shape))
120 |
121 | for i in range(10):
122 | sample = sample_preds[i]
123 |
124 | sample['age_out'] = int(age_out[i] * 100)
125 | sample['pitch_out'] = float('{0:.2f}'.format(pitch_out[i] * 360 - 180))
126 | sample['roll_out'] = float('{0:.2f}'.format(roll_out[i] * 360 - 180))
127 | sample['yaw_out'] = float('{0:.2f}'.format(yaw_out[i] * 360 - 180))
128 | sample['beauty_out'] = float('{0:.2f}'.format(beauty_out[i] * 100))
129 | sample['expression_out'] = idx2name(int(expression_out[i][0]), 'expression')
130 | sample['gender_out'] = idx2name(int(gender_out[i][0]), 'gender')
131 | sample['glasses_out'] = idx2name(int(glasses_out[i][0]), 'glasses')
132 | sample['race_out'] = idx2name(int(race_out[i][0]), 'race')
133 |
134 | with open('sample_preds.json', 'w') as file:
135 | json.dump(sample_preds, file, indent=4, ensure_ascii=False)
136 |
--------------------------------------------------------------------------------
/download.py:
--------------------------------------------------------------------------------
1 | import os
2 | import pickle
3 |
4 | from ratelimit import limits, sleep_and_retry
5 | from tqdm import tqdm
6 |
7 | from config import pickle_file
8 | from utils_aip import get_face_attributes
9 |
10 | ONE_SECOND = 1
11 |
12 |
13 | @sleep_and_retry
14 | @limits(calls=2, period=ONE_SECOND)
15 | def get_attr(fn):
16 | return get_face_attributes(fn)
17 |
18 |
19 | if __name__ == "__main__":
20 | subjects = [d for d in os.listdir('data/CASIA-WebFace') if os.path.isdir(os.path.join('data/CASIA-WebFace', d))]
21 | assert (len(subjects) == 10575), "Number of subjects is: {}!".format(len(subjects))
22 |
23 | file_names = []
24 | for i in range(len(subjects)):
25 | sub = subjects[i]
26 | folder = os.path.join('data/CASIA-WebFace', sub)
27 | files = [f for f in os.listdir(folder) if
28 | os.path.isfile(os.path.join(folder, f)) and f.lower().endswith('.jpg')]
29 | for file in files:
30 | filename = os.path.join(folder, file)
31 | file_names.append({'filename': filename, 'class_id': i, 'subject': sub})
32 |
33 | assert (len(file_names) == 494414), "Number of files is: {}!".format(len(file_names))
34 |
35 | samples = []
36 | for item in tqdm(file_names):
37 | filename = item['filename']
38 | try:
39 | attr = get_attr(filename)
40 |
41 | if len(attr) > 0:
42 | class_id = item['class_id']
43 | sub = item['subject']
44 |
45 | samples.append(
46 | {'class_id': class_id, 'subject': sub, 'full_path': filename, 'attr': attr})
47 | except Exception as err:
48 | print(err)
49 |
50 | print('num_samples: ' + str(len(samples)))
51 |
52 | with open(pickle_file, 'wb') as file:
53 | save = {
54 | 'samples': samples
55 | }
56 | pickle.dump(save, file, pickle.HIGHEST_PROTOCOL)
57 |
--------------------------------------------------------------------------------
/export.py:
--------------------------------------------------------------------------------
1 | import time
2 |
3 | import torch
4 |
5 | from models import FaceAttributeModel
6 |
7 | if __name__ == '__main__':
8 | checkpoint = 'BEST_checkpoint.tar'
9 | print('loading {}...'.format(checkpoint))
10 | start = time.time()
11 | checkpoint = torch.load(checkpoint)
12 | print('elapsed {} sec'.format(time.time() - start))
13 | model = checkpoint['model'].module
14 | print(type(model))
15 | # model.eval()
16 |
17 | filename = 'face-attributes.pt'
18 | torch.save(model.state_dict(), filename)
19 | start = time.time()
20 | torch.save(model.state_dict(), filename)
21 | print('elapsed {} sec'.format(time.time() - start))
22 |
23 | print('loading {}...'.format(filename))
24 | start = time.time()
25 | model = FaceAttributeModel()
26 | model.load_state_dict(torch.load(filename))
27 | print('elapsed {} sec'.format(time.time() - start))
28 |
29 | filename_scripted = 'face-attributes_scripted.pt'
30 | print('saving {}...'.format(filename_scripted))
31 | start = time.time()
32 | torch.jit.save(torch.jit.script(model), filename_scripted)
33 | print('elapsed {} sec'.format(time.time() - start))
34 |
35 | print('loading {}...'.format(filename))
36 | start = time.time()
37 | model = torch.jit.load(filename_scripted)
38 | print('elapsed {} sec'.format(time.time() - start))
39 |
--------------------------------------------------------------------------------
/extract.py:
--------------------------------------------------------------------------------
1 | import os
2 | import zipfile
3 |
4 |
5 | def extract(filename):
6 | print('Extracting {}...'.format(filename))
7 | zip_ref = zipfile.ZipFile(filename, 'r')
8 | zip_ref.extractall('data')
9 | zip_ref.close()
10 |
11 |
12 | if __name__ == "__main__":
13 | if not os.path.isdir('data/CASIA-WebFace'):
14 | extract('data/CASIA-WebFace.zip')
15 |
--------------------------------------------------------------------------------
/get_prob.py:
--------------------------------------------------------------------------------
1 | from scipy.stats import norm
2 |
3 |
4 | def get_prob(beauty):
5 | mu = 49.1982
6 | sigma = 14.0220
7 | prob = norm.cdf(beauty, mu, sigma)
8 | return prob
9 |
10 |
11 | if __name__ == '__main__':
12 | print(get_prob(80))
13 |
--------------------------------------------------------------------------------
/images/003ac.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/foamliu/Face-Attributes-Mobile/5ad6186312308f95495a6bf17e9fa9b4f4f4604f/images/003ac.jpg
--------------------------------------------------------------------------------
/images/0_img.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/foamliu/Face-Attributes-Mobile/5ad6186312308f95495a6bf17e9fa9b4f4f4604f/images/0_img.jpg
--------------------------------------------------------------------------------
/images/0_raw.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/foamliu/Face-Attributes-Mobile/5ad6186312308f95495a6bf17e9fa9b4f4f4604f/images/0_raw.jpg
--------------------------------------------------------------------------------
/images/1.JPG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/foamliu/Face-Attributes-Mobile/5ad6186312308f95495a6bf17e9fa9b4f4f4604f/images/1.JPG
--------------------------------------------------------------------------------
/images/1_img.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/foamliu/Face-Attributes-Mobile/5ad6186312308f95495a6bf17e9fa9b4f4f4604f/images/1_img.jpg
--------------------------------------------------------------------------------
/images/1_raw.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/foamliu/Face-Attributes-Mobile/5ad6186312308f95495a6bf17e9fa9b4f4f4604f/images/1_raw.jpg
--------------------------------------------------------------------------------
/images/2_img.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/foamliu/Face-Attributes-Mobile/5ad6186312308f95495a6bf17e9fa9b4f4f4604f/images/2_img.jpg
--------------------------------------------------------------------------------
/images/2_raw.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/foamliu/Face-Attributes-Mobile/5ad6186312308f95495a6bf17e9fa9b4f4f4604f/images/2_raw.jpg
--------------------------------------------------------------------------------
/images/3_img.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/foamliu/Face-Attributes-Mobile/5ad6186312308f95495a6bf17e9fa9b4f4f4604f/images/3_img.jpg
--------------------------------------------------------------------------------
/images/3_raw.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/foamliu/Face-Attributes-Mobile/5ad6186312308f95495a6bf17e9fa9b4f4f4604f/images/3_raw.jpg
--------------------------------------------------------------------------------
/images/4_img.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/foamliu/Face-Attributes-Mobile/5ad6186312308f95495a6bf17e9fa9b4f4f4604f/images/4_img.jpg
--------------------------------------------------------------------------------
/images/4_raw.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/foamliu/Face-Attributes-Mobile/5ad6186312308f95495a6bf17e9fa9b4f4f4604f/images/4_raw.jpg
--------------------------------------------------------------------------------
/images/5_img.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/foamliu/Face-Attributes-Mobile/5ad6186312308f95495a6bf17e9fa9b4f4f4604f/images/5_img.jpg
--------------------------------------------------------------------------------
/images/5_raw.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/foamliu/Face-Attributes-Mobile/5ad6186312308f95495a6bf17e9fa9b4f4f4604f/images/5_raw.jpg
--------------------------------------------------------------------------------
/images/6_img.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/foamliu/Face-Attributes-Mobile/5ad6186312308f95495a6bf17e9fa9b4f4f4604f/images/6_img.jpg
--------------------------------------------------------------------------------
/images/6_raw.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/foamliu/Face-Attributes-Mobile/5ad6186312308f95495a6bf17e9fa9b4f4f4604f/images/6_raw.jpg
--------------------------------------------------------------------------------
/images/7_img.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/foamliu/Face-Attributes-Mobile/5ad6186312308f95495a6bf17e9fa9b4f4f4604f/images/7_img.jpg
--------------------------------------------------------------------------------
/images/7_raw.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/foamliu/Face-Attributes-Mobile/5ad6186312308f95495a6bf17e9fa9b4f4f4604f/images/7_raw.jpg
--------------------------------------------------------------------------------
/images/8_img.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/foamliu/Face-Attributes-Mobile/5ad6186312308f95495a6bf17e9fa9b4f4f4604f/images/8_img.jpg
--------------------------------------------------------------------------------
/images/8_raw.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/foamliu/Face-Attributes-Mobile/5ad6186312308f95495a6bf17e9fa9b4f4f4604f/images/8_raw.jpg
--------------------------------------------------------------------------------
/images/9_img.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/foamliu/Face-Attributes-Mobile/5ad6186312308f95495a6bf17e9fa9b4f4f4604f/images/9_img.jpg
--------------------------------------------------------------------------------
/images/9_raw.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/foamliu/Face-Attributes-Mobile/5ad6186312308f95495a6bf17e9fa9b4f4f4604f/images/9_raw.jpg
--------------------------------------------------------------------------------
/images/age_dist.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/foamliu/Face-Attributes-Mobile/5ad6186312308f95495a6bf17e9fa9b4f4f4604f/images/age_dist.png
--------------------------------------------------------------------------------
/images/angle_pitch_dist.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/foamliu/Face-Attributes-Mobile/5ad6186312308f95495a6bf17e9fa9b4f4f4604f/images/angle_pitch_dist.png
--------------------------------------------------------------------------------
/images/angle_roll_dist.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/foamliu/Face-Attributes-Mobile/5ad6186312308f95495a6bf17e9fa9b4f4f4604f/images/angle_roll_dist.png
--------------------------------------------------------------------------------
/images/angle_yaw_dist.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/foamliu/Face-Attributes-Mobile/5ad6186312308f95495a6bf17e9fa9b4f4f4604f/images/angle_yaw_dist.png
--------------------------------------------------------------------------------
/images/beauty_dist.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/foamliu/Face-Attributes-Mobile/5ad6186312308f95495a6bf17e9fa9b4f4f4604f/images/beauty_dist.png
--------------------------------------------------------------------------------
/images/euler_angles.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/foamliu/Face-Attributes-Mobile/5ad6186312308f95495a6bf17e9fa9b4f4f4604f/images/euler_angles.png
--------------------------------------------------------------------------------
/images/expression_dist.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/foamliu/Face-Attributes-Mobile/5ad6186312308f95495a6bf17e9fa9b4f4f4604f/images/expression_dist.png
--------------------------------------------------------------------------------
/images/face_shape_dist.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/foamliu/Face-Attributes-Mobile/5ad6186312308f95495a6bf17e9fa9b4f4f4604f/images/face_shape_dist.png
--------------------------------------------------------------------------------
/images/face_type_dist.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/foamliu/Face-Attributes-Mobile/5ad6186312308f95495a6bf17e9fa9b4f4f4604f/images/face_type_dist.png
--------------------------------------------------------------------------------
/images/gender_dist.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/foamliu/Face-Attributes-Mobile/5ad6186312308f95495a6bf17e9fa9b4f4f4604f/images/gender_dist.png
--------------------------------------------------------------------------------
/images/glasses_dist.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/foamliu/Face-Attributes-Mobile/5ad6186312308f95495a6bf17e9fa9b4f4f4604f/images/glasses_dist.png
--------------------------------------------------------------------------------
/images/img_flip_0.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/foamliu/Face-Attributes-Mobile/5ad6186312308f95495a6bf17e9fa9b4f4f4604f/images/img_flip_0.jpg
--------------------------------------------------------------------------------
/images/img_flip_1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/foamliu/Face-Attributes-Mobile/5ad6186312308f95495a6bf17e9fa9b4f4f4604f/images/img_flip_1.jpg
--------------------------------------------------------------------------------
/images/img_flip_2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/foamliu/Face-Attributes-Mobile/5ad6186312308f95495a6bf17e9fa9b4f4f4604f/images/img_flip_2.jpg
--------------------------------------------------------------------------------
/images/img_flip_3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/foamliu/Face-Attributes-Mobile/5ad6186312308f95495a6bf17e9fa9b4f4f4604f/images/img_flip_3.jpg
--------------------------------------------------------------------------------
/images/img_flip_4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/foamliu/Face-Attributes-Mobile/5ad6186312308f95495a6bf17e9fa9b4f4f4604f/images/img_flip_4.jpg
--------------------------------------------------------------------------------
/images/img_flip_5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/foamliu/Face-Attributes-Mobile/5ad6186312308f95495a6bf17e9fa9b4f4f4604f/images/img_flip_5.jpg
--------------------------------------------------------------------------------
/images/img_flip_6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/foamliu/Face-Attributes-Mobile/5ad6186312308f95495a6bf17e9fa9b4f4f4604f/images/img_flip_6.jpg
--------------------------------------------------------------------------------
/images/img_flip_7.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/foamliu/Face-Attributes-Mobile/5ad6186312308f95495a6bf17e9fa9b4f4f4604f/images/img_flip_7.jpg
--------------------------------------------------------------------------------
/images/img_flip_8.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/foamliu/Face-Attributes-Mobile/5ad6186312308f95495a6bf17e9fa9b4f4f4604f/images/img_flip_8.jpg
--------------------------------------------------------------------------------
/images/img_flip_9.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/foamliu/Face-Attributes-Mobile/5ad6186312308f95495a6bf17e9fa9b4f4f4604f/images/img_flip_9.jpg
--------------------------------------------------------------------------------
/images/img_norm_0.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/foamliu/Face-Attributes-Mobile/5ad6186312308f95495a6bf17e9fa9b4f4f4604f/images/img_norm_0.jpg
--------------------------------------------------------------------------------
/images/img_norm_1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/foamliu/Face-Attributes-Mobile/5ad6186312308f95495a6bf17e9fa9b4f4f4604f/images/img_norm_1.jpg
--------------------------------------------------------------------------------
/images/img_norm_2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/foamliu/Face-Attributes-Mobile/5ad6186312308f95495a6bf17e9fa9b4f4f4604f/images/img_norm_2.jpg
--------------------------------------------------------------------------------
/images/img_norm_3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/foamliu/Face-Attributes-Mobile/5ad6186312308f95495a6bf17e9fa9b4f4f4604f/images/img_norm_3.jpg
--------------------------------------------------------------------------------
/images/img_norm_4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/foamliu/Face-Attributes-Mobile/5ad6186312308f95495a6bf17e9fa9b4f4f4604f/images/img_norm_4.jpg
--------------------------------------------------------------------------------
/images/img_norm_5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/foamliu/Face-Attributes-Mobile/5ad6186312308f95495a6bf17e9fa9b4f4f4604f/images/img_norm_5.jpg
--------------------------------------------------------------------------------
/images/img_norm_6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/foamliu/Face-Attributes-Mobile/5ad6186312308f95495a6bf17e9fa9b4f4f4604f/images/img_norm_6.jpg
--------------------------------------------------------------------------------
/images/img_norm_7.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/foamliu/Face-Attributes-Mobile/5ad6186312308f95495a6bf17e9fa9b4f4f4604f/images/img_norm_7.jpg
--------------------------------------------------------------------------------
/images/img_norm_8.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/foamliu/Face-Attributes-Mobile/5ad6186312308f95495a6bf17e9fa9b4f4f4604f/images/img_norm_8.jpg
--------------------------------------------------------------------------------
/images/img_norm_9.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/foamliu/Face-Attributes-Mobile/5ad6186312308f95495a6bf17e9fa9b4f4f4604f/images/img_norm_9.jpg
--------------------------------------------------------------------------------
/images/learning_curve.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/foamliu/Face-Attributes-Mobile/5ad6186312308f95495a6bf17e9fa9b4f4f4604f/images/learning_curve.jpg
--------------------------------------------------------------------------------
/images/race_dist.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/foamliu/Face-Attributes-Mobile/5ad6186312308f95495a6bf17e9fa9b4f4f4604f/images/race_dist.png
--------------------------------------------------------------------------------
/images/wanghong.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/foamliu/Face-Attributes-Mobile/5ad6186312308f95495a6bf17e9fa9b4f4f4604f/images/wanghong.jpg
--------------------------------------------------------------------------------
/img_aug.py:
--------------------------------------------------------------------------------
1 | # import the OpenCV package
2 | import cv2
3 |
4 | # load the image with imread()
5 | imageSource = 'images/0_img.jpg'
6 | img = cv2.imread(imageSource)
7 |
8 | # copy image to display all 4 variations
9 | horizontal_img = img.copy()
10 | vertical_img = img.copy()
11 | both_img = img.copy()
12 |
13 | # flip img horizontally, vertically,
14 | # and both axes with flip()
15 | horizontal_img = cv2.flip(img, 1)
16 | vertical_img = cv2.flip(img, 0)
17 | both_img = cv2.flip(img, -1)
18 |
19 | # display the images on screen with imshow()
20 | cv2.imshow("Original", img)
21 | cv2.imshow("Horizontal flip", horizontal_img)
22 | cv2.imshow("Vertical flip", vertical_img)
23 | cv2.imshow("Both flip", both_img)
24 |
25 | # wait time in milliseconds
26 | # this is required to show the image
27 | # 0 = wait indefinitely
28 | cv2.waitKey(0)
29 |
30 | # close the windows
31 | cv2.destroyAllWindows()
--------------------------------------------------------------------------------
/models.py:
--------------------------------------------------------------------------------
1 | from torch import nn
2 | from torchscope import scope
3 | from torchvision import models
4 |
5 |
6 | class FaceAttributeModel(nn.Module):
7 | def __init__(self):
8 | super(FaceAttributeModel, self).__init__()
9 | model = models.mobilenet_v2(pretrained=True)
10 | # Remove linear and pool layers (since we're not doing classification)
11 | modules = list(model.children())[:-1]
12 | self.resnet = nn.Sequential(*modules)
13 | self.pool = nn.AvgPool2d(kernel_size=7)
14 | self.fc = nn.Linear(1280, 17)
15 | self.sigmoid = nn.Sigmoid()
16 | self.softmax = nn.Softmax(dim=-1)
17 |
18 | def forward(self, images):
19 | x = self.resnet(images) # [N, 1280, 1, 1]
20 | x = self.pool(x)
21 | x = x.view(-1, 1280) # [N, 1280]
22 | x = self.fc(x)
23 | reg = self.sigmoid(x[:, :5]) # [N, 8]
24 | expression = self.softmax(x[:, 5:8])
25 | gender = self.softmax(x[:, 8:10])
26 | glasses = self.softmax(x[:, 10:13])
27 | race = self.softmax(x[:, 13:17])
28 | return reg, expression, gender, glasses, race
29 |
30 |
31 | if __name__ == "__main__":
32 | model = FaceAttributeModel()
33 | scope(model, input_size=(3, 224, 224))
34 |
--------------------------------------------------------------------------------
/pre_process.py:
--------------------------------------------------------------------------------
1 | import os
2 | import pickle
3 |
4 | import cv2 as cv
5 | from tqdm import tqdm
6 |
7 | from config import IMG_DIR, pickle_file, pickle_file_aligned
8 | from retinaface.detector import detect_faces
9 | from utils import ensure_folder, crop_image
10 |
11 |
12 | def select_significant_face(bboxes):
13 | best_index = -1
14 | best_rank = float('-inf')
15 | for i, b in enumerate(bboxes):
16 | bbox_w, bbox_h = b[2] - b[0], b[3] - b[1]
17 | area = bbox_w * bbox_h
18 | score = b[4]
19 | rank = score * area
20 | if rank > best_rank:
21 | best_rank = rank
22 | best_index = i
23 |
24 | return best_index
25 |
26 |
27 | if __name__ == "__main__":
28 | ensure_folder(IMG_DIR)
29 |
30 | print('loading {}...'.format(pickle_file))
31 | with open(pickle_file, 'rb') as file:
32 | data = pickle.load(file)
33 |
34 | items = data['samples']
35 | print('num_items: ' + str(len(items)))
36 |
37 | samples = []
38 | for item in tqdm(items):
39 | try:
40 | full_path = item['full_path']
41 | img = cv.imread(full_path)
42 | bboxes, landmarks = detect_faces(img)
43 | idx = select_significant_face(bboxes)
44 | bbox = bboxes[idx]
45 | img = crop_image(img, bbox)
46 | filename = full_path.replace('data/CASIA-WebFace/', '').replace('/', '_')
47 |
48 | item['filename'] = filename
49 | samples.append(item)
50 |
51 | filename = os.path.join(IMG_DIR, filename)
52 | cv.imwrite(filename, img)
53 |
54 | except Exception as err:
55 | print(err)
56 |
57 | print('num_samples: ' + str(len(samples)))
58 |
59 | with open(pickle_file_aligned, 'wb') as file:
60 | save = {
61 | 'samples': samples
62 | }
63 | pickle.dump(save, file, pickle.HIGHEST_PROTOCOL)
64 |
--------------------------------------------------------------------------------
/replace_macros.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | import json
3 |
4 |
5 | def safe_get(dic, key):
6 | if key in dic:
7 | return dic[key]
8 | else:
9 | return None
10 |
11 |
12 | def get_attrs(item, split):
13 | age = safe_get(item, 'age_' + split)
14 | pitch = safe_get(item, 'pitch_' + split)
15 | roll = safe_get(item, 'roll_' + split)
16 | yaw = safe_get(item, 'yaw_' + split)
17 | beauty = safe_get(item, 'beauty_' + split)
18 | expression = safe_get(item, 'expression_' + split)
19 | # face_prob = safe_get(item, 'face_prob_' + split)
20 | # face_shape = safe_get(item, 'face_shape_' + split)
21 | # face_type = safe_get(item, 'face_type_' + split)
22 | gender = safe_get(item, 'gender_' + split)
23 | glasses = safe_get(item, 'glasses_' + split)
24 | race = safe_get(item, 'race_' + split)
25 | result = 'age: {}
'.format(age)
26 | result += 'pitch: {}
'.format(pitch)
27 | result += 'roll: {}
'.format(roll)
28 | result += 'yaw: {}
'.format(yaw)
29 | result += 'beauty: {}
'.format(beauty)
30 | result += 'expression: {}
'.format(expression)
31 | # result += 'face_prob: {}
'.format(face_prob)
32 | # result += 'face_shape: {}
'.format(face_shape)
33 | # result += 'face_type: {}
'.format(face_type)
34 | result += 'gender: {}
'.format(gender)
35 | result += 'glasses: {}
'.format(glasses)
36 | result += 'race: {}'.format(race)
37 | return result
38 |
39 |
40 | if __name__ == '__main__':
41 | with open('README.t', 'r', encoding="utf-8") as file:
42 | text = file.readlines()
43 | text = ''.join(text)
44 |
45 | with open('sample_preds.json', 'r', encoding="utf-8") as file:
46 | results = json.load(file)
47 |
48 | for i in range(10):
49 | item = results[i]
50 | result_true = get_attrs(item, 'true')
51 | result_out = get_attrs(item, 'out')
52 | text = text.replace('$(result_true_{})'.format(i), result_true)
53 | text = text.replace('$(result_out_{})'.format(i), result_out)
54 |
55 | with open('README.md', 'w', encoding="utf-8") as file:
56 | file.write(text)
57 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | baidu-aip
2 | ratelimit
--------------------------------------------------------------------------------
/retinaface/data/FDDB/img_list.txt:
--------------------------------------------------------------------------------
1 | 2002/08/11/big/img_591
2 | 2002/08/26/big/img_265
3 | 2002/07/19/big/img_423
4 | 2002/08/24/big/img_490
5 | 2002/08/31/big/img_17676
6 | 2002/07/31/big/img_228
7 | 2002/07/24/big/img_402
8 | 2002/08/04/big/img_769
9 | 2002/07/19/big/img_581
10 | 2002/08/13/big/img_723
11 | 2002/08/12/big/img_821
12 | 2003/01/17/big/img_610
13 | 2002/08/13/big/img_1116
14 | 2002/08/28/big/img_19238
15 | 2002/08/21/big/img_660
16 | 2002/08/14/big/img_607
17 | 2002/08/05/big/img_3708
18 | 2002/08/19/big/img_511
19 | 2002/08/07/big/img_1316
20 | 2002/07/25/big/img_1047
21 | 2002/07/23/big/img_474
22 | 2002/07/27/big/img_970
23 | 2002/09/02/big/img_15752
24 | 2002/09/01/big/img_16378
25 | 2002/09/01/big/img_16189
26 | 2002/08/26/big/img_276
27 | 2002/07/24/big/img_518
28 | 2002/08/14/big/img_1027
29 | 2002/08/24/big/img_733
30 | 2002/08/15/big/img_249
31 | 2003/01/15/big/img_1371
32 | 2002/08/07/big/img_1348
33 | 2003/01/01/big/img_331
34 | 2002/08/23/big/img_536
35 | 2002/07/30/big/img_224
36 | 2002/08/10/big/img_763
37 | 2002/08/21/big/img_293
38 | 2002/08/15/big/img_1211
39 | 2002/08/15/big/img_1194
40 | 2003/01/15/big/img_390
41 | 2002/08/06/big/img_2893
42 | 2002/08/17/big/img_691
43 | 2002/08/07/big/img_1695
44 | 2002/08/16/big/img_829
45 | 2002/07/25/big/img_201
46 | 2002/08/23/big/img_36
47 | 2003/01/15/big/img_763
48 | 2003/01/15/big/img_637
49 | 2002/08/22/big/img_592
50 | 2002/07/25/big/img_817
51 | 2003/01/15/big/img_1219
52 | 2002/08/05/big/img_3508
53 | 2002/08/15/big/img_1108
54 | 2002/07/19/big/img_488
55 | 2003/01/16/big/img_704
56 | 2003/01/13/big/img_1087
57 | 2002/08/10/big/img_670
58 | 2002/07/24/big/img_104
59 | 2002/08/27/big/img_19823
60 | 2002/09/01/big/img_16229
61 | 2003/01/13/big/img_846
62 | 2002/08/04/big/img_412
63 | 2002/07/22/big/img_554
64 | 2002/08/12/big/img_331
65 | 2002/08/02/big/img_533
66 | 2002/08/12/big/img_259
67 | 2002/08/18/big/img_328
68 | 2003/01/14/big/img_630
69 | 2002/08/05/big/img_3541
70 | 2002/08/06/big/img_2390
71 | 2002/08/20/big/img_150
72 | 2002/08/02/big/img_1231
73 | 2002/08/16/big/img_710
74 | 2002/08/19/big/img_591
75 | 2002/07/22/big/img_725
76 | 2002/07/24/big/img_820
77 | 2003/01/13/big/img_568
78 | 2002/08/22/big/img_853
79 | 2002/08/09/big/img_648
80 | 2002/08/23/big/img_528
81 | 2003/01/14/big/img_888
82 | 2002/08/30/big/img_18201
83 | 2002/08/13/big/img_965
84 | 2003/01/14/big/img_660
85 | 2002/07/19/big/img_517
86 | 2003/01/14/big/img_406
87 | 2002/08/30/big/img_18433
88 | 2002/08/07/big/img_1630
89 | 2002/08/06/big/img_2717
90 | 2002/08/21/big/img_470
91 | 2002/07/23/big/img_633
92 | 2002/08/20/big/img_915
93 | 2002/08/16/big/img_893
94 | 2002/07/29/big/img_644
95 | 2002/08/15/big/img_529
96 | 2002/08/16/big/img_668
97 | 2002/08/07/big/img_1871
98 | 2002/07/25/big/img_192
99 | 2002/07/31/big/img_961
100 | 2002/08/19/big/img_738
101 | 2002/07/31/big/img_382
102 | 2002/08/19/big/img_298
103 | 2003/01/17/big/img_608
104 | 2002/08/21/big/img_514
105 | 2002/07/23/big/img_183
106 | 2003/01/17/big/img_536
107 | 2002/07/24/big/img_478
108 | 2002/08/06/big/img_2997
109 | 2002/09/02/big/img_15380
110 | 2002/08/07/big/img_1153
111 | 2002/07/31/big/img_967
112 | 2002/07/31/big/img_711
113 | 2002/08/26/big/img_664
114 | 2003/01/01/big/img_326
115 | 2002/08/24/big/img_775
116 | 2002/08/08/big/img_961
117 | 2002/08/16/big/img_77
118 | 2002/08/12/big/img_296
119 | 2002/07/22/big/img_905
120 | 2003/01/13/big/img_284
121 | 2002/08/13/big/img_887
122 | 2002/08/24/big/img_849
123 | 2002/07/30/big/img_345
124 | 2002/08/18/big/img_419
125 | 2002/08/01/big/img_1347
126 | 2002/08/05/big/img_3670
127 | 2002/07/21/big/img_479
128 | 2002/08/08/big/img_913
129 | 2002/09/02/big/img_15828
130 | 2002/08/30/big/img_18194
131 | 2002/08/08/big/img_471
132 | 2002/08/22/big/img_734
133 | 2002/08/09/big/img_586
134 | 2002/08/09/big/img_454
135 | 2002/07/29/big/img_47
136 | 2002/07/19/big/img_381
137 | 2002/07/29/big/img_733
138 | 2002/08/20/big/img_327
139 | 2002/07/21/big/img_96
140 | 2002/08/06/big/img_2680
141 | 2002/07/25/big/img_919
142 | 2002/07/21/big/img_158
143 | 2002/07/22/big/img_801
144 | 2002/07/22/big/img_567
145 | 2002/07/24/big/img_804
146 | 2002/07/24/big/img_690
147 | 2003/01/15/big/img_576
148 | 2002/08/14/big/img_335
149 | 2003/01/13/big/img_390
150 | 2002/08/11/big/img_258
151 | 2002/07/23/big/img_917
152 | 2002/08/15/big/img_525
153 | 2003/01/15/big/img_505
154 | 2002/07/30/big/img_886
155 | 2003/01/16/big/img_640
156 | 2003/01/14/big/img_642
157 | 2003/01/17/big/img_844
158 | 2002/08/04/big/img_571
159 | 2002/08/29/big/img_18702
160 | 2003/01/15/big/img_240
161 | 2002/07/29/big/img_553
162 | 2002/08/10/big/img_354
163 | 2002/08/18/big/img_17
164 | 2003/01/15/big/img_782
165 | 2002/07/27/big/img_382
166 | 2002/08/14/big/img_970
167 | 2003/01/16/big/img_70
168 | 2003/01/16/big/img_625
169 | 2002/08/18/big/img_341
170 | 2002/08/26/big/img_188
171 | 2002/08/09/big/img_405
172 | 2002/08/02/big/img_37
173 | 2002/08/13/big/img_748
174 | 2002/07/22/big/img_399
175 | 2002/07/25/big/img_844
176 | 2002/08/12/big/img_340
177 | 2003/01/13/big/img_815
178 | 2002/08/26/big/img_5
179 | 2002/08/10/big/img_158
180 | 2002/08/18/big/img_95
181 | 2002/07/29/big/img_1297
182 | 2003/01/13/big/img_508
183 | 2002/09/01/big/img_16680
184 | 2003/01/16/big/img_338
185 | 2002/08/13/big/img_517
186 | 2002/07/22/big/img_626
187 | 2002/08/06/big/img_3024
188 | 2002/07/26/big/img_499
189 | 2003/01/13/big/img_387
190 | 2002/08/31/big/img_18025
191 | 2002/08/13/big/img_520
192 | 2003/01/16/big/img_576
193 | 2002/07/26/big/img_121
194 | 2002/08/25/big/img_703
195 | 2002/08/26/big/img_615
196 | 2002/08/17/big/img_434
197 | 2002/08/02/big/img_677
198 | 2002/08/18/big/img_276
199 | 2002/08/05/big/img_3672
200 | 2002/07/26/big/img_700
201 | 2002/07/31/big/img_277
202 | 2003/01/14/big/img_220
203 | 2002/08/23/big/img_232
204 | 2002/08/31/big/img_17422
205 | 2002/07/22/big/img_508
206 | 2002/08/13/big/img_681
207 | 2003/01/15/big/img_638
208 | 2002/08/30/big/img_18408
209 | 2003/01/14/big/img_533
210 | 2003/01/17/big/img_12
211 | 2002/08/28/big/img_19388
212 | 2002/08/08/big/img_133
213 | 2002/07/26/big/img_885
214 | 2002/08/19/big/img_387
215 | 2002/08/27/big/img_19976
216 | 2002/08/26/big/img_118
217 | 2002/08/28/big/img_19146
218 | 2002/08/05/big/img_3259
219 | 2002/08/15/big/img_536
220 | 2002/07/22/big/img_279
221 | 2002/07/22/big/img_9
222 | 2002/08/13/big/img_301
223 | 2002/08/15/big/img_974
224 | 2002/08/06/big/img_2355
225 | 2002/08/01/big/img_1526
226 | 2002/08/03/big/img_417
227 | 2002/08/04/big/img_407
228 | 2002/08/15/big/img_1029
229 | 2002/07/29/big/img_700
230 | 2002/08/01/big/img_1463
231 | 2002/08/31/big/img_17365
232 | 2002/07/28/big/img_223
233 | 2002/07/19/big/img_827
234 | 2002/07/27/big/img_531
235 | 2002/07/19/big/img_845
236 | 2002/08/20/big/img_382
237 | 2002/07/31/big/img_268
238 | 2002/08/27/big/img_19705
239 | 2002/08/02/big/img_830
240 | 2002/08/23/big/img_250
241 | 2002/07/20/big/img_777
242 | 2002/08/21/big/img_879
243 | 2002/08/26/big/img_20146
244 | 2002/08/23/big/img_789
245 | 2002/08/06/big/img_2683
246 | 2002/08/25/big/img_576
247 | 2002/08/09/big/img_498
248 | 2002/08/08/big/img_384
249 | 2002/08/26/big/img_592
250 | 2002/07/29/big/img_1470
251 | 2002/08/21/big/img_452
252 | 2002/08/30/big/img_18395
253 | 2002/08/15/big/img_215
254 | 2002/07/21/big/img_643
255 | 2002/07/22/big/img_209
256 | 2003/01/17/big/img_346
257 | 2002/08/25/big/img_658
258 | 2002/08/21/big/img_221
259 | 2002/08/14/big/img_60
260 | 2003/01/17/big/img_885
261 | 2003/01/16/big/img_482
262 | 2002/08/19/big/img_593
263 | 2002/08/08/big/img_233
264 | 2002/07/30/big/img_458
265 | 2002/07/23/big/img_384
266 | 2003/01/15/big/img_670
267 | 2003/01/15/big/img_267
268 | 2002/08/26/big/img_540
269 | 2002/07/29/big/img_552
270 | 2002/07/30/big/img_997
271 | 2003/01/17/big/img_377
272 | 2002/08/21/big/img_265
273 | 2002/08/09/big/img_561
274 | 2002/07/31/big/img_945
275 | 2002/09/02/big/img_15252
276 | 2002/08/11/big/img_276
277 | 2002/07/22/big/img_491
278 | 2002/07/26/big/img_517
279 | 2002/08/14/big/img_726
280 | 2002/08/08/big/img_46
281 | 2002/08/28/big/img_19458
282 | 2002/08/06/big/img_2935
283 | 2002/07/29/big/img_1392
284 | 2002/08/13/big/img_776
285 | 2002/08/24/big/img_616
286 | 2002/08/14/big/img_1065
287 | 2002/07/29/big/img_889
288 | 2002/08/18/big/img_188
289 | 2002/08/07/big/img_1453
290 | 2002/08/02/big/img_760
291 | 2002/07/28/big/img_416
292 | 2002/08/07/big/img_1393
293 | 2002/08/26/big/img_292
294 | 2002/08/26/big/img_301
295 | 2003/01/13/big/img_195
296 | 2002/07/26/big/img_532
297 | 2002/08/20/big/img_550
298 | 2002/08/05/big/img_3658
299 | 2002/08/26/big/img_738
300 | 2002/09/02/big/img_15750
301 | 2003/01/17/big/img_451
302 | 2002/07/23/big/img_339
303 | 2002/08/16/big/img_637
304 | 2002/08/14/big/img_748
305 | 2002/08/06/big/img_2739
306 | 2002/07/25/big/img_482
307 | 2002/08/19/big/img_191
308 | 2002/08/26/big/img_537
309 | 2003/01/15/big/img_716
310 | 2003/01/15/big/img_767
311 | 2002/08/02/big/img_452
312 | 2002/08/08/big/img_1011
313 | 2002/08/10/big/img_144
314 | 2003/01/14/big/img_122
315 | 2002/07/24/big/img_586
316 | 2002/07/24/big/img_762
317 | 2002/08/20/big/img_369
318 | 2002/07/30/big/img_146
319 | 2002/08/23/big/img_396
320 | 2003/01/15/big/img_200
321 | 2002/08/15/big/img_1183
322 | 2003/01/14/big/img_698
323 | 2002/08/09/big/img_792
324 | 2002/08/06/big/img_2347
325 | 2002/07/31/big/img_911
326 | 2002/08/26/big/img_722
327 | 2002/08/23/big/img_621
328 | 2002/08/05/big/img_3790
329 | 2003/01/13/big/img_633
330 | 2002/08/09/big/img_224
331 | 2002/07/24/big/img_454
332 | 2002/07/21/big/img_202
333 | 2002/08/02/big/img_630
334 | 2002/08/30/big/img_18315
335 | 2002/07/19/big/img_491
336 | 2002/09/01/big/img_16456
337 | 2002/08/09/big/img_242
338 | 2002/07/25/big/img_595
339 | 2002/07/22/big/img_522
340 | 2002/08/01/big/img_1593
341 | 2002/07/29/big/img_336
342 | 2002/08/15/big/img_448
343 | 2002/08/28/big/img_19281
344 | 2002/07/29/big/img_342
345 | 2002/08/12/big/img_78
346 | 2003/01/14/big/img_525
347 | 2002/07/28/big/img_147
348 | 2002/08/11/big/img_353
349 | 2002/08/22/big/img_513
350 | 2002/08/04/big/img_721
351 | 2002/08/17/big/img_247
352 | 2003/01/14/big/img_891
353 | 2002/08/20/big/img_853
354 | 2002/07/19/big/img_414
355 | 2002/08/01/big/img_1530
356 | 2003/01/14/big/img_924
357 | 2002/08/22/big/img_468
358 | 2002/08/18/big/img_354
359 | 2002/08/30/big/img_18193
360 | 2002/08/23/big/img_492
361 | 2002/08/15/big/img_871
362 | 2002/08/12/big/img_494
363 | 2002/08/06/big/img_2470
364 | 2002/07/23/big/img_923
365 | 2002/08/26/big/img_155
366 | 2002/08/08/big/img_669
367 | 2002/07/23/big/img_404
368 | 2002/08/28/big/img_19421
369 | 2002/08/29/big/img_18993
370 | 2002/08/25/big/img_416
371 | 2003/01/17/big/img_434
372 | 2002/07/29/big/img_1370
373 | 2002/07/28/big/img_483
374 | 2002/08/11/big/img_50
375 | 2002/08/10/big/img_404
376 | 2002/09/02/big/img_15057
377 | 2003/01/14/big/img_911
378 | 2002/09/01/big/img_16697
379 | 2003/01/16/big/img_665
380 | 2002/09/01/big/img_16708
381 | 2002/08/22/big/img_612
382 | 2002/08/28/big/img_19471
383 | 2002/08/02/big/img_198
384 | 2003/01/16/big/img_527
385 | 2002/08/22/big/img_209
386 | 2002/08/30/big/img_18205
387 | 2003/01/14/big/img_114
388 | 2003/01/14/big/img_1028
389 | 2003/01/16/big/img_894
390 | 2003/01/14/big/img_837
391 | 2002/07/30/big/img_9
392 | 2002/08/06/big/img_2821
393 | 2002/08/04/big/img_85
394 | 2003/01/13/big/img_884
395 | 2002/07/22/big/img_570
396 | 2002/08/07/big/img_1773
397 | 2002/07/26/big/img_208
398 | 2003/01/17/big/img_946
399 | 2002/07/19/big/img_930
400 | 2003/01/01/big/img_698
401 | 2003/01/17/big/img_612
402 | 2002/07/19/big/img_372
403 | 2002/07/30/big/img_721
404 | 2003/01/14/big/img_649
405 | 2002/08/19/big/img_4
406 | 2002/07/25/big/img_1024
407 | 2003/01/15/big/img_601
408 | 2002/08/30/big/img_18470
409 | 2002/07/22/big/img_29
410 | 2002/08/07/big/img_1686
411 | 2002/07/20/big/img_294
412 | 2002/08/14/big/img_800
413 | 2002/08/19/big/img_353
414 | 2002/08/19/big/img_350
415 | 2002/08/05/big/img_3392
416 | 2002/08/09/big/img_622
417 | 2003/01/15/big/img_236
418 | 2002/08/11/big/img_643
419 | 2002/08/05/big/img_3458
420 | 2002/08/12/big/img_413
421 | 2002/08/22/big/img_415
422 | 2002/08/13/big/img_635
423 | 2002/08/07/big/img_1198
424 | 2002/08/04/big/img_873
425 | 2002/08/12/big/img_407
426 | 2003/01/15/big/img_346
427 | 2002/08/02/big/img_275
428 | 2002/08/17/big/img_997
429 | 2002/08/21/big/img_958
430 | 2002/08/20/big/img_579
431 | 2002/07/29/big/img_142
432 | 2003/01/14/big/img_1115
433 | 2002/08/16/big/img_365
434 | 2002/07/29/big/img_1414
435 | 2002/08/17/big/img_489
436 | 2002/08/13/big/img_1010
437 | 2002/07/31/big/img_276
438 | 2002/07/25/big/img_1000
439 | 2002/08/23/big/img_524
440 | 2002/08/28/big/img_19147
441 | 2003/01/13/big/img_433
442 | 2002/08/20/big/img_205
443 | 2003/01/01/big/img_458
444 | 2002/07/29/big/img_1449
445 | 2003/01/16/big/img_696
446 | 2002/08/28/big/img_19296
447 | 2002/08/29/big/img_18688
448 | 2002/08/21/big/img_767
449 | 2002/08/20/big/img_532
450 | 2002/08/26/big/img_187
451 | 2002/07/26/big/img_183
452 | 2002/07/27/big/img_890
453 | 2003/01/13/big/img_576
454 | 2002/07/30/big/img_15
455 | 2002/07/31/big/img_889
456 | 2002/08/31/big/img_17759
457 | 2003/01/14/big/img_1114
458 | 2002/07/19/big/img_445
459 | 2002/08/03/big/img_593
460 | 2002/07/24/big/img_750
461 | 2002/07/30/big/img_133
462 | 2002/08/25/big/img_671
463 | 2002/07/20/big/img_351
464 | 2002/08/31/big/img_17276
465 | 2002/08/05/big/img_3231
466 | 2002/09/02/big/img_15882
467 | 2002/08/14/big/img_115
468 | 2002/08/02/big/img_1148
469 | 2002/07/25/big/img_936
470 | 2002/07/31/big/img_639
471 | 2002/08/04/big/img_427
472 | 2002/08/22/big/img_843
473 | 2003/01/17/big/img_17
474 | 2003/01/13/big/img_690
475 | 2002/08/13/big/img_472
476 | 2002/08/09/big/img_425
477 | 2002/08/05/big/img_3450
478 | 2003/01/17/big/img_439
479 | 2002/08/13/big/img_539
480 | 2002/07/28/big/img_35
481 | 2002/08/16/big/img_241
482 | 2002/08/06/big/img_2898
483 | 2003/01/16/big/img_429
484 | 2002/08/05/big/img_3817
485 | 2002/08/27/big/img_19919
486 | 2002/07/19/big/img_422
487 | 2002/08/15/big/img_560
488 | 2002/07/23/big/img_750
489 | 2002/07/30/big/img_353
490 | 2002/08/05/big/img_43
491 | 2002/08/23/big/img_305
492 | 2002/08/01/big/img_2137
493 | 2002/08/30/big/img_18097
494 | 2002/08/01/big/img_1389
495 | 2002/08/02/big/img_308
496 | 2003/01/14/big/img_652
497 | 2002/08/01/big/img_1798
498 | 2003/01/14/big/img_732
499 | 2003/01/16/big/img_294
500 | 2002/08/26/big/img_213
501 | 2002/07/24/big/img_842
502 | 2003/01/13/big/img_630
503 | 2003/01/13/big/img_634
504 | 2002/08/06/big/img_2285
505 | 2002/08/01/big/img_2162
506 | 2002/08/30/big/img_18134
507 | 2002/08/02/big/img_1045
508 | 2002/08/01/big/img_2143
509 | 2002/07/25/big/img_135
510 | 2002/07/20/big/img_645
511 | 2002/08/05/big/img_3666
512 | 2002/08/14/big/img_523
513 | 2002/08/04/big/img_425
514 | 2003/01/14/big/img_137
515 | 2003/01/01/big/img_176
516 | 2002/08/15/big/img_505
517 | 2002/08/24/big/img_386
518 | 2002/08/05/big/img_3187
519 | 2002/08/15/big/img_419
520 | 2003/01/13/big/img_520
521 | 2002/08/04/big/img_444
522 | 2002/08/26/big/img_483
523 | 2002/08/05/big/img_3449
524 | 2002/08/30/big/img_18409
525 | 2002/08/28/big/img_19455
526 | 2002/08/27/big/img_20090
527 | 2002/07/23/big/img_625
528 | 2002/08/24/big/img_205
529 | 2002/08/08/big/img_938
530 | 2003/01/13/big/img_527
531 | 2002/08/07/big/img_1712
532 | 2002/07/24/big/img_801
533 | 2002/08/09/big/img_579
534 | 2003/01/14/big/img_41
535 | 2003/01/15/big/img_1130
536 | 2002/07/21/big/img_672
537 | 2002/08/07/big/img_1590
538 | 2003/01/01/big/img_532
539 | 2002/08/02/big/img_529
540 | 2002/08/05/big/img_3591
541 | 2002/08/23/big/img_5
542 | 2003/01/14/big/img_882
543 | 2002/08/28/big/img_19234
544 | 2002/07/24/big/img_398
545 | 2003/01/14/big/img_592
546 | 2002/08/22/big/img_548
547 | 2002/08/12/big/img_761
548 | 2003/01/16/big/img_497
549 | 2002/08/18/big/img_133
550 | 2002/08/08/big/img_874
551 | 2002/07/19/big/img_247
552 | 2002/08/15/big/img_170
553 | 2002/08/27/big/img_19679
554 | 2002/08/20/big/img_246
555 | 2002/08/24/big/img_358
556 | 2002/07/29/big/img_599
557 | 2002/08/01/big/img_1555
558 | 2002/07/30/big/img_491
559 | 2002/07/30/big/img_371
560 | 2003/01/16/big/img_682
561 | 2002/07/25/big/img_619
562 | 2003/01/15/big/img_587
563 | 2002/08/02/big/img_1212
564 | 2002/08/01/big/img_2152
565 | 2002/07/25/big/img_668
566 | 2003/01/16/big/img_574
567 | 2002/08/28/big/img_19464
568 | 2002/08/11/big/img_536
569 | 2002/07/24/big/img_201
570 | 2002/08/05/big/img_3488
571 | 2002/07/25/big/img_887
572 | 2002/07/22/big/img_789
573 | 2002/07/30/big/img_432
574 | 2002/08/16/big/img_166
575 | 2002/09/01/big/img_16333
576 | 2002/07/26/big/img_1010
577 | 2002/07/21/big/img_793
578 | 2002/07/22/big/img_720
579 | 2002/07/31/big/img_337
580 | 2002/07/27/big/img_185
581 | 2002/08/23/big/img_440
582 | 2002/07/31/big/img_801
583 | 2002/07/25/big/img_478
584 | 2003/01/14/big/img_171
585 | 2002/08/07/big/img_1054
586 | 2002/09/02/big/img_15659
587 | 2002/07/29/big/img_1348
588 | 2002/08/09/big/img_337
589 | 2002/08/26/big/img_684
590 | 2002/07/31/big/img_537
591 | 2002/08/15/big/img_808
592 | 2003/01/13/big/img_740
593 | 2002/08/07/big/img_1667
594 | 2002/08/03/big/img_404
595 | 2002/08/06/big/img_2520
596 | 2002/07/19/big/img_230
597 | 2002/07/19/big/img_356
598 | 2003/01/16/big/img_627
599 | 2002/08/04/big/img_474
600 | 2002/07/29/big/img_833
601 | 2002/07/25/big/img_176
602 | 2002/08/01/big/img_1684
603 | 2002/08/21/big/img_643
604 | 2002/08/27/big/img_19673
605 | 2002/08/02/big/img_838
606 | 2002/08/06/big/img_2378
607 | 2003/01/15/big/img_48
608 | 2002/07/30/big/img_470
609 | 2002/08/15/big/img_963
610 | 2002/08/24/big/img_444
611 | 2002/08/16/big/img_662
612 | 2002/08/15/big/img_1209
613 | 2002/07/24/big/img_25
614 | 2002/08/06/big/img_2740
615 | 2002/07/29/big/img_996
616 | 2002/08/31/big/img_18074
617 | 2002/08/04/big/img_343
618 | 2003/01/17/big/img_509
619 | 2003/01/13/big/img_726
620 | 2002/08/07/big/img_1466
621 | 2002/07/26/big/img_307
622 | 2002/08/10/big/img_598
623 | 2002/08/13/big/img_890
624 | 2002/08/14/big/img_997
625 | 2002/07/19/big/img_392
626 | 2002/08/02/big/img_475
627 | 2002/08/29/big/img_19038
628 | 2002/07/29/big/img_538
629 | 2002/07/29/big/img_502
630 | 2002/08/02/big/img_364
631 | 2002/08/31/big/img_17353
632 | 2002/08/08/big/img_539
633 | 2002/08/01/big/img_1449
634 | 2002/07/22/big/img_363
635 | 2002/08/02/big/img_90
636 | 2002/09/01/big/img_16867
637 | 2002/08/05/big/img_3371
638 | 2002/07/30/big/img_342
639 | 2002/08/07/big/img_1363
640 | 2002/08/22/big/img_790
641 | 2003/01/15/big/img_404
642 | 2002/08/05/big/img_3447
643 | 2002/09/01/big/img_16167
644 | 2003/01/13/big/img_840
645 | 2002/08/22/big/img_1001
646 | 2002/08/09/big/img_431
647 | 2002/07/27/big/img_618
648 | 2002/07/31/big/img_741
649 | 2002/07/30/big/img_964
650 | 2002/07/25/big/img_86
651 | 2002/07/29/big/img_275
652 | 2002/08/21/big/img_921
653 | 2002/07/26/big/img_892
654 | 2002/08/21/big/img_663
655 | 2003/01/13/big/img_567
656 | 2003/01/14/big/img_719
657 | 2002/07/28/big/img_251
658 | 2003/01/15/big/img_1123
659 | 2002/07/29/big/img_260
660 | 2002/08/24/big/img_337
661 | 2002/08/01/big/img_1914
662 | 2002/08/13/big/img_373
663 | 2003/01/15/big/img_589
664 | 2002/08/13/big/img_906
665 | 2002/07/26/big/img_270
666 | 2002/08/26/big/img_313
667 | 2002/08/25/big/img_694
668 | 2003/01/01/big/img_327
669 | 2002/07/23/big/img_261
670 | 2002/08/26/big/img_642
671 | 2002/07/29/big/img_918
672 | 2002/07/23/big/img_455
673 | 2002/07/24/big/img_612
674 | 2002/07/23/big/img_534
675 | 2002/07/19/big/img_534
676 | 2002/07/19/big/img_726
677 | 2002/08/01/big/img_2146
678 | 2002/08/02/big/img_543
679 | 2003/01/16/big/img_777
680 | 2002/07/30/big/img_484
681 | 2002/08/13/big/img_1161
682 | 2002/07/21/big/img_390
683 | 2002/08/06/big/img_2288
684 | 2002/08/21/big/img_677
685 | 2002/08/13/big/img_747
686 | 2002/08/15/big/img_1248
687 | 2002/07/31/big/img_416
688 | 2002/09/02/big/img_15259
689 | 2002/08/16/big/img_781
690 | 2002/08/24/big/img_754
691 | 2002/07/24/big/img_803
692 | 2002/08/20/big/img_609
693 | 2002/08/28/big/img_19571
694 | 2002/09/01/big/img_16140
695 | 2002/08/26/big/img_769
696 | 2002/07/20/big/img_588
697 | 2002/08/02/big/img_898
698 | 2002/07/21/big/img_466
699 | 2002/08/14/big/img_1046
700 | 2002/07/25/big/img_212
701 | 2002/08/26/big/img_353
702 | 2002/08/19/big/img_810
703 | 2002/08/31/big/img_17824
704 | 2002/08/12/big/img_631
705 | 2002/07/19/big/img_828
706 | 2002/07/24/big/img_130
707 | 2002/08/25/big/img_580
708 | 2002/07/31/big/img_699
709 | 2002/07/23/big/img_808
710 | 2002/07/31/big/img_377
711 | 2003/01/16/big/img_570
712 | 2002/09/01/big/img_16254
713 | 2002/07/21/big/img_471
714 | 2002/08/01/big/img_1548
715 | 2002/08/18/big/img_252
716 | 2002/08/19/big/img_576
717 | 2002/08/20/big/img_464
718 | 2002/07/27/big/img_735
719 | 2002/08/21/big/img_589
720 | 2003/01/15/big/img_1192
721 | 2002/08/09/big/img_302
722 | 2002/07/31/big/img_594
723 | 2002/08/23/big/img_19
724 | 2002/08/29/big/img_18819
725 | 2002/08/19/big/img_293
726 | 2002/07/30/big/img_331
727 | 2002/08/23/big/img_607
728 | 2002/07/30/big/img_363
729 | 2002/08/16/big/img_766
730 | 2003/01/13/big/img_481
731 | 2002/08/06/big/img_2515
732 | 2002/09/02/big/img_15913
733 | 2002/09/02/big/img_15827
734 | 2002/09/02/big/img_15053
735 | 2002/08/07/big/img_1576
736 | 2002/07/23/big/img_268
737 | 2002/08/21/big/img_152
738 | 2003/01/15/big/img_578
739 | 2002/07/21/big/img_589
740 | 2002/07/20/big/img_548
741 | 2002/08/27/big/img_19693
742 | 2002/08/31/big/img_17252
743 | 2002/07/31/big/img_138
744 | 2002/07/23/big/img_372
745 | 2002/08/16/big/img_695
746 | 2002/07/27/big/img_287
747 | 2002/08/15/big/img_315
748 | 2002/08/10/big/img_361
749 | 2002/07/29/big/img_899
750 | 2002/08/13/big/img_771
751 | 2002/08/21/big/img_92
752 | 2003/01/15/big/img_425
753 | 2003/01/16/big/img_450
754 | 2002/09/01/big/img_16942
755 | 2002/08/02/big/img_51
756 | 2002/09/02/big/img_15379
757 | 2002/08/24/big/img_147
758 | 2002/08/30/big/img_18122
759 | 2002/07/26/big/img_950
760 | 2002/08/07/big/img_1400
761 | 2002/08/17/big/img_468
762 | 2002/08/15/big/img_470
763 | 2002/07/30/big/img_318
764 | 2002/07/22/big/img_644
765 | 2002/08/27/big/img_19732
766 | 2002/07/23/big/img_601
767 | 2002/08/26/big/img_398
768 | 2002/08/21/big/img_428
769 | 2002/08/06/big/img_2119
770 | 2002/08/29/big/img_19103
771 | 2003/01/14/big/img_933
772 | 2002/08/11/big/img_674
773 | 2002/08/28/big/img_19420
774 | 2002/08/03/big/img_418
775 | 2002/08/17/big/img_312
776 | 2002/07/25/big/img_1044
777 | 2003/01/17/big/img_671
778 | 2002/08/30/big/img_18297
779 | 2002/07/25/big/img_755
780 | 2002/07/23/big/img_471
781 | 2002/08/21/big/img_39
782 | 2002/07/26/big/img_699
783 | 2003/01/14/big/img_33
784 | 2002/07/31/big/img_411
785 | 2002/08/16/big/img_645
786 | 2003/01/17/big/img_116
787 | 2002/09/02/big/img_15903
788 | 2002/08/20/big/img_120
789 | 2002/08/22/big/img_176
790 | 2002/07/29/big/img_1316
791 | 2002/08/27/big/img_19914
792 | 2002/07/22/big/img_719
793 | 2002/08/28/big/img_19239
794 | 2003/01/13/big/img_385
795 | 2002/08/08/big/img_525
796 | 2002/07/19/big/img_782
797 | 2002/08/13/big/img_843
798 | 2002/07/30/big/img_107
799 | 2002/08/11/big/img_752
800 | 2002/07/29/big/img_383
801 | 2002/08/26/big/img_249
802 | 2002/08/29/big/img_18860
803 | 2002/07/30/big/img_70
804 | 2002/07/26/big/img_194
805 | 2002/08/15/big/img_530
806 | 2002/08/08/big/img_816
807 | 2002/07/31/big/img_286
808 | 2003/01/13/big/img_294
809 | 2002/07/31/big/img_251
810 | 2002/07/24/big/img_13
811 | 2002/08/31/big/img_17938
812 | 2002/07/22/big/img_642
813 | 2003/01/14/big/img_728
814 | 2002/08/18/big/img_47
815 | 2002/08/22/big/img_306
816 | 2002/08/20/big/img_348
817 | 2002/08/15/big/img_764
818 | 2002/08/08/big/img_163
819 | 2002/07/23/big/img_531
820 | 2002/07/23/big/img_467
821 | 2003/01/16/big/img_743
822 | 2003/01/13/big/img_535
823 | 2002/08/02/big/img_523
824 | 2002/08/22/big/img_120
825 | 2002/08/11/big/img_496
826 | 2002/08/29/big/img_19075
827 | 2002/08/08/big/img_465
828 | 2002/08/09/big/img_790
829 | 2002/08/19/big/img_588
830 | 2002/08/23/big/img_407
831 | 2003/01/17/big/img_435
832 | 2002/08/24/big/img_398
833 | 2002/08/27/big/img_19899
834 | 2003/01/15/big/img_335
835 | 2002/08/13/big/img_493
836 | 2002/09/02/big/img_15460
837 | 2002/07/31/big/img_470
838 | 2002/08/05/big/img_3550
839 | 2002/07/28/big/img_123
840 | 2002/08/01/big/img_1498
841 | 2002/08/04/big/img_504
842 | 2003/01/17/big/img_427
843 | 2002/08/27/big/img_19708
844 | 2002/07/27/big/img_861
845 | 2002/07/25/big/img_685
846 | 2002/07/31/big/img_207
847 | 2003/01/14/big/img_745
848 | 2002/08/31/big/img_17756
849 | 2002/08/24/big/img_288
850 | 2002/08/18/big/img_181
851 | 2002/08/10/big/img_520
852 | 2002/08/25/big/img_705
853 | 2002/08/23/big/img_226
854 | 2002/08/04/big/img_727
855 | 2002/07/24/big/img_625
856 | 2002/08/28/big/img_19157
857 | 2002/08/23/big/img_586
858 | 2002/07/31/big/img_232
859 | 2003/01/13/big/img_240
860 | 2003/01/14/big/img_321
861 | 2003/01/15/big/img_533
862 | 2002/07/23/big/img_480
863 | 2002/07/24/big/img_371
864 | 2002/08/21/big/img_702
865 | 2002/08/31/big/img_17075
866 | 2002/09/02/big/img_15278
867 | 2002/07/29/big/img_246
868 | 2003/01/15/big/img_829
869 | 2003/01/15/big/img_1213
870 | 2003/01/16/big/img_441
871 | 2002/08/14/big/img_921
872 | 2002/07/23/big/img_425
873 | 2002/08/15/big/img_296
874 | 2002/07/19/big/img_135
875 | 2002/07/26/big/img_402
876 | 2003/01/17/big/img_88
877 | 2002/08/20/big/img_872
878 | 2002/08/13/big/img_1110
879 | 2003/01/16/big/img_1040
880 | 2002/07/23/big/img_9
881 | 2002/08/13/big/img_700
882 | 2002/08/16/big/img_371
883 | 2002/08/27/big/img_19966
884 | 2003/01/17/big/img_391
885 | 2002/08/18/big/img_426
886 | 2002/08/01/big/img_1618
887 | 2002/07/21/big/img_754
888 | 2003/01/14/big/img_1101
889 | 2003/01/16/big/img_1022
890 | 2002/07/22/big/img_275
891 | 2002/08/24/big/img_86
892 | 2002/08/17/big/img_582
893 | 2003/01/15/big/img_765
894 | 2003/01/17/big/img_449
895 | 2002/07/28/big/img_265
896 | 2003/01/13/big/img_552
897 | 2002/07/28/big/img_115
898 | 2003/01/16/big/img_56
899 | 2002/08/02/big/img_1232
900 | 2003/01/17/big/img_925
901 | 2002/07/22/big/img_445
902 | 2002/07/25/big/img_957
903 | 2002/07/20/big/img_589
904 | 2002/08/31/big/img_17107
905 | 2002/07/29/big/img_483
906 | 2002/08/14/big/img_1063
907 | 2002/08/07/big/img_1545
908 | 2002/08/14/big/img_680
909 | 2002/09/01/big/img_16694
910 | 2002/08/14/big/img_257
911 | 2002/08/11/big/img_726
912 | 2002/07/26/big/img_681
913 | 2002/07/25/big/img_481
914 | 2003/01/14/big/img_737
915 | 2002/08/28/big/img_19480
916 | 2003/01/16/big/img_362
917 | 2002/08/27/big/img_19865
918 | 2003/01/01/big/img_547
919 | 2002/09/02/big/img_15074
920 | 2002/08/01/big/img_1453
921 | 2002/08/22/big/img_594
922 | 2002/08/28/big/img_19263
923 | 2002/08/13/big/img_478
924 | 2002/07/29/big/img_1358
925 | 2003/01/14/big/img_1022
926 | 2002/08/16/big/img_450
927 | 2002/08/02/big/img_159
928 | 2002/07/26/big/img_781
929 | 2003/01/13/big/img_601
930 | 2002/08/20/big/img_407
931 | 2002/08/15/big/img_468
932 | 2002/08/31/big/img_17902
933 | 2002/08/16/big/img_81
934 | 2002/07/25/big/img_987
935 | 2002/07/25/big/img_500
936 | 2002/08/02/big/img_31
937 | 2002/08/18/big/img_538
938 | 2002/08/08/big/img_54
939 | 2002/07/23/big/img_686
940 | 2002/07/24/big/img_836
941 | 2003/01/17/big/img_734
942 | 2002/08/16/big/img_1055
943 | 2003/01/16/big/img_521
944 | 2002/07/25/big/img_612
945 | 2002/08/22/big/img_778
946 | 2002/08/03/big/img_251
947 | 2002/08/12/big/img_436
948 | 2002/08/23/big/img_705
949 | 2002/07/28/big/img_243
950 | 2002/07/25/big/img_1029
951 | 2002/08/20/big/img_287
952 | 2002/08/29/big/img_18739
953 | 2002/08/05/big/img_3272
954 | 2002/07/27/big/img_214
955 | 2003/01/14/big/img_5
956 | 2002/08/01/big/img_1380
957 | 2002/08/29/big/img_19097
958 | 2002/07/30/big/img_486
959 | 2002/08/29/big/img_18707
960 | 2002/08/10/big/img_559
961 | 2002/08/15/big/img_365
962 | 2002/08/09/big/img_525
963 | 2002/08/10/big/img_689
964 | 2002/07/25/big/img_502
965 | 2002/08/03/big/img_667
966 | 2002/08/10/big/img_855
967 | 2002/08/10/big/img_706
968 | 2002/08/18/big/img_603
969 | 2003/01/16/big/img_1055
970 | 2002/08/31/big/img_17890
971 | 2002/08/15/big/img_761
972 | 2003/01/15/big/img_489
973 | 2002/08/26/big/img_351
974 | 2002/08/01/big/img_1772
975 | 2002/08/31/big/img_17729
976 | 2002/07/25/big/img_609
977 | 2003/01/13/big/img_539
978 | 2002/07/27/big/img_686
979 | 2002/07/31/big/img_311
980 | 2002/08/22/big/img_799
981 | 2003/01/16/big/img_936
982 | 2002/08/31/big/img_17813
983 | 2002/08/04/big/img_862
984 | 2002/08/09/big/img_332
985 | 2002/07/20/big/img_148
986 | 2002/08/12/big/img_426
987 | 2002/07/24/big/img_69
988 | 2002/07/27/big/img_685
989 | 2002/08/02/big/img_480
990 | 2002/08/26/big/img_154
991 | 2002/07/24/big/img_598
992 | 2002/08/01/big/img_1881
993 | 2002/08/20/big/img_667
994 | 2003/01/14/big/img_495
995 | 2002/07/21/big/img_744
996 | 2002/07/30/big/img_150
997 | 2002/07/23/big/img_924
998 | 2002/08/08/big/img_272
999 | 2002/07/23/big/img_310
1000 | 2002/07/25/big/img_1011
1001 | 2002/09/02/big/img_15725
1002 | 2002/07/19/big/img_814
1003 | 2002/08/20/big/img_936
1004 | 2002/07/25/big/img_85
1005 | 2002/08/24/big/img_662
1006 | 2002/08/09/big/img_495
1007 | 2003/01/15/big/img_196
1008 | 2002/08/16/big/img_707
1009 | 2002/08/28/big/img_19370
1010 | 2002/08/06/big/img_2366
1011 | 2002/08/06/big/img_3012
1012 | 2002/08/01/big/img_1452
1013 | 2002/07/31/big/img_742
1014 | 2002/07/27/big/img_914
1015 | 2003/01/13/big/img_290
1016 | 2002/07/31/big/img_288
1017 | 2002/08/02/big/img_171
1018 | 2002/08/22/big/img_191
1019 | 2002/07/27/big/img_1066
1020 | 2002/08/12/big/img_383
1021 | 2003/01/17/big/img_1018
1022 | 2002/08/01/big/img_1785
1023 | 2002/08/11/big/img_390
1024 | 2002/08/27/big/img_20037
1025 | 2002/08/12/big/img_38
1026 | 2003/01/15/big/img_103
1027 | 2002/08/26/big/img_31
1028 | 2002/08/18/big/img_660
1029 | 2002/07/22/big/img_694
1030 | 2002/08/15/big/img_24
1031 | 2002/07/27/big/img_1077
1032 | 2002/08/01/big/img_1943
1033 | 2002/07/22/big/img_292
1034 | 2002/09/01/big/img_16857
1035 | 2002/07/22/big/img_892
1036 | 2003/01/14/big/img_46
1037 | 2002/08/09/big/img_469
1038 | 2002/08/09/big/img_414
1039 | 2003/01/16/big/img_40
1040 | 2002/08/28/big/img_19231
1041 | 2002/07/27/big/img_978
1042 | 2002/07/23/big/img_475
1043 | 2002/07/25/big/img_92
1044 | 2002/08/09/big/img_799
1045 | 2002/07/25/big/img_491
1046 | 2002/08/03/big/img_654
1047 | 2003/01/15/big/img_687
1048 | 2002/08/11/big/img_478
1049 | 2002/08/07/big/img_1664
1050 | 2002/08/20/big/img_362
1051 | 2002/08/01/big/img_1298
1052 | 2003/01/13/big/img_500
1053 | 2002/08/06/big/img_2896
1054 | 2002/08/30/big/img_18529
1055 | 2002/08/16/big/img_1020
1056 | 2002/07/29/big/img_892
1057 | 2002/08/29/big/img_18726
1058 | 2002/07/21/big/img_453
1059 | 2002/08/17/big/img_437
1060 | 2002/07/19/big/img_665
1061 | 2002/07/22/big/img_440
1062 | 2002/07/19/big/img_582
1063 | 2002/07/21/big/img_233
1064 | 2003/01/01/big/img_82
1065 | 2002/07/25/big/img_341
1066 | 2002/07/29/big/img_864
1067 | 2002/08/02/big/img_276
1068 | 2002/08/29/big/img_18654
1069 | 2002/07/27/big/img_1024
1070 | 2002/08/19/big/img_373
1071 | 2003/01/15/big/img_241
1072 | 2002/07/25/big/img_84
1073 | 2002/08/13/big/img_834
1074 | 2002/08/10/big/img_511
1075 | 2002/08/01/big/img_1627
1076 | 2002/08/08/big/img_607
1077 | 2002/08/06/big/img_2083
1078 | 2002/08/01/big/img_1486
1079 | 2002/08/08/big/img_700
1080 | 2002/08/01/big/img_1954
1081 | 2002/08/21/big/img_54
1082 | 2002/07/30/big/img_847
1083 | 2002/08/28/big/img_19169
1084 | 2002/07/21/big/img_549
1085 | 2002/08/03/big/img_693
1086 | 2002/07/31/big/img_1002
1087 | 2003/01/14/big/img_1035
1088 | 2003/01/16/big/img_622
1089 | 2002/07/30/big/img_1201
1090 | 2002/08/10/big/img_444
1091 | 2002/07/31/big/img_374
1092 | 2002/08/21/big/img_301
1093 | 2002/08/13/big/img_1095
1094 | 2003/01/13/big/img_288
1095 | 2002/07/25/big/img_232
1096 | 2003/01/13/big/img_967
1097 | 2002/08/26/big/img_360
1098 | 2002/08/05/big/img_67
1099 | 2002/08/29/big/img_18969
1100 | 2002/07/28/big/img_16
1101 | 2002/08/16/big/img_515
1102 | 2002/07/20/big/img_708
1103 | 2002/08/18/big/img_178
1104 | 2003/01/15/big/img_509
1105 | 2002/07/25/big/img_430
1106 | 2002/08/21/big/img_738
1107 | 2002/08/16/big/img_886
1108 | 2002/09/02/big/img_15605
1109 | 2002/09/01/big/img_16242
1110 | 2002/08/24/big/img_711
1111 | 2002/07/25/big/img_90
1112 | 2002/08/09/big/img_491
1113 | 2002/07/30/big/img_534
1114 | 2003/01/13/big/img_474
1115 | 2002/08/25/big/img_510
1116 | 2002/08/15/big/img_555
1117 | 2002/08/02/big/img_775
1118 | 2002/07/23/big/img_975
1119 | 2002/08/19/big/img_229
1120 | 2003/01/17/big/img_860
1121 | 2003/01/02/big/img_10
1122 | 2002/07/23/big/img_542
1123 | 2002/08/06/big/img_2535
1124 | 2002/07/22/big/img_37
1125 | 2002/08/06/big/img_2342
1126 | 2002/08/25/big/img_515
1127 | 2002/08/25/big/img_336
1128 | 2002/08/18/big/img_837
1129 | 2002/08/21/big/img_616
1130 | 2003/01/17/big/img_24
1131 | 2002/07/26/big/img_936
1132 | 2002/08/14/big/img_896
1133 | 2002/07/29/big/img_465
1134 | 2002/07/31/big/img_543
1135 | 2002/08/01/big/img_1411
1136 | 2002/08/02/big/img_423
1137 | 2002/08/21/big/img_44
1138 | 2002/07/31/big/img_11
1139 | 2003/01/15/big/img_628
1140 | 2003/01/15/big/img_605
1141 | 2002/07/30/big/img_571
1142 | 2002/07/23/big/img_428
1143 | 2002/08/15/big/img_942
1144 | 2002/07/26/big/img_531
1145 | 2003/01/16/big/img_59
1146 | 2002/08/02/big/img_410
1147 | 2002/07/31/big/img_230
1148 | 2002/08/19/big/img_806
1149 | 2003/01/14/big/img_462
1150 | 2002/08/16/big/img_370
1151 | 2002/08/13/big/img_380
1152 | 2002/08/16/big/img_932
1153 | 2002/07/19/big/img_393
1154 | 2002/08/20/big/img_764
1155 | 2002/08/15/big/img_616
1156 | 2002/07/26/big/img_267
1157 | 2002/07/27/big/img_1069
1158 | 2002/08/14/big/img_1041
1159 | 2003/01/13/big/img_594
1160 | 2002/09/01/big/img_16845
1161 | 2002/08/09/big/img_229
1162 | 2003/01/16/big/img_639
1163 | 2002/08/19/big/img_398
1164 | 2002/08/18/big/img_978
1165 | 2002/08/24/big/img_296
1166 | 2002/07/29/big/img_415
1167 | 2002/07/30/big/img_923
1168 | 2002/08/18/big/img_575
1169 | 2002/08/22/big/img_182
1170 | 2002/07/25/big/img_806
1171 | 2002/07/22/big/img_49
1172 | 2002/07/29/big/img_989
1173 | 2003/01/17/big/img_789
1174 | 2003/01/15/big/img_503
1175 | 2002/09/01/big/img_16062
1176 | 2003/01/17/big/img_794
1177 | 2002/08/15/big/img_564
1178 | 2003/01/15/big/img_222
1179 | 2002/08/01/big/img_1656
1180 | 2003/01/13/big/img_432
1181 | 2002/07/19/big/img_426
1182 | 2002/08/17/big/img_244
1183 | 2002/08/13/big/img_805
1184 | 2002/09/02/big/img_15067
1185 | 2002/08/11/big/img_58
1186 | 2002/08/22/big/img_636
1187 | 2002/07/22/big/img_416
1188 | 2002/08/13/big/img_836
1189 | 2002/08/26/big/img_363
1190 | 2002/07/30/big/img_917
1191 | 2003/01/14/big/img_206
1192 | 2002/08/12/big/img_311
1193 | 2002/08/31/big/img_17623
1194 | 2002/07/29/big/img_661
1195 | 2003/01/13/big/img_417
1196 | 2002/08/02/big/img_463
1197 | 2002/08/02/big/img_669
1198 | 2002/08/26/big/img_670
1199 | 2002/08/02/big/img_375
1200 | 2002/07/19/big/img_209
1201 | 2002/08/08/big/img_115
1202 | 2002/08/21/big/img_399
1203 | 2002/08/20/big/img_911
1204 | 2002/08/07/big/img_1212
1205 | 2002/08/20/big/img_578
1206 | 2002/08/22/big/img_554
1207 | 2002/08/21/big/img_484
1208 | 2002/07/25/big/img_450
1209 | 2002/08/03/big/img_542
1210 | 2002/08/15/big/img_561
1211 | 2002/07/23/big/img_360
1212 | 2002/08/30/big/img_18137
1213 | 2002/07/25/big/img_250
1214 | 2002/08/03/big/img_647
1215 | 2002/08/20/big/img_375
1216 | 2002/08/14/big/img_387
1217 | 2002/09/01/big/img_16990
1218 | 2002/08/28/big/img_19341
1219 | 2003/01/15/big/img_239
1220 | 2002/08/20/big/img_528
1221 | 2002/08/12/big/img_130
1222 | 2002/09/02/big/img_15108
1223 | 2003/01/15/big/img_372
1224 | 2002/08/16/big/img_678
1225 | 2002/08/04/big/img_623
1226 | 2002/07/23/big/img_477
1227 | 2002/08/28/big/img_19590
1228 | 2003/01/17/big/img_978
1229 | 2002/09/01/big/img_16692
1230 | 2002/07/20/big/img_109
1231 | 2002/08/06/big/img_2660
1232 | 2003/01/14/big/img_464
1233 | 2002/08/09/big/img_618
1234 | 2002/07/22/big/img_722
1235 | 2002/08/25/big/img_419
1236 | 2002/08/03/big/img_314
1237 | 2002/08/25/big/img_40
1238 | 2002/07/27/big/img_430
1239 | 2002/08/10/big/img_569
1240 | 2002/08/23/big/img_398
1241 | 2002/07/23/big/img_893
1242 | 2002/08/16/big/img_261
1243 | 2002/08/06/big/img_2668
1244 | 2002/07/22/big/img_835
1245 | 2002/09/02/big/img_15093
1246 | 2003/01/16/big/img_65
1247 | 2002/08/21/big/img_448
1248 | 2003/01/14/big/img_351
1249 | 2003/01/17/big/img_133
1250 | 2002/07/28/big/img_493
1251 | 2003/01/15/big/img_640
1252 | 2002/09/01/big/img_16880
1253 | 2002/08/15/big/img_350
1254 | 2002/08/20/big/img_624
1255 | 2002/08/25/big/img_604
1256 | 2002/08/06/big/img_2200
1257 | 2002/08/23/big/img_290
1258 | 2002/08/13/big/img_1152
1259 | 2003/01/14/big/img_251
1260 | 2002/08/02/big/img_538
1261 | 2002/08/22/big/img_613
1262 | 2003/01/13/big/img_351
1263 | 2002/08/18/big/img_368
1264 | 2002/07/23/big/img_392
1265 | 2002/07/25/big/img_198
1266 | 2002/07/25/big/img_418
1267 | 2002/08/26/big/img_614
1268 | 2002/07/23/big/img_405
1269 | 2003/01/14/big/img_445
1270 | 2002/07/25/big/img_326
1271 | 2002/08/10/big/img_734
1272 | 2003/01/14/big/img_530
1273 | 2002/08/08/big/img_561
1274 | 2002/08/29/big/img_18990
1275 | 2002/08/10/big/img_576
1276 | 2002/07/29/big/img_1494
1277 | 2002/07/19/big/img_198
1278 | 2002/08/10/big/img_562
1279 | 2002/07/22/big/img_901
1280 | 2003/01/14/big/img_37
1281 | 2002/09/02/big/img_15629
1282 | 2003/01/14/big/img_58
1283 | 2002/08/01/big/img_1364
1284 | 2002/07/27/big/img_636
1285 | 2003/01/13/big/img_241
1286 | 2002/09/01/big/img_16988
1287 | 2003/01/13/big/img_560
1288 | 2002/08/09/big/img_533
1289 | 2002/07/31/big/img_249
1290 | 2003/01/17/big/img_1007
1291 | 2002/07/21/big/img_64
1292 | 2003/01/13/big/img_537
1293 | 2003/01/15/big/img_606
1294 | 2002/08/18/big/img_651
1295 | 2002/08/24/big/img_405
1296 | 2002/07/26/big/img_837
1297 | 2002/08/09/big/img_562
1298 | 2002/08/01/big/img_1983
1299 | 2002/08/03/big/img_514
1300 | 2002/07/29/big/img_314
1301 | 2002/08/12/big/img_493
1302 | 2003/01/14/big/img_121
1303 | 2003/01/14/big/img_479
1304 | 2002/08/04/big/img_410
1305 | 2002/07/22/big/img_607
1306 | 2003/01/17/big/img_417
1307 | 2002/07/20/big/img_547
1308 | 2002/08/13/big/img_396
1309 | 2002/08/31/big/img_17538
1310 | 2002/08/13/big/img_187
1311 | 2002/08/12/big/img_328
1312 | 2003/01/14/big/img_569
1313 | 2002/07/27/big/img_1081
1314 | 2002/08/14/big/img_504
1315 | 2002/08/23/big/img_785
1316 | 2002/07/26/big/img_339
1317 | 2002/08/07/big/img_1156
1318 | 2002/08/07/big/img_1456
1319 | 2002/08/23/big/img_378
1320 | 2002/08/27/big/img_19719
1321 | 2002/07/31/big/img_39
1322 | 2002/07/31/big/img_883
1323 | 2003/01/14/big/img_676
1324 | 2002/07/29/big/img_214
1325 | 2002/07/26/big/img_669
1326 | 2002/07/25/big/img_202
1327 | 2002/08/08/big/img_259
1328 | 2003/01/17/big/img_943
1329 | 2003/01/15/big/img_512
1330 | 2002/08/05/big/img_3295
1331 | 2002/08/27/big/img_19685
1332 | 2002/08/08/big/img_277
1333 | 2002/08/30/big/img_18154
1334 | 2002/07/22/big/img_663
1335 | 2002/08/29/big/img_18914
1336 | 2002/07/31/big/img_908
1337 | 2002/08/27/big/img_19926
1338 | 2003/01/13/big/img_791
1339 | 2003/01/15/big/img_827
1340 | 2002/08/18/big/img_878
1341 | 2002/08/14/big/img_670
1342 | 2002/07/20/big/img_182
1343 | 2002/08/15/big/img_291
1344 | 2002/08/06/big/img_2600
1345 | 2002/07/23/big/img_587
1346 | 2002/08/14/big/img_577
1347 | 2003/01/15/big/img_585
1348 | 2002/07/30/big/img_310
1349 | 2002/08/03/big/img_658
1350 | 2002/08/10/big/img_157
1351 | 2002/08/19/big/img_811
1352 | 2002/07/29/big/img_1318
1353 | 2002/08/04/big/img_104
1354 | 2002/07/30/big/img_332
1355 | 2002/07/24/big/img_789
1356 | 2002/07/29/big/img_516
1357 | 2002/07/23/big/img_843
1358 | 2002/08/01/big/img_1528
1359 | 2002/08/13/big/img_798
1360 | 2002/08/07/big/img_1729
1361 | 2002/08/28/big/img_19448
1362 | 2003/01/16/big/img_95
1363 | 2002/08/12/big/img_473
1364 | 2002/07/27/big/img_269
1365 | 2003/01/16/big/img_621
1366 | 2002/07/29/big/img_772
1367 | 2002/07/24/big/img_171
1368 | 2002/07/19/big/img_429
1369 | 2002/08/07/big/img_1933
1370 | 2002/08/27/big/img_19629
1371 | 2002/08/05/big/img_3688
1372 | 2002/08/07/big/img_1691
1373 | 2002/07/23/big/img_600
1374 | 2002/07/29/big/img_666
1375 | 2002/08/25/big/img_566
1376 | 2002/08/06/big/img_2659
1377 | 2002/08/29/big/img_18929
1378 | 2002/08/16/big/img_407
1379 | 2002/08/18/big/img_774
1380 | 2002/08/19/big/img_249
1381 | 2002/08/06/big/img_2427
1382 | 2002/08/29/big/img_18899
1383 | 2002/08/01/big/img_1818
1384 | 2002/07/31/big/img_108
1385 | 2002/07/29/big/img_500
1386 | 2002/08/11/big/img_115
1387 | 2002/07/19/big/img_521
1388 | 2002/08/02/big/img_1163
1389 | 2002/07/22/big/img_62
1390 | 2002/08/13/big/img_466
1391 | 2002/08/21/big/img_956
1392 | 2002/08/23/big/img_602
1393 | 2002/08/20/big/img_858
1394 | 2002/07/25/big/img_690
1395 | 2002/07/19/big/img_130
1396 | 2002/08/04/big/img_874
1397 | 2002/07/26/big/img_489
1398 | 2002/07/22/big/img_548
1399 | 2002/08/10/big/img_191
1400 | 2002/07/25/big/img_1051
1401 | 2002/08/18/big/img_473
1402 | 2002/08/12/big/img_755
1403 | 2002/08/18/big/img_413
1404 | 2002/08/08/big/img_1044
1405 | 2002/08/17/big/img_680
1406 | 2002/08/26/big/img_235
1407 | 2002/08/20/big/img_330
1408 | 2002/08/22/big/img_344
1409 | 2002/08/09/big/img_593
1410 | 2002/07/31/big/img_1006
1411 | 2002/08/14/big/img_337
1412 | 2002/08/16/big/img_728
1413 | 2002/07/24/big/img_834
1414 | 2002/08/04/big/img_552
1415 | 2002/09/02/big/img_15213
1416 | 2002/07/25/big/img_725
1417 | 2002/08/30/big/img_18290
1418 | 2003/01/01/big/img_475
1419 | 2002/07/27/big/img_1083
1420 | 2002/08/29/big/img_18955
1421 | 2002/08/31/big/img_17232
1422 | 2002/08/08/big/img_480
1423 | 2002/08/01/big/img_1311
1424 | 2002/07/30/big/img_745
1425 | 2002/08/03/big/img_649
1426 | 2002/08/12/big/img_193
1427 | 2002/07/29/big/img_228
1428 | 2002/07/25/big/img_836
1429 | 2002/08/20/big/img_400
1430 | 2002/07/30/big/img_507
1431 | 2002/09/02/big/img_15072
1432 | 2002/07/26/big/img_658
1433 | 2002/07/28/big/img_503
1434 | 2002/08/05/big/img_3814
1435 | 2002/08/24/big/img_745
1436 | 2003/01/13/big/img_817
1437 | 2002/08/08/big/img_579
1438 | 2002/07/22/big/img_251
1439 | 2003/01/13/big/img_689
1440 | 2002/07/25/big/img_407
1441 | 2002/08/13/big/img_1050
1442 | 2002/08/14/big/img_733
1443 | 2002/07/24/big/img_82
1444 | 2003/01/17/big/img_288
1445 | 2003/01/15/big/img_475
1446 | 2002/08/14/big/img_620
1447 | 2002/08/21/big/img_167
1448 | 2002/07/19/big/img_300
1449 | 2002/07/26/big/img_219
1450 | 2002/08/01/big/img_1468
1451 | 2002/07/23/big/img_260
1452 | 2002/08/09/big/img_555
1453 | 2002/07/19/big/img_160
1454 | 2002/08/02/big/img_1060
1455 | 2003/01/14/big/img_149
1456 | 2002/08/15/big/img_346
1457 | 2002/08/24/big/img_597
1458 | 2002/08/22/big/img_502
1459 | 2002/08/30/big/img_18228
1460 | 2002/07/21/big/img_766
1461 | 2003/01/15/big/img_841
1462 | 2002/07/24/big/img_516
1463 | 2002/08/02/big/img_265
1464 | 2002/08/15/big/img_1243
1465 | 2003/01/15/big/img_223
1466 | 2002/08/04/big/img_236
1467 | 2002/07/22/big/img_309
1468 | 2002/07/20/big/img_656
1469 | 2002/07/31/big/img_412
1470 | 2002/09/01/big/img_16462
1471 | 2003/01/16/big/img_431
1472 | 2002/07/22/big/img_793
1473 | 2002/08/15/big/img_877
1474 | 2002/07/26/big/img_282
1475 | 2002/07/25/big/img_529
1476 | 2002/08/24/big/img_613
1477 | 2003/01/17/big/img_700
1478 | 2002/08/06/big/img_2526
1479 | 2002/08/24/big/img_394
1480 | 2002/08/21/big/img_521
1481 | 2002/08/25/big/img_560
1482 | 2002/07/29/big/img_966
1483 | 2002/07/25/big/img_448
1484 | 2003/01/13/big/img_782
1485 | 2002/08/21/big/img_296
1486 | 2002/09/01/big/img_16755
1487 | 2002/08/05/big/img_3552
1488 | 2002/09/02/big/img_15823
1489 | 2003/01/14/big/img_193
1490 | 2002/07/21/big/img_159
1491 | 2002/08/02/big/img_564
1492 | 2002/08/16/big/img_300
1493 | 2002/07/19/big/img_269
1494 | 2002/08/13/big/img_676
1495 | 2002/07/28/big/img_57
1496 | 2002/08/05/big/img_3318
1497 | 2002/07/31/big/img_218
1498 | 2002/08/21/big/img_898
1499 | 2002/07/29/big/img_109
1500 | 2002/07/19/big/img_854
1501 | 2002/08/23/big/img_311
1502 | 2002/08/14/big/img_318
1503 | 2002/07/25/big/img_523
1504 | 2002/07/21/big/img_678
1505 | 2003/01/17/big/img_690
1506 | 2002/08/28/big/img_19503
1507 | 2002/08/18/big/img_251
1508 | 2002/08/22/big/img_672
1509 | 2002/08/20/big/img_663
1510 | 2002/08/02/big/img_148
1511 | 2002/09/02/big/img_15580
1512 | 2002/07/25/big/img_778
1513 | 2002/08/14/big/img_565
1514 | 2002/08/12/big/img_374
1515 | 2002/08/13/big/img_1018
1516 | 2002/08/20/big/img_474
1517 | 2002/08/25/big/img_33
1518 | 2002/08/02/big/img_1190
1519 | 2002/08/08/big/img_864
1520 | 2002/08/14/big/img_1071
1521 | 2002/08/30/big/img_18103
1522 | 2002/08/18/big/img_533
1523 | 2003/01/16/big/img_650
1524 | 2002/07/25/big/img_108
1525 | 2002/07/26/big/img_81
1526 | 2002/07/27/big/img_543
1527 | 2002/07/29/big/img_521
1528 | 2003/01/13/big/img_434
1529 | 2002/08/26/big/img_674
1530 | 2002/08/06/big/img_2932
1531 | 2002/08/07/big/img_1262
1532 | 2003/01/15/big/img_201
1533 | 2003/01/16/big/img_673
1534 | 2002/09/02/big/img_15988
1535 | 2002/07/29/big/img_1306
1536 | 2003/01/14/big/img_1072
1537 | 2002/08/30/big/img_18232
1538 | 2002/08/05/big/img_3711
1539 | 2002/07/23/big/img_775
1540 | 2002/08/01/big/img_16
1541 | 2003/01/16/big/img_630
1542 | 2002/08/22/big/img_695
1543 | 2002/08/14/big/img_51
1544 | 2002/08/14/big/img_782
1545 | 2002/08/24/big/img_742
1546 | 2003/01/14/big/img_512
1547 | 2003/01/15/big/img_1183
1548 | 2003/01/15/big/img_714
1549 | 2002/08/01/big/img_2078
1550 | 2002/07/31/big/img_682
1551 | 2002/09/02/big/img_15687
1552 | 2002/07/26/big/img_518
1553 | 2002/08/27/big/img_19676
1554 | 2002/09/02/big/img_15969
1555 | 2002/08/02/big/img_931
1556 | 2002/08/25/big/img_508
1557 | 2002/08/29/big/img_18616
1558 | 2002/07/22/big/img_839
1559 | 2002/07/28/big/img_313
1560 | 2003/01/14/big/img_155
1561 | 2002/08/02/big/img_1105
1562 | 2002/08/09/big/img_53
1563 | 2002/08/16/big/img_469
1564 | 2002/08/15/big/img_502
1565 | 2002/08/20/big/img_575
1566 | 2002/07/25/big/img_138
1567 | 2003/01/16/big/img_579
1568 | 2002/07/19/big/img_352
1569 | 2003/01/14/big/img_762
1570 | 2003/01/01/big/img_588
1571 | 2002/08/02/big/img_981
1572 | 2002/08/21/big/img_447
1573 | 2002/09/01/big/img_16151
1574 | 2003/01/14/big/img_769
1575 | 2002/08/23/big/img_461
1576 | 2002/08/17/big/img_240
1577 | 2002/09/02/big/img_15220
1578 | 2002/07/19/big/img_408
1579 | 2002/09/02/big/img_15496
1580 | 2002/07/29/big/img_758
1581 | 2002/08/28/big/img_19392
1582 | 2002/08/06/big/img_2723
1583 | 2002/08/31/big/img_17752
1584 | 2002/08/23/big/img_469
1585 | 2002/08/13/big/img_515
1586 | 2002/09/02/big/img_15551
1587 | 2002/08/03/big/img_462
1588 | 2002/07/24/big/img_613
1589 | 2002/07/22/big/img_61
1590 | 2002/08/08/big/img_171
1591 | 2002/08/21/big/img_177
1592 | 2003/01/14/big/img_105
1593 | 2002/08/02/big/img_1017
1594 | 2002/08/22/big/img_106
1595 | 2002/07/27/big/img_542
1596 | 2002/07/21/big/img_665
1597 | 2002/07/23/big/img_595
1598 | 2002/08/04/big/img_657
1599 | 2002/08/29/big/img_19002
1600 | 2003/01/15/big/img_550
1601 | 2002/08/14/big/img_662
1602 | 2002/07/20/big/img_425
1603 | 2002/08/30/big/img_18528
1604 | 2002/07/26/big/img_611
1605 | 2002/07/22/big/img_849
1606 | 2002/08/07/big/img_1655
1607 | 2002/08/21/big/img_638
1608 | 2003/01/17/big/img_732
1609 | 2003/01/01/big/img_496
1610 | 2002/08/18/big/img_713
1611 | 2002/08/08/big/img_109
1612 | 2002/07/27/big/img_1008
1613 | 2002/07/20/big/img_559
1614 | 2002/08/16/big/img_699
1615 | 2002/08/31/big/img_17702
1616 | 2002/07/31/big/img_1013
1617 | 2002/08/01/big/img_2027
1618 | 2002/08/02/big/img_1001
1619 | 2002/08/03/big/img_210
1620 | 2002/08/01/big/img_2087
1621 | 2003/01/14/big/img_199
1622 | 2002/07/29/big/img_48
1623 | 2002/07/19/big/img_727
1624 | 2002/08/09/big/img_249
1625 | 2002/08/04/big/img_632
1626 | 2002/08/22/big/img_620
1627 | 2003/01/01/big/img_457
1628 | 2002/08/05/big/img_3223
1629 | 2002/07/27/big/img_240
1630 | 2002/07/25/big/img_797
1631 | 2002/08/13/big/img_430
1632 | 2002/07/25/big/img_615
1633 | 2002/08/12/big/img_28
1634 | 2002/07/30/big/img_220
1635 | 2002/07/24/big/img_89
1636 | 2002/08/21/big/img_357
1637 | 2002/08/09/big/img_590
1638 | 2003/01/13/big/img_525
1639 | 2002/08/17/big/img_818
1640 | 2003/01/02/big/img_7
1641 | 2002/07/26/big/img_636
1642 | 2003/01/13/big/img_1122
1643 | 2002/07/23/big/img_810
1644 | 2002/08/20/big/img_888
1645 | 2002/07/27/big/img_3
1646 | 2002/08/15/big/img_451
1647 | 2002/09/02/big/img_15787
1648 | 2002/07/31/big/img_281
1649 | 2002/08/05/big/img_3274
1650 | 2002/08/07/big/img_1254
1651 | 2002/07/31/big/img_27
1652 | 2002/08/01/big/img_1366
1653 | 2002/07/30/big/img_182
1654 | 2002/08/27/big/img_19690
1655 | 2002/07/29/big/img_68
1656 | 2002/08/23/big/img_754
1657 | 2002/07/30/big/img_540
1658 | 2002/08/27/big/img_20063
1659 | 2002/08/14/big/img_471
1660 | 2002/08/02/big/img_615
1661 | 2002/07/30/big/img_186
1662 | 2002/08/25/big/img_150
1663 | 2002/07/27/big/img_626
1664 | 2002/07/20/big/img_225
1665 | 2003/01/15/big/img_1252
1666 | 2002/07/19/big/img_367
1667 | 2003/01/15/big/img_582
1668 | 2002/08/09/big/img_572
1669 | 2002/08/08/big/img_428
1670 | 2003/01/15/big/img_639
1671 | 2002/08/28/big/img_19245
1672 | 2002/07/24/big/img_321
1673 | 2002/08/02/big/img_662
1674 | 2002/08/08/big/img_1033
1675 | 2003/01/17/big/img_867
1676 | 2002/07/22/big/img_652
1677 | 2003/01/14/big/img_224
1678 | 2002/08/18/big/img_49
1679 | 2002/07/26/big/img_46
1680 | 2002/08/31/big/img_18021
1681 | 2002/07/25/big/img_151
1682 | 2002/08/23/big/img_540
1683 | 2002/08/25/big/img_693
1684 | 2002/07/23/big/img_340
1685 | 2002/07/28/big/img_117
1686 | 2002/09/02/big/img_15768
1687 | 2002/08/26/big/img_562
1688 | 2002/07/24/big/img_480
1689 | 2003/01/15/big/img_341
1690 | 2002/08/10/big/img_783
1691 | 2002/08/20/big/img_132
1692 | 2003/01/14/big/img_370
1693 | 2002/07/20/big/img_720
1694 | 2002/08/03/big/img_144
1695 | 2002/08/20/big/img_538
1696 | 2002/08/01/big/img_1745
1697 | 2002/08/11/big/img_683
1698 | 2002/08/03/big/img_328
1699 | 2002/08/10/big/img_793
1700 | 2002/08/14/big/img_689
1701 | 2002/08/02/big/img_162
1702 | 2003/01/17/big/img_411
1703 | 2002/07/31/big/img_361
1704 | 2002/08/15/big/img_289
1705 | 2002/08/08/big/img_254
1706 | 2002/08/15/big/img_996
1707 | 2002/08/20/big/img_785
1708 | 2002/07/24/big/img_511
1709 | 2002/08/06/big/img_2614
1710 | 2002/08/29/big/img_18733
1711 | 2002/08/17/big/img_78
1712 | 2002/07/30/big/img_378
1713 | 2002/08/31/big/img_17947
1714 | 2002/08/26/big/img_88
1715 | 2002/07/30/big/img_558
1716 | 2002/08/02/big/img_67
1717 | 2003/01/14/big/img_325
1718 | 2002/07/29/big/img_1357
1719 | 2002/07/19/big/img_391
1720 | 2002/07/30/big/img_307
1721 | 2003/01/13/big/img_219
1722 | 2002/07/24/big/img_807
1723 | 2002/08/23/big/img_543
1724 | 2002/08/29/big/img_18620
1725 | 2002/07/22/big/img_769
1726 | 2002/08/26/big/img_503
1727 | 2002/07/30/big/img_78
1728 | 2002/08/14/big/img_1036
1729 | 2002/08/09/big/img_58
1730 | 2002/07/24/big/img_616
1731 | 2002/08/02/big/img_464
1732 | 2002/07/26/big/img_576
1733 | 2002/07/22/big/img_273
1734 | 2003/01/16/big/img_470
1735 | 2002/07/29/big/img_329
1736 | 2002/07/30/big/img_1086
1737 | 2002/07/31/big/img_353
1738 | 2002/09/02/big/img_15275
1739 | 2003/01/17/big/img_555
1740 | 2002/08/26/big/img_212
1741 | 2002/08/01/big/img_1692
1742 | 2003/01/15/big/img_600
1743 | 2002/07/29/big/img_825
1744 | 2002/08/08/big/img_68
1745 | 2002/08/10/big/img_719
1746 | 2002/07/31/big/img_636
1747 | 2002/07/29/big/img_325
1748 | 2002/07/21/big/img_515
1749 | 2002/07/22/big/img_705
1750 | 2003/01/13/big/img_818
1751 | 2002/08/09/big/img_486
1752 | 2002/08/22/big/img_141
1753 | 2002/07/22/big/img_303
1754 | 2002/08/09/big/img_393
1755 | 2002/07/29/big/img_963
1756 | 2002/08/02/big/img_1215
1757 | 2002/08/19/big/img_674
1758 | 2002/08/12/big/img_690
1759 | 2002/08/21/big/img_637
1760 | 2002/08/21/big/img_841
1761 | 2002/08/24/big/img_71
1762 | 2002/07/25/big/img_596
1763 | 2002/07/24/big/img_864
1764 | 2002/08/18/big/img_293
1765 | 2003/01/14/big/img_657
1766 | 2002/08/15/big/img_411
1767 | 2002/08/16/big/img_348
1768 | 2002/08/05/big/img_3157
1769 | 2002/07/20/big/img_663
1770 | 2003/01/13/big/img_654
1771 | 2003/01/16/big/img_433
1772 | 2002/08/30/big/img_18200
1773 | 2002/08/12/big/img_226
1774 | 2003/01/16/big/img_491
1775 | 2002/08/08/big/img_666
1776 | 2002/07/19/big/img_576
1777 | 2003/01/15/big/img_776
1778 | 2003/01/16/big/img_899
1779 | 2002/07/19/big/img_397
1780 | 2002/08/14/big/img_44
1781 | 2003/01/15/big/img_762
1782 | 2002/08/02/big/img_982
1783 | 2002/09/02/big/img_15234
1784 | 2002/08/17/big/img_556
1785 | 2002/08/21/big/img_410
1786 | 2002/08/21/big/img_386
1787 | 2002/07/19/big/img_690
1788 | 2002/08/05/big/img_3052
1789 | 2002/08/14/big/img_219
1790 | 2002/08/16/big/img_273
1791 | 2003/01/15/big/img_752
1792 | 2002/08/08/big/img_184
1793 | 2002/07/31/big/img_743
1794 | 2002/08/23/big/img_338
1795 | 2003/01/14/big/img_1055
1796 | 2002/08/05/big/img_3405
1797 | 2003/01/15/big/img_17
1798 | 2002/08/03/big/img_141
1799 | 2002/08/14/big/img_549
1800 | 2002/07/27/big/img_1034
1801 | 2002/07/31/big/img_932
1802 | 2002/08/30/big/img_18487
1803 | 2002/09/02/big/img_15814
1804 | 2002/08/01/big/img_2086
1805 | 2002/09/01/big/img_16535
1806 | 2002/07/22/big/img_500
1807 | 2003/01/13/big/img_400
1808 | 2002/08/25/big/img_607
1809 | 2002/08/30/big/img_18384
1810 | 2003/01/14/big/img_951
1811 | 2002/08/13/big/img_1150
1812 | 2002/08/08/big/img_1022
1813 | 2002/08/10/big/img_428
1814 | 2002/08/28/big/img_19242
1815 | 2002/08/05/big/img_3098
1816 | 2002/07/23/big/img_400
1817 | 2002/08/26/big/img_365
1818 | 2002/07/20/big/img_318
1819 | 2002/08/13/big/img_740
1820 | 2003/01/16/big/img_37
1821 | 2002/08/26/big/img_274
1822 | 2002/08/02/big/img_205
1823 | 2002/08/21/big/img_695
1824 | 2002/08/06/big/img_2289
1825 | 2002/08/20/big/img_794
1826 | 2002/08/18/big/img_438
1827 | 2002/08/07/big/img_1380
1828 | 2002/08/02/big/img_737
1829 | 2002/08/07/big/img_1651
1830 | 2002/08/15/big/img_1238
1831 | 2002/08/01/big/img_1681
1832 | 2002/08/06/big/img_3017
1833 | 2002/07/23/big/img_706
1834 | 2002/07/31/big/img_392
1835 | 2002/08/09/big/img_539
1836 | 2002/07/29/big/img_835
1837 | 2002/08/26/big/img_723
1838 | 2002/08/28/big/img_19235
1839 | 2003/01/16/big/img_353
1840 | 2002/08/10/big/img_150
1841 | 2002/08/29/big/img_19025
1842 | 2002/08/21/big/img_310
1843 | 2002/08/10/big/img_823
1844 | 2002/07/26/big/img_981
1845 | 2002/08/11/big/img_288
1846 | 2002/08/19/big/img_534
1847 | 2002/08/21/big/img_300
1848 | 2002/07/31/big/img_49
1849 | 2002/07/30/big/img_469
1850 | 2002/08/28/big/img_19197
1851 | 2002/08/25/big/img_205
1852 | 2002/08/10/big/img_390
1853 | 2002/08/23/big/img_291
1854 | 2002/08/26/big/img_230
1855 | 2002/08/18/big/img_76
1856 | 2002/07/23/big/img_409
1857 | 2002/08/14/big/img_1053
1858 | 2003/01/14/big/img_291
1859 | 2002/08/10/big/img_503
1860 | 2002/08/27/big/img_19928
1861 | 2002/08/03/big/img_563
1862 | 2002/08/17/big/img_250
1863 | 2002/08/06/big/img_2381
1864 | 2002/08/17/big/img_948
1865 | 2002/08/06/big/img_2710
1866 | 2002/07/22/big/img_696
1867 | 2002/07/31/big/img_670
1868 | 2002/08/12/big/img_594
1869 | 2002/07/29/big/img_624
1870 | 2003/01/17/big/img_934
1871 | 2002/08/03/big/img_584
1872 | 2002/08/22/big/img_1003
1873 | 2002/08/05/big/img_3396
1874 | 2003/01/13/big/img_570
1875 | 2002/08/02/big/img_219
1876 | 2002/09/02/big/img_15774
1877 | 2002/08/16/big/img_818
1878 | 2002/08/23/big/img_402
1879 | 2003/01/14/big/img_552
1880 | 2002/07/29/big/img_71
1881 | 2002/08/05/big/img_3592
1882 | 2002/08/16/big/img_80
1883 | 2002/07/27/big/img_672
1884 | 2003/01/13/big/img_470
1885 | 2003/01/16/big/img_702
1886 | 2002/09/01/big/img_16130
1887 | 2002/08/08/big/img_240
1888 | 2002/09/01/big/img_16338
1889 | 2002/07/26/big/img_312
1890 | 2003/01/14/big/img_538
1891 | 2002/07/20/big/img_695
1892 | 2002/08/30/big/img_18098
1893 | 2002/08/25/big/img_259
1894 | 2002/08/16/big/img_1042
1895 | 2002/08/09/big/img_837
1896 | 2002/08/31/big/img_17760
1897 | 2002/07/31/big/img_14
1898 | 2002/08/09/big/img_361
1899 | 2003/01/16/big/img_107
1900 | 2002/08/14/big/img_124
1901 | 2002/07/19/big/img_463
1902 | 2003/01/15/big/img_275
1903 | 2002/07/25/big/img_1151
1904 | 2002/07/29/big/img_1501
1905 | 2002/08/27/big/img_19889
1906 | 2002/08/29/big/img_18603
1907 | 2003/01/17/big/img_601
1908 | 2002/08/25/big/img_355
1909 | 2002/08/08/big/img_297
1910 | 2002/08/20/big/img_290
1911 | 2002/07/31/big/img_195
1912 | 2003/01/01/big/img_336
1913 | 2002/08/18/big/img_369
1914 | 2002/07/25/big/img_621
1915 | 2002/08/11/big/img_508
1916 | 2003/01/14/big/img_458
1917 | 2003/01/15/big/img_795
1918 | 2002/08/12/big/img_498
1919 | 2002/08/01/big/img_1734
1920 | 2002/08/02/big/img_246
1921 | 2002/08/16/big/img_565
1922 | 2002/08/11/big/img_475
1923 | 2002/08/22/big/img_408
1924 | 2002/07/28/big/img_78
1925 | 2002/07/21/big/img_81
1926 | 2003/01/14/big/img_697
1927 | 2002/08/14/big/img_661
1928 | 2002/08/15/big/img_507
1929 | 2002/08/19/big/img_55
1930 | 2002/07/22/big/img_152
1931 | 2003/01/14/big/img_470
1932 | 2002/08/03/big/img_379
1933 | 2002/08/22/big/img_506
1934 | 2003/01/16/big/img_966
1935 | 2002/08/18/big/img_698
1936 | 2002/08/24/big/img_528
1937 | 2002/08/23/big/img_10
1938 | 2002/08/01/big/img_1655
1939 | 2002/08/22/big/img_953
1940 | 2002/07/19/big/img_630
1941 | 2002/07/22/big/img_889
1942 | 2002/08/16/big/img_351
1943 | 2003/01/16/big/img_83
1944 | 2002/07/19/big/img_805
1945 | 2002/08/14/big/img_704
1946 | 2002/07/19/big/img_389
1947 | 2002/08/31/big/img_17765
1948 | 2002/07/29/big/img_606
1949 | 2003/01/17/big/img_939
1950 | 2002/09/02/big/img_15081
1951 | 2002/08/21/big/img_181
1952 | 2002/07/29/big/img_1321
1953 | 2002/07/21/big/img_497
1954 | 2002/07/20/big/img_539
1955 | 2002/08/24/big/img_119
1956 | 2002/08/01/big/img_1281
1957 | 2002/07/26/big/img_207
1958 | 2002/07/26/big/img_432
1959 | 2002/07/27/big/img_1006
1960 | 2002/08/05/big/img_3087
1961 | 2002/08/14/big/img_252
1962 | 2002/08/14/big/img_798
1963 | 2002/07/24/big/img_538
1964 | 2002/09/02/big/img_15507
1965 | 2002/08/08/big/img_901
1966 | 2003/01/14/big/img_557
1967 | 2002/08/07/big/img_1819
1968 | 2002/08/04/big/img_470
1969 | 2002/08/01/big/img_1504
1970 | 2002/08/16/big/img_1070
1971 | 2002/08/16/big/img_372
1972 | 2002/08/23/big/img_416
1973 | 2002/08/30/big/img_18208
1974 | 2002/08/01/big/img_2043
1975 | 2002/07/22/big/img_385
1976 | 2002/08/22/big/img_466
1977 | 2002/08/21/big/img_869
1978 | 2002/08/28/big/img_19429
1979 | 2002/08/02/big/img_770
1980 | 2002/07/23/big/img_433
1981 | 2003/01/14/big/img_13
1982 | 2002/07/27/big/img_953
1983 | 2002/09/02/big/img_15728
1984 | 2002/08/01/big/img_1361
1985 | 2002/08/29/big/img_18897
1986 | 2002/08/26/big/img_534
1987 | 2002/08/11/big/img_121
1988 | 2002/08/26/big/img_20130
1989 | 2002/07/31/big/img_363
1990 | 2002/08/13/big/img_978
1991 | 2002/07/25/big/img_835
1992 | 2002/08/02/big/img_906
1993 | 2003/01/14/big/img_548
1994 | 2002/07/30/big/img_80
1995 | 2002/07/26/big/img_982
1996 | 2003/01/16/big/img_99
1997 | 2002/08/19/big/img_362
1998 | 2002/08/24/big/img_376
1999 | 2002/08/07/big/img_1264
2000 | 2002/07/27/big/img_938
2001 | 2003/01/17/big/img_535
2002 | 2002/07/26/big/img_457
2003 | 2002/08/08/big/img_848
2004 | 2003/01/15/big/img_859
2005 | 2003/01/15/big/img_622
2006 | 2002/07/30/big/img_403
2007 | 2002/07/29/big/img_217
2008 | 2002/07/26/big/img_891
2009 | 2002/07/24/big/img_70
2010 | 2002/08/25/big/img_619
2011 | 2002/08/05/big/img_3375
2012 | 2002/08/01/big/img_2160
2013 | 2002/08/06/big/img_2227
2014 | 2003/01/14/big/img_117
2015 | 2002/08/14/big/img_227
2016 | 2002/08/13/big/img_565
2017 | 2002/08/19/big/img_625
2018 | 2002/08/03/big/img_812
2019 | 2002/07/24/big/img_41
2020 | 2002/08/16/big/img_235
2021 | 2002/07/29/big/img_759
2022 | 2002/07/21/big/img_433
2023 | 2002/07/29/big/img_190
2024 | 2003/01/16/big/img_435
2025 | 2003/01/13/big/img_708
2026 | 2002/07/30/big/img_57
2027 | 2002/08/22/big/img_162
2028 | 2003/01/01/big/img_558
2029 | 2003/01/15/big/img_604
2030 | 2002/08/16/big/img_935
2031 | 2002/08/20/big/img_394
2032 | 2002/07/28/big/img_465
2033 | 2002/09/02/big/img_15534
2034 | 2002/08/16/big/img_87
2035 | 2002/07/22/big/img_469
2036 | 2002/08/12/big/img_245
2037 | 2003/01/13/big/img_236
2038 | 2002/08/06/big/img_2736
2039 | 2002/08/03/big/img_348
2040 | 2003/01/14/big/img_218
2041 | 2002/07/26/big/img_232
2042 | 2003/01/15/big/img_244
2043 | 2002/07/25/big/img_1121
2044 | 2002/08/01/big/img_1484
2045 | 2002/07/26/big/img_541
2046 | 2002/08/07/big/img_1244
2047 | 2002/07/31/big/img_3
2048 | 2002/08/30/big/img_18437
2049 | 2002/08/29/big/img_19094
2050 | 2002/08/01/big/img_1355
2051 | 2002/08/19/big/img_338
2052 | 2002/07/19/big/img_255
2053 | 2002/07/21/big/img_76
2054 | 2002/08/25/big/img_199
2055 | 2002/08/12/big/img_740
2056 | 2002/07/30/big/img_852
2057 | 2002/08/15/big/img_599
2058 | 2002/08/23/big/img_254
2059 | 2002/08/19/big/img_125
2060 | 2002/07/24/big/img_2
2061 | 2002/08/04/big/img_145
2062 | 2002/08/05/big/img_3137
2063 | 2002/07/28/big/img_463
2064 | 2003/01/14/big/img_801
2065 | 2002/07/23/big/img_366
2066 | 2002/08/26/big/img_600
2067 | 2002/08/26/big/img_649
2068 | 2002/09/02/big/img_15849
2069 | 2002/07/26/big/img_248
2070 | 2003/01/13/big/img_200
2071 | 2002/08/07/big/img_1794
2072 | 2002/08/31/big/img_17270
2073 | 2002/08/23/big/img_608
2074 | 2003/01/13/big/img_837
2075 | 2002/08/23/big/img_581
2076 | 2002/08/20/big/img_754
2077 | 2002/08/18/big/img_183
2078 | 2002/08/20/big/img_328
2079 | 2002/07/22/big/img_494
2080 | 2002/07/29/big/img_399
2081 | 2002/08/28/big/img_19284
2082 | 2002/08/08/big/img_566
2083 | 2002/07/25/big/img_376
2084 | 2002/07/23/big/img_138
2085 | 2002/07/25/big/img_435
2086 | 2002/08/17/big/img_685
2087 | 2002/07/19/big/img_90
2088 | 2002/07/20/big/img_716
2089 | 2002/08/31/big/img_17458
2090 | 2002/08/26/big/img_461
2091 | 2002/07/25/big/img_355
2092 | 2002/08/06/big/img_2152
2093 | 2002/07/27/big/img_932
2094 | 2002/07/23/big/img_232
2095 | 2002/08/08/big/img_1020
2096 | 2002/07/31/big/img_366
2097 | 2002/08/06/big/img_2667
2098 | 2002/08/21/big/img_465
2099 | 2002/08/15/big/img_305
2100 | 2002/08/02/big/img_247
2101 | 2002/07/28/big/img_46
2102 | 2002/08/27/big/img_19922
2103 | 2002/08/23/big/img_643
2104 | 2003/01/13/big/img_624
2105 | 2002/08/23/big/img_625
2106 | 2002/08/05/big/img_3787
2107 | 2003/01/13/big/img_627
2108 | 2002/09/01/big/img_16381
2109 | 2002/08/05/big/img_3668
2110 | 2002/07/21/big/img_535
2111 | 2002/08/27/big/img_19680
2112 | 2002/07/22/big/img_413
2113 | 2002/07/29/big/img_481
2114 | 2003/01/15/big/img_496
2115 | 2002/07/23/big/img_701
2116 | 2002/08/29/big/img_18670
2117 | 2002/07/28/big/img_319
2118 | 2003/01/14/big/img_517
2119 | 2002/07/26/big/img_256
2120 | 2003/01/16/big/img_593
2121 | 2002/07/30/big/img_956
2122 | 2002/07/30/big/img_667
2123 | 2002/07/25/big/img_100
2124 | 2002/08/11/big/img_570
2125 | 2002/07/26/big/img_745
2126 | 2002/08/04/big/img_834
2127 | 2002/08/25/big/img_521
2128 | 2002/08/01/big/img_2148
2129 | 2002/09/02/big/img_15183
2130 | 2002/08/22/big/img_514
2131 | 2002/08/23/big/img_477
2132 | 2002/07/23/big/img_336
2133 | 2002/07/26/big/img_481
2134 | 2002/08/20/big/img_409
2135 | 2002/07/23/big/img_918
2136 | 2002/08/09/big/img_474
2137 | 2002/08/02/big/img_929
2138 | 2002/08/31/big/img_17932
2139 | 2002/08/19/big/img_161
2140 | 2002/08/09/big/img_667
2141 | 2002/07/31/big/img_805
2142 | 2002/09/02/big/img_15678
2143 | 2002/08/31/big/img_17509
2144 | 2002/08/29/big/img_18998
2145 | 2002/07/23/big/img_301
2146 | 2002/08/07/big/img_1612
2147 | 2002/08/06/big/img_2472
2148 | 2002/07/23/big/img_466
2149 | 2002/08/27/big/img_19634
2150 | 2003/01/16/big/img_16
2151 | 2002/08/14/big/img_193
2152 | 2002/08/21/big/img_340
2153 | 2002/08/27/big/img_19799
2154 | 2002/08/01/big/img_1345
2155 | 2002/08/07/big/img_1448
2156 | 2002/08/11/big/img_324
2157 | 2003/01/16/big/img_754
2158 | 2002/08/13/big/img_418
2159 | 2003/01/16/big/img_544
2160 | 2002/08/19/big/img_135
2161 | 2002/08/10/big/img_455
2162 | 2002/08/10/big/img_693
2163 | 2002/08/31/big/img_17967
2164 | 2002/08/28/big/img_19229
2165 | 2002/08/04/big/img_811
2166 | 2002/09/01/big/img_16225
2167 | 2003/01/16/big/img_428
2168 | 2002/09/02/big/img_15295
2169 | 2002/07/26/big/img_108
2170 | 2002/07/21/big/img_477
2171 | 2002/08/07/big/img_1354
2172 | 2002/08/23/big/img_246
2173 | 2002/08/16/big/img_652
2174 | 2002/07/27/big/img_553
2175 | 2002/07/31/big/img_346
2176 | 2002/08/04/big/img_537
2177 | 2002/08/08/big/img_498
2178 | 2002/08/29/big/img_18956
2179 | 2003/01/13/big/img_922
2180 | 2002/08/31/big/img_17425
2181 | 2002/07/26/big/img_438
2182 | 2002/08/19/big/img_185
2183 | 2003/01/16/big/img_33
2184 | 2002/08/10/big/img_252
2185 | 2002/07/29/big/img_598
2186 | 2002/08/27/big/img_19820
2187 | 2002/08/06/big/img_2664
2188 | 2002/08/20/big/img_705
2189 | 2003/01/14/big/img_816
2190 | 2002/08/03/big/img_552
2191 | 2002/07/25/big/img_561
2192 | 2002/07/25/big/img_934
2193 | 2002/08/01/big/img_1893
2194 | 2003/01/14/big/img_746
2195 | 2003/01/16/big/img_519
2196 | 2002/08/03/big/img_681
2197 | 2002/07/24/big/img_808
2198 | 2002/08/14/big/img_803
2199 | 2002/08/25/big/img_155
2200 | 2002/07/30/big/img_1107
2201 | 2002/08/29/big/img_18882
2202 | 2003/01/15/big/img_598
2203 | 2002/08/19/big/img_122
2204 | 2002/07/30/big/img_428
2205 | 2002/07/24/big/img_684
2206 | 2002/08/22/big/img_192
2207 | 2002/08/22/big/img_543
2208 | 2002/08/07/big/img_1318
2209 | 2002/08/18/big/img_25
2210 | 2002/07/26/big/img_583
2211 | 2002/07/20/big/img_464
2212 | 2002/08/19/big/img_664
2213 | 2002/08/24/big/img_861
2214 | 2002/09/01/big/img_16136
2215 | 2002/08/22/big/img_400
2216 | 2002/08/12/big/img_445
2217 | 2003/01/14/big/img_174
2218 | 2002/08/27/big/img_19677
2219 | 2002/08/31/big/img_17214
2220 | 2002/08/30/big/img_18175
2221 | 2003/01/17/big/img_402
2222 | 2002/08/06/big/img_2396
2223 | 2002/08/18/big/img_448
2224 | 2002/08/21/big/img_165
2225 | 2002/08/31/big/img_17609
2226 | 2003/01/01/big/img_151
2227 | 2002/08/26/big/img_372
2228 | 2002/09/02/big/img_15994
2229 | 2002/07/26/big/img_660
2230 | 2002/09/02/big/img_15197
2231 | 2002/07/29/big/img_258
2232 | 2002/08/30/big/img_18525
2233 | 2003/01/13/big/img_368
2234 | 2002/07/29/big/img_1538
2235 | 2002/07/21/big/img_787
2236 | 2002/08/18/big/img_152
2237 | 2002/08/06/big/img_2379
2238 | 2003/01/17/big/img_864
2239 | 2002/08/27/big/img_19998
2240 | 2002/08/01/big/img_1634
2241 | 2002/07/25/big/img_414
2242 | 2002/08/22/big/img_627
2243 | 2002/08/07/big/img_1669
2244 | 2002/08/16/big/img_1052
2245 | 2002/08/31/big/img_17796
2246 | 2002/08/18/big/img_199
2247 | 2002/09/02/big/img_15147
2248 | 2002/08/09/big/img_460
2249 | 2002/08/14/big/img_581
2250 | 2002/08/30/big/img_18286
2251 | 2002/07/26/big/img_337
2252 | 2002/08/18/big/img_589
2253 | 2003/01/14/big/img_866
2254 | 2002/07/20/big/img_624
2255 | 2002/08/01/big/img_1801
2256 | 2002/07/24/big/img_683
2257 | 2002/08/09/big/img_725
2258 | 2003/01/14/big/img_34
2259 | 2002/07/30/big/img_144
2260 | 2002/07/30/big/img_706
2261 | 2002/08/08/big/img_394
2262 | 2002/08/19/big/img_619
2263 | 2002/08/06/big/img_2703
2264 | 2002/08/29/big/img_19034
2265 | 2002/07/24/big/img_67
2266 | 2002/08/27/big/img_19841
2267 | 2002/08/19/big/img_427
2268 | 2003/01/14/big/img_333
2269 | 2002/09/01/big/img_16406
2270 | 2002/07/19/big/img_882
2271 | 2002/08/17/big/img_238
2272 | 2003/01/14/big/img_739
2273 | 2002/07/22/big/img_151
2274 | 2002/08/21/big/img_743
2275 | 2002/07/25/big/img_1048
2276 | 2002/07/30/big/img_395
2277 | 2003/01/13/big/img_584
2278 | 2002/08/13/big/img_742
2279 | 2002/08/13/big/img_1168
2280 | 2003/01/14/big/img_147
2281 | 2002/07/26/big/img_803
2282 | 2002/08/05/big/img_3298
2283 | 2002/08/07/big/img_1451
2284 | 2002/08/16/big/img_424
2285 | 2002/07/29/big/img_1069
2286 | 2002/09/01/big/img_16735
2287 | 2002/07/21/big/img_637
2288 | 2003/01/14/big/img_585
2289 | 2002/08/02/big/img_358
2290 | 2003/01/13/big/img_358
2291 | 2002/08/14/big/img_198
2292 | 2002/08/17/big/img_935
2293 | 2002/08/04/big/img_42
2294 | 2002/08/30/big/img_18245
2295 | 2002/07/25/big/img_158
2296 | 2002/08/22/big/img_744
2297 | 2002/08/06/big/img_2291
2298 | 2002/08/05/big/img_3044
2299 | 2002/07/30/big/img_272
2300 | 2002/08/23/big/img_641
2301 | 2002/07/24/big/img_797
2302 | 2002/07/30/big/img_392
2303 | 2003/01/14/big/img_447
2304 | 2002/07/31/big/img_898
2305 | 2002/08/06/big/img_2812
2306 | 2002/08/13/big/img_564
2307 | 2002/07/22/big/img_43
2308 | 2002/07/26/big/img_634
2309 | 2002/07/19/big/img_843
2310 | 2002/08/26/big/img_58
2311 | 2002/07/21/big/img_375
2312 | 2002/08/25/big/img_729
2313 | 2002/07/19/big/img_561
2314 | 2003/01/15/big/img_884
2315 | 2002/07/25/big/img_891
2316 | 2002/08/09/big/img_558
2317 | 2002/08/26/big/img_587
2318 | 2002/08/13/big/img_1146
2319 | 2002/09/02/big/img_15153
2320 | 2002/07/26/big/img_316
2321 | 2002/08/01/big/img_1940
2322 | 2002/08/26/big/img_90
2323 | 2003/01/13/big/img_347
2324 | 2002/07/25/big/img_520
2325 | 2002/08/29/big/img_18718
2326 | 2002/08/28/big/img_19219
2327 | 2002/08/13/big/img_375
2328 | 2002/07/20/big/img_719
2329 | 2002/08/31/big/img_17431
2330 | 2002/07/28/big/img_192
2331 | 2002/08/26/big/img_259
2332 | 2002/08/18/big/img_484
2333 | 2002/07/29/big/img_580
2334 | 2002/07/26/big/img_84
2335 | 2002/08/02/big/img_302
2336 | 2002/08/31/big/img_17007
2337 | 2003/01/15/big/img_543
2338 | 2002/09/01/big/img_16488
2339 | 2002/08/22/big/img_798
2340 | 2002/07/30/big/img_383
2341 | 2002/08/04/big/img_668
2342 | 2002/08/13/big/img_156
2343 | 2002/08/07/big/img_1353
2344 | 2002/07/25/big/img_281
2345 | 2003/01/14/big/img_587
2346 | 2003/01/15/big/img_524
2347 | 2002/08/19/big/img_726
2348 | 2002/08/21/big/img_709
2349 | 2002/08/26/big/img_465
2350 | 2002/07/31/big/img_658
2351 | 2002/08/28/big/img_19148
2352 | 2002/07/23/big/img_423
2353 | 2002/08/16/big/img_758
2354 | 2002/08/22/big/img_523
2355 | 2002/08/16/big/img_591
2356 | 2002/08/23/big/img_845
2357 | 2002/07/26/big/img_678
2358 | 2002/08/09/big/img_806
2359 | 2002/08/06/big/img_2369
2360 | 2002/07/29/big/img_457
2361 | 2002/07/19/big/img_278
2362 | 2002/08/30/big/img_18107
2363 | 2002/07/26/big/img_444
2364 | 2002/08/20/big/img_278
2365 | 2002/08/26/big/img_92
2366 | 2002/08/26/big/img_257
2367 | 2002/07/25/big/img_266
2368 | 2002/08/05/big/img_3829
2369 | 2002/07/26/big/img_757
2370 | 2002/07/29/big/img_1536
2371 | 2002/08/09/big/img_472
2372 | 2003/01/17/big/img_480
2373 | 2002/08/28/big/img_19355
2374 | 2002/07/26/big/img_97
2375 | 2002/08/06/big/img_2503
2376 | 2002/07/19/big/img_254
2377 | 2002/08/01/big/img_1470
2378 | 2002/08/21/big/img_42
2379 | 2002/08/20/big/img_217
2380 | 2002/08/06/big/img_2459
2381 | 2002/07/19/big/img_552
2382 | 2002/08/13/big/img_717
2383 | 2002/08/12/big/img_586
2384 | 2002/08/20/big/img_411
2385 | 2003/01/13/big/img_768
2386 | 2002/08/07/big/img_1747
2387 | 2002/08/15/big/img_385
2388 | 2002/08/01/big/img_1648
2389 | 2002/08/15/big/img_311
2390 | 2002/08/21/big/img_95
2391 | 2002/08/09/big/img_108
2392 | 2002/08/21/big/img_398
2393 | 2002/08/17/big/img_340
2394 | 2002/08/14/big/img_474
2395 | 2002/08/13/big/img_294
2396 | 2002/08/24/big/img_840
2397 | 2002/08/09/big/img_808
2398 | 2002/08/23/big/img_491
2399 | 2002/07/28/big/img_33
2400 | 2003/01/13/big/img_664
2401 | 2002/08/02/big/img_261
2402 | 2002/08/09/big/img_591
2403 | 2002/07/26/big/img_309
2404 | 2003/01/14/big/img_372
2405 | 2002/08/19/big/img_581
2406 | 2002/08/19/big/img_168
2407 | 2002/08/26/big/img_422
2408 | 2002/07/24/big/img_106
2409 | 2002/08/01/big/img_1936
2410 | 2002/08/05/big/img_3764
2411 | 2002/08/21/big/img_266
2412 | 2002/08/31/big/img_17968
2413 | 2002/08/01/big/img_1941
2414 | 2002/08/15/big/img_550
2415 | 2002/08/14/big/img_13
2416 | 2002/07/30/big/img_171
2417 | 2003/01/13/big/img_490
2418 | 2002/07/25/big/img_427
2419 | 2002/07/19/big/img_770
2420 | 2002/08/12/big/img_759
2421 | 2003/01/15/big/img_1360
2422 | 2002/08/05/big/img_3692
2423 | 2003/01/16/big/img_30
2424 | 2002/07/25/big/img_1026
2425 | 2002/07/22/big/img_288
2426 | 2002/08/29/big/img_18801
2427 | 2002/07/24/big/img_793
2428 | 2002/08/13/big/img_178
2429 | 2002/08/06/big/img_2322
2430 | 2003/01/14/big/img_560
2431 | 2002/08/18/big/img_408
2432 | 2003/01/16/big/img_915
2433 | 2003/01/16/big/img_679
2434 | 2002/08/07/big/img_1552
2435 | 2002/08/29/big/img_19050
2436 | 2002/08/01/big/img_2172
2437 | 2002/07/31/big/img_30
2438 | 2002/07/30/big/img_1019
2439 | 2002/07/30/big/img_587
2440 | 2003/01/13/big/img_773
2441 | 2002/07/30/big/img_410
2442 | 2002/07/28/big/img_65
2443 | 2002/08/05/big/img_3138
2444 | 2002/07/23/big/img_541
2445 | 2002/08/22/big/img_963
2446 | 2002/07/27/big/img_657
2447 | 2002/07/30/big/img_1051
2448 | 2003/01/16/big/img_150
2449 | 2002/07/31/big/img_519
2450 | 2002/08/01/big/img_1961
2451 | 2002/08/05/big/img_3752
2452 | 2002/07/23/big/img_631
2453 | 2003/01/14/big/img_237
2454 | 2002/07/28/big/img_21
2455 | 2002/07/22/big/img_813
2456 | 2002/08/05/big/img_3563
2457 | 2003/01/17/big/img_620
2458 | 2002/07/19/big/img_523
2459 | 2002/07/30/big/img_904
2460 | 2002/08/29/big/img_18642
2461 | 2002/08/11/big/img_492
2462 | 2002/08/01/big/img_2130
2463 | 2002/07/25/big/img_618
2464 | 2002/08/17/big/img_305
2465 | 2003/01/16/big/img_520
2466 | 2002/07/26/big/img_495
2467 | 2002/08/17/big/img_164
2468 | 2002/08/03/big/img_440
2469 | 2002/07/24/big/img_441
2470 | 2002/08/06/big/img_2146
2471 | 2002/08/11/big/img_558
2472 | 2002/08/02/big/img_545
2473 | 2002/08/31/big/img_18090
2474 | 2003/01/01/big/img_136
2475 | 2002/07/25/big/img_1099
2476 | 2003/01/13/big/img_728
2477 | 2003/01/16/big/img_197
2478 | 2002/07/26/big/img_651
2479 | 2002/08/11/big/img_676
2480 | 2003/01/15/big/img_10
2481 | 2002/08/21/big/img_250
2482 | 2002/08/14/big/img_325
2483 | 2002/08/04/big/img_390
2484 | 2002/07/24/big/img_554
2485 | 2003/01/16/big/img_333
2486 | 2002/07/31/big/img_922
2487 | 2002/09/02/big/img_15586
2488 | 2003/01/16/big/img_184
2489 | 2002/07/22/big/img_766
2490 | 2002/07/21/big/img_608
2491 | 2002/08/07/big/img_1578
2492 | 2002/08/17/big/img_961
2493 | 2002/07/27/big/img_324
2494 | 2002/08/05/big/img_3765
2495 | 2002/08/23/big/img_462
2496 | 2003/01/16/big/img_382
2497 | 2002/08/27/big/img_19838
2498 | 2002/08/01/big/img_1505
2499 | 2002/08/21/big/img_662
2500 | 2002/08/14/big/img_605
2501 | 2002/08/19/big/img_816
2502 | 2002/07/29/big/img_136
2503 | 2002/08/20/big/img_719
2504 | 2002/08/06/big/img_2826
2505 | 2002/08/10/big/img_630
2506 | 2003/01/17/big/img_973
2507 | 2002/08/14/big/img_116
2508 | 2002/08/02/big/img_666
2509 | 2002/08/21/big/img_710
2510 | 2002/08/05/big/img_55
2511 | 2002/07/31/big/img_229
2512 | 2002/08/01/big/img_1549
2513 | 2002/07/23/big/img_432
2514 | 2002/07/21/big/img_430
2515 | 2002/08/21/big/img_549
2516 | 2002/08/08/big/img_985
2517 | 2002/07/20/big/img_610
2518 | 2002/07/23/big/img_978
2519 | 2002/08/23/big/img_219
2520 | 2002/07/25/big/img_175
2521 | 2003/01/15/big/img_230
2522 | 2002/08/23/big/img_385
2523 | 2002/07/31/big/img_879
2524 | 2002/08/12/big/img_495
2525 | 2002/08/22/big/img_499
2526 | 2002/08/30/big/img_18322
2527 | 2002/08/15/big/img_795
2528 | 2002/08/13/big/img_835
2529 | 2003/01/17/big/img_930
2530 | 2002/07/30/big/img_873
2531 | 2002/08/11/big/img_257
2532 | 2002/07/31/big/img_593
2533 | 2002/08/21/big/img_916
2534 | 2003/01/13/big/img_814
2535 | 2002/07/25/big/img_722
2536 | 2002/08/16/big/img_379
2537 | 2002/07/31/big/img_497
2538 | 2002/07/22/big/img_602
2539 | 2002/08/21/big/img_642
2540 | 2002/08/21/big/img_614
2541 | 2002/08/23/big/img_482
2542 | 2002/07/29/big/img_603
2543 | 2002/08/13/big/img_705
2544 | 2002/07/23/big/img_833
2545 | 2003/01/14/big/img_511
2546 | 2002/07/24/big/img_376
2547 | 2002/08/17/big/img_1030
2548 | 2002/08/05/big/img_3576
2549 | 2002/08/16/big/img_540
2550 | 2002/07/22/big/img_630
2551 | 2002/08/10/big/img_180
2552 | 2002/08/14/big/img_905
2553 | 2002/08/29/big/img_18777
2554 | 2002/08/22/big/img_693
2555 | 2003/01/16/big/img_933
2556 | 2002/08/20/big/img_555
2557 | 2002/08/15/big/img_549
2558 | 2003/01/14/big/img_830
2559 | 2003/01/16/big/img_64
2560 | 2002/08/27/big/img_19670
2561 | 2002/08/22/big/img_729
2562 | 2002/07/27/big/img_981
2563 | 2002/08/09/big/img_458
2564 | 2003/01/17/big/img_884
2565 | 2002/07/25/big/img_639
2566 | 2002/08/31/big/img_18008
2567 | 2002/08/22/big/img_249
2568 | 2002/08/17/big/img_971
2569 | 2002/08/04/big/img_308
2570 | 2002/07/28/big/img_362
2571 | 2002/08/12/big/img_142
2572 | 2002/08/26/big/img_61
2573 | 2002/08/14/big/img_422
2574 | 2002/07/19/big/img_607
2575 | 2003/01/15/big/img_717
2576 | 2002/08/01/big/img_1475
2577 | 2002/08/29/big/img_19061
2578 | 2003/01/01/big/img_346
2579 | 2002/07/20/big/img_315
2580 | 2003/01/15/big/img_756
2581 | 2002/08/15/big/img_879
2582 | 2002/08/08/big/img_615
2583 | 2003/01/13/big/img_431
2584 | 2002/08/05/big/img_3233
2585 | 2002/08/24/big/img_526
2586 | 2003/01/13/big/img_717
2587 | 2002/09/01/big/img_16408
2588 | 2002/07/22/big/img_217
2589 | 2002/07/31/big/img_960
2590 | 2002/08/21/big/img_610
2591 | 2002/08/05/big/img_3753
2592 | 2002/08/03/big/img_151
2593 | 2002/08/21/big/img_267
2594 | 2002/08/01/big/img_2175
2595 | 2002/08/04/big/img_556
2596 | 2002/08/21/big/img_527
2597 | 2002/09/02/big/img_15800
2598 | 2002/07/27/big/img_156
2599 | 2002/07/20/big/img_590
2600 | 2002/08/15/big/img_700
2601 | 2002/08/08/big/img_444
2602 | 2002/07/25/big/img_94
2603 | 2002/07/24/big/img_778
2604 | 2002/08/14/big/img_694
2605 | 2002/07/20/big/img_666
2606 | 2002/08/02/big/img_200
2607 | 2002/08/02/big/img_578
2608 | 2003/01/17/big/img_332
2609 | 2002/09/01/big/img_16352
2610 | 2002/08/27/big/img_19668
2611 | 2002/07/23/big/img_823
2612 | 2002/08/13/big/img_431
2613 | 2003/01/16/big/img_463
2614 | 2002/08/27/big/img_19711
2615 | 2002/08/23/big/img_154
2616 | 2002/07/31/big/img_360
2617 | 2002/08/23/big/img_555
2618 | 2002/08/10/big/img_561
2619 | 2003/01/14/big/img_550
2620 | 2002/08/07/big/img_1370
2621 | 2002/07/30/big/img_1184
2622 | 2002/08/01/big/img_1445
2623 | 2002/08/23/big/img_22
2624 | 2002/07/30/big/img_606
2625 | 2003/01/17/big/img_271
2626 | 2002/08/31/big/img_17316
2627 | 2002/08/16/big/img_973
2628 | 2002/07/26/big/img_77
2629 | 2002/07/20/big/img_788
2630 | 2002/08/06/big/img_2426
2631 | 2002/08/07/big/img_1498
2632 | 2002/08/16/big/img_358
2633 | 2002/08/06/big/img_2851
2634 | 2002/08/12/big/img_359
2635 | 2002/08/01/big/img_1521
2636 | 2002/08/02/big/img_709
2637 | 2002/08/20/big/img_935
2638 | 2002/08/12/big/img_188
2639 | 2002/08/24/big/img_411
2640 | 2002/08/22/big/img_680
2641 | 2002/08/06/big/img_2480
2642 | 2002/07/20/big/img_627
2643 | 2002/07/30/big/img_214
2644 | 2002/07/25/big/img_354
2645 | 2002/08/02/big/img_636
2646 | 2003/01/15/big/img_661
2647 | 2002/08/07/big/img_1327
2648 | 2002/08/01/big/img_2108
2649 | 2002/08/31/big/img_17919
2650 | 2002/08/29/big/img_18768
2651 | 2002/08/05/big/img_3840
2652 | 2002/07/26/big/img_242
2653 | 2003/01/14/big/img_451
2654 | 2002/08/20/big/img_923
2655 | 2002/08/27/big/img_19908
2656 | 2002/08/16/big/img_282
2657 | 2002/08/19/big/img_440
2658 | 2003/01/01/big/img_230
2659 | 2002/08/08/big/img_212
2660 | 2002/07/20/big/img_443
2661 | 2002/08/25/big/img_635
2662 | 2003/01/13/big/img_1169
2663 | 2002/07/26/big/img_998
2664 | 2002/08/15/big/img_995
2665 | 2002/08/06/big/img_3002
2666 | 2002/07/29/big/img_460
2667 | 2003/01/14/big/img_925
2668 | 2002/07/23/big/img_539
2669 | 2002/08/16/big/img_694
2670 | 2003/01/13/big/img_459
2671 | 2002/07/23/big/img_249
2672 | 2002/08/20/big/img_539
2673 | 2002/08/04/big/img_186
2674 | 2002/08/26/big/img_264
2675 | 2002/07/22/big/img_704
2676 | 2002/08/25/big/img_277
2677 | 2002/08/22/big/img_988
2678 | 2002/07/29/big/img_504
2679 | 2002/08/05/big/img_3600
2680 | 2002/08/30/big/img_18380
2681 | 2003/01/14/big/img_937
2682 | 2002/08/21/big/img_254
2683 | 2002/08/10/big/img_130
2684 | 2002/08/20/big/img_339
2685 | 2003/01/14/big/img_428
2686 | 2002/08/20/big/img_889
2687 | 2002/08/31/big/img_17637
2688 | 2002/07/26/big/img_644
2689 | 2002/09/01/big/img_16776
2690 | 2002/08/06/big/img_2239
2691 | 2002/08/06/big/img_2646
2692 | 2003/01/13/big/img_491
2693 | 2002/08/10/big/img_579
2694 | 2002/08/21/big/img_713
2695 | 2002/08/22/big/img_482
2696 | 2002/07/22/big/img_167
2697 | 2002/07/24/big/img_539
2698 | 2002/08/14/big/img_721
2699 | 2002/07/25/big/img_389
2700 | 2002/09/01/big/img_16591
2701 | 2002/08/13/big/img_543
2702 | 2003/01/14/big/img_432
2703 | 2002/08/09/big/img_287
2704 | 2002/07/26/big/img_126
2705 | 2002/08/23/big/img_412
2706 | 2002/08/15/big/img_1034
2707 | 2002/08/28/big/img_19485
2708 | 2002/07/31/big/img_236
2709 | 2002/07/30/big/img_523
2710 | 2002/07/19/big/img_141
2711 | 2003/01/17/big/img_957
2712 | 2002/08/04/big/img_81
2713 | 2002/07/25/big/img_206
2714 | 2002/08/15/big/img_716
2715 | 2002/08/13/big/img_403
2716 | 2002/08/15/big/img_685
2717 | 2002/07/26/big/img_884
2718 | 2002/07/19/big/img_499
2719 | 2002/07/23/big/img_772
2720 | 2002/07/27/big/img_752
2721 | 2003/01/14/big/img_493
2722 | 2002/08/25/big/img_664
2723 | 2002/07/31/big/img_334
2724 | 2002/08/26/big/img_678
2725 | 2002/09/01/big/img_16541
2726 | 2003/01/14/big/img_347
2727 | 2002/07/23/big/img_187
2728 | 2002/07/30/big/img_1163
2729 | 2002/08/05/big/img_35
2730 | 2002/08/22/big/img_944
2731 | 2002/08/07/big/img_1239
2732 | 2002/07/29/big/img_1215
2733 | 2002/08/03/big/img_312
2734 | 2002/08/05/big/img_3523
2735 | 2002/07/29/big/img_218
2736 | 2002/08/13/big/img_672
2737 | 2002/08/16/big/img_205
2738 | 2002/08/17/big/img_594
2739 | 2002/07/29/big/img_1411
2740 | 2002/07/30/big/img_942
2741 | 2003/01/16/big/img_312
2742 | 2002/08/08/big/img_312
2743 | 2002/07/25/big/img_15
2744 | 2002/08/09/big/img_839
2745 | 2002/08/01/big/img_2069
2746 | 2002/08/31/big/img_17512
2747 | 2002/08/01/big/img_3
2748 | 2002/07/31/big/img_320
2749 | 2003/01/15/big/img_1265
2750 | 2002/08/14/big/img_563
2751 | 2002/07/31/big/img_167
2752 | 2002/08/20/big/img_374
2753 | 2002/08/13/big/img_406
2754 | 2002/08/08/big/img_625
2755 | 2002/08/02/big/img_314
2756 | 2002/08/27/big/img_19964
2757 | 2002/09/01/big/img_16670
2758 | 2002/07/31/big/img_599
2759 | 2002/08/29/big/img_18906
2760 | 2002/07/24/big/img_373
2761 | 2002/07/26/big/img_513
2762 | 2002/09/02/big/img_15497
2763 | 2002/08/19/big/img_117
2764 | 2003/01/01/big/img_158
2765 | 2002/08/24/big/img_178
2766 | 2003/01/13/big/img_935
2767 | 2002/08/13/big/img_609
2768 | 2002/08/30/big/img_18341
2769 | 2002/08/25/big/img_674
2770 | 2003/01/13/big/img_209
2771 | 2002/08/13/big/img_258
2772 | 2002/08/05/big/img_3543
2773 | 2002/08/07/big/img_1970
2774 | 2002/08/06/big/img_3004
2775 | 2003/01/17/big/img_487
2776 | 2002/08/24/big/img_873
2777 | 2002/08/29/big/img_18730
2778 | 2002/08/09/big/img_375
2779 | 2003/01/16/big/img_751
2780 | 2002/08/02/big/img_603
2781 | 2002/08/19/big/img_325
2782 | 2002/09/01/big/img_16420
2783 | 2002/08/05/big/img_3633
2784 | 2002/08/21/big/img_516
2785 | 2002/07/19/big/img_501
2786 | 2002/07/26/big/img_688
2787 | 2002/07/24/big/img_256
2788 | 2002/07/25/big/img_438
2789 | 2002/07/31/big/img_1017
2790 | 2002/08/22/big/img_512
2791 | 2002/07/21/big/img_543
2792 | 2002/08/08/big/img_223
2793 | 2002/08/19/big/img_189
2794 | 2002/08/12/big/img_630
2795 | 2002/07/30/big/img_958
2796 | 2002/07/28/big/img_208
2797 | 2002/08/31/big/img_17691
2798 | 2002/07/22/big/img_542
2799 | 2002/07/19/big/img_741
2800 | 2002/07/19/big/img_158
2801 | 2002/08/15/big/img_399
2802 | 2002/08/01/big/img_2159
2803 | 2002/08/14/big/img_455
2804 | 2002/08/17/big/img_1011
2805 | 2002/08/26/big/img_744
2806 | 2002/08/12/big/img_624
2807 | 2003/01/17/big/img_821
2808 | 2002/08/16/big/img_980
2809 | 2002/07/28/big/img_281
2810 | 2002/07/25/big/img_171
2811 | 2002/08/03/big/img_116
2812 | 2002/07/22/big/img_467
2813 | 2002/07/31/big/img_750
2814 | 2002/07/26/big/img_435
2815 | 2002/07/19/big/img_822
2816 | 2002/08/13/big/img_626
2817 | 2002/08/11/big/img_344
2818 | 2002/08/02/big/img_473
2819 | 2002/09/01/big/img_16817
2820 | 2002/08/01/big/img_1275
2821 | 2002/08/28/big/img_19270
2822 | 2002/07/23/big/img_607
2823 | 2002/08/09/big/img_316
2824 | 2002/07/29/big/img_626
2825 | 2002/07/24/big/img_824
2826 | 2002/07/22/big/img_342
2827 | 2002/08/08/big/img_794
2828 | 2002/08/07/big/img_1209
2829 | 2002/07/19/big/img_18
2830 | 2002/08/25/big/img_634
2831 | 2002/07/24/big/img_730
2832 | 2003/01/17/big/img_356
2833 | 2002/07/23/big/img_305
2834 | 2002/07/30/big/img_453
2835 | 2003/01/13/big/img_972
2836 | 2002/08/06/big/img_2610
2837 | 2002/08/29/big/img_18920
2838 | 2002/07/31/big/img_123
2839 | 2002/07/26/big/img_979
2840 | 2002/08/24/big/img_635
2841 | 2002/08/05/big/img_3704
2842 | 2002/08/07/big/img_1358
2843 | 2002/07/22/big/img_306
2844 | 2002/08/13/big/img_619
2845 | 2002/08/02/big/img_366
2846 |
--------------------------------------------------------------------------------
/retinaface/data/__init__.py:
--------------------------------------------------------------------------------
1 | from .wider_face import WiderFaceDetection, detection_collate
2 | from .data_augment import *
3 | from .config import *
4 |
--------------------------------------------------------------------------------
/retinaface/data/config.py:
--------------------------------------------------------------------------------
1 | # config.py
2 |
3 | cfg_mnet = {
4 | 'name': 'mobilenet0.25',
5 | 'min_sizes': [[16, 32], [64, 128], [256, 512]],
6 | 'steps': [8, 16, 32],
7 | 'variance': [0.1, 0.2],
8 | 'clip': False,
9 | 'loc_weight': 2.0,
10 | 'gpu_train': True,
11 | 'batch_size': 32,
12 | 'ngpu': 1,
13 | 'epoch': 250,
14 | 'decay1': 190,
15 | 'decay2': 220,
16 | 'image_size': 640,
17 | 'pretrain': True,
18 | 'return_layers': {'stage1': 1, 'stage2': 2, 'stage3': 3},
19 | 'in_channel': 32,
20 | 'out_channel': 64
21 | }
22 |
23 | cfg_re50 = {
24 | 'name': 'Resnet50',
25 | 'min_sizes': [[16, 32], [64, 128], [256, 512]],
26 | 'steps': [8, 16, 32],
27 | 'variance': [0.1, 0.2],
28 | 'clip': False,
29 | 'loc_weight': 2.0,
30 | 'gpu_train': True,
31 | 'batch_size': 24,
32 | 'ngpu': 4,
33 | 'epoch': 100,
34 | 'decay1': 70,
35 | 'decay2': 90,
36 | 'image_size': 840,
37 | 'pretrain': True,
38 | 'return_layers': {'layer2': 1, 'layer3': 2, 'layer4': 3},
39 | 'in_channel': 256,
40 | 'out_channel': 256
41 | }
42 |
43 |
--------------------------------------------------------------------------------
/retinaface/data/data_augment.py:
--------------------------------------------------------------------------------
1 | import cv2
2 | import numpy as np
3 | import random
4 | from retinaface.utils.box_utils import matrix_iof
5 |
6 |
7 | def _crop(image, boxes, labels, landm, img_dim):
8 | height, width, _ = image.shape
9 | pad_image_flag = True
10 |
11 | for _ in range(250):
12 | """
13 | if random.uniform(0, 1) <= 0.2:
14 | scale = 1.0
15 | else:
16 | scale = random.uniform(0.3, 1.0)
17 | """
18 | PRE_SCALES = [0.3, 0.45, 0.6, 0.8, 1.0]
19 | scale = random.choice(PRE_SCALES)
20 | short_side = min(width, height)
21 | w = int(scale * short_side)
22 | h = w
23 |
24 | if width == w:
25 | l = 0
26 | else:
27 | l = random.randrange(width - w)
28 | if height == h:
29 | t = 0
30 | else:
31 | t = random.randrange(height - h)
32 | roi = np.array((l, t, l + w, t + h))
33 |
34 | value = matrix_iof(boxes, roi[np.newaxis])
35 | flag = (value >= 1)
36 | if not flag.any():
37 | continue
38 |
39 | centers = (boxes[:, :2] + boxes[:, 2:]) / 2
40 | mask_a = np.logical_and(roi[:2] < centers, centers < roi[2:]).all(axis=1)
41 | boxes_t = boxes[mask_a].copy()
42 | labels_t = labels[mask_a].copy()
43 | landms_t = landm[mask_a].copy()
44 | landms_t = landms_t.reshape([-1, 5, 2])
45 |
46 | if boxes_t.shape[0] == 0:
47 | continue
48 |
49 | image_t = image[roi[1]:roi[3], roi[0]:roi[2]]
50 |
51 | boxes_t[:, :2] = np.maximum(boxes_t[:, :2], roi[:2])
52 | boxes_t[:, :2] -= roi[:2]
53 | boxes_t[:, 2:] = np.minimum(boxes_t[:, 2:], roi[2:])
54 | boxes_t[:, 2:] -= roi[:2]
55 |
56 | # landm
57 | landms_t[:, :, :2] = landms_t[:, :, :2] - roi[:2]
58 | landms_t[:, :, :2] = np.maximum(landms_t[:, :, :2], np.array([0, 0]))
59 | landms_t[:, :, :2] = np.minimum(landms_t[:, :, :2], roi[2:] - roi[:2])
60 | landms_t = landms_t.reshape([-1, 10])
61 |
62 |
63 | # make sure that the cropped image contains at least one face > 16 pixel at training image scale
64 | b_w_t = (boxes_t[:, 2] - boxes_t[:, 0] + 1) / w * img_dim
65 | b_h_t = (boxes_t[:, 3] - boxes_t[:, 1] + 1) / h * img_dim
66 | mask_b = np.minimum(b_w_t, b_h_t) > 0.0
67 | boxes_t = boxes_t[mask_b]
68 | labels_t = labels_t[mask_b]
69 | landms_t = landms_t[mask_b]
70 |
71 | if boxes_t.shape[0] == 0:
72 | continue
73 |
74 | pad_image_flag = False
75 |
76 | return image_t, boxes_t, labels_t, landms_t, pad_image_flag
77 | return image, boxes, labels, landm, pad_image_flag
78 |
79 |
80 | def _distort(image):
81 |
82 | def _convert(image, alpha=1, beta=0):
83 | tmp = image.astype(float) * alpha + beta
84 | tmp[tmp < 0] = 0
85 | tmp[tmp > 255] = 255
86 | image[:] = tmp
87 |
88 | image = image.copy()
89 |
90 | if random.randrange(2):
91 |
92 | #brightness distortion
93 | if random.randrange(2):
94 | _convert(image, beta=random.uniform(-32, 32))
95 |
96 | #contrast distortion
97 | if random.randrange(2):
98 | _convert(image, alpha=random.uniform(0.5, 1.5))
99 |
100 | image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
101 |
102 | #saturation distortion
103 | if random.randrange(2):
104 | _convert(image[:, :, 1], alpha=random.uniform(0.5, 1.5))
105 |
106 | #hue distortion
107 | if random.randrange(2):
108 | tmp = image[:, :, 0].astype(int) + random.randint(-18, 18)
109 | tmp %= 180
110 | image[:, :, 0] = tmp
111 |
112 | image = cv2.cvtColor(image, cv2.COLOR_HSV2BGR)
113 |
114 | else:
115 |
116 | #brightness distortion
117 | if random.randrange(2):
118 | _convert(image, beta=random.uniform(-32, 32))
119 |
120 | image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
121 |
122 | #saturation distortion
123 | if random.randrange(2):
124 | _convert(image[:, :, 1], alpha=random.uniform(0.5, 1.5))
125 |
126 | #hue distortion
127 | if random.randrange(2):
128 | tmp = image[:, :, 0].astype(int) + random.randint(-18, 18)
129 | tmp %= 180
130 | image[:, :, 0] = tmp
131 |
132 | image = cv2.cvtColor(image, cv2.COLOR_HSV2BGR)
133 |
134 | #contrast distortion
135 | if random.randrange(2):
136 | _convert(image, alpha=random.uniform(0.5, 1.5))
137 |
138 | return image
139 |
140 |
141 | def _expand(image, boxes, fill, p):
142 | if random.randrange(2):
143 | return image, boxes
144 |
145 | height, width, depth = image.shape
146 |
147 | scale = random.uniform(1, p)
148 | w = int(scale * width)
149 | h = int(scale * height)
150 |
151 | left = random.randint(0, w - width)
152 | top = random.randint(0, h - height)
153 |
154 | boxes_t = boxes.copy()
155 | boxes_t[:, :2] += (left, top)
156 | boxes_t[:, 2:] += (left, top)
157 | expand_image = np.empty(
158 | (h, w, depth),
159 | dtype=image.dtype)
160 | expand_image[:, :] = fill
161 | expand_image[top:top + height, left:left + width] = image
162 | image = expand_image
163 |
164 | return image, boxes_t
165 |
166 |
167 | def _mirror(image, boxes, landms):
168 | _, width, _ = image.shape
169 | if random.randrange(2):
170 | image = image[:, ::-1]
171 | boxes = boxes.copy()
172 | boxes[:, 0::2] = width - boxes[:, 2::-2]
173 |
174 | # landm
175 | landms = landms.copy()
176 | landms = landms.reshape([-1, 5, 2])
177 | landms[:, :, 0] = width - landms[:, :, 0]
178 | tmp = landms[:, 1, :].copy()
179 | landms[:, 1, :] = landms[:, 0, :]
180 | landms[:, 0, :] = tmp
181 | tmp1 = landms[:, 4, :].copy()
182 | landms[:, 4, :] = landms[:, 3, :]
183 | landms[:, 3, :] = tmp1
184 | landms = landms.reshape([-1, 10])
185 |
186 | return image, boxes, landms
187 |
188 |
189 | def _pad_to_square(image, rgb_mean, pad_image_flag):
190 | if not pad_image_flag:
191 | return image
192 | height, width, _ = image.shape
193 | long_side = max(width, height)
194 | image_t = np.empty((long_side, long_side, 3), dtype=image.dtype)
195 | image_t[:, :] = rgb_mean
196 | image_t[0:0 + height, 0:0 + width] = image
197 | return image_t
198 |
199 |
200 | def _resize_subtract_mean(image, insize, rgb_mean):
201 | interp_methods = [cv2.INTER_LINEAR, cv2.INTER_CUBIC, cv2.INTER_AREA, cv2.INTER_NEAREST, cv2.INTER_LANCZOS4]
202 | interp_method = interp_methods[random.randrange(5)]
203 | image = cv2.resize(image, (insize, insize), interpolation=interp_method)
204 | image = image.astype(np.float32)
205 | image -= rgb_mean
206 | return image.transpose(2, 0, 1)
207 |
208 |
209 | class preproc(object):
210 |
211 | def __init__(self, img_dim, rgb_means):
212 | self.img_dim = img_dim
213 | self.rgb_means = rgb_means
214 |
215 | def __call__(self, image, targets):
216 | assert targets.shape[0] > 0, "this image does not have gt"
217 |
218 | boxes = targets[:, :4].copy()
219 | labels = targets[:, -1].copy()
220 | landm = targets[:, 4:-1].copy()
221 |
222 | image_t, boxes_t, labels_t, landm_t, pad_image_flag = _crop(image, boxes, labels, landm, self.img_dim)
223 | image_t = _distort(image_t)
224 | image_t = _pad_to_square(image_t,self.rgb_means, pad_image_flag)
225 | image_t, boxes_t, landm_t = _mirror(image_t, boxes_t, landm_t)
226 | height, width, _ = image_t.shape
227 | image_t = _resize_subtract_mean(image_t, self.img_dim, self.rgb_means)
228 | boxes_t[:, 0::2] /= width
229 | boxes_t[:, 1::2] /= height
230 |
231 | landm_t[:, 0::2] /= width
232 | landm_t[:, 1::2] /= height
233 |
234 | labels_t = np.expand_dims(labels_t, 1)
235 | targets_t = np.hstack((boxes_t, landm_t, labels_t))
236 |
237 | return image_t, targets_t
238 |
--------------------------------------------------------------------------------
/retinaface/data/wider_face.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | import torch
3 | import torch.utils.data as data
4 |
5 |
6 | class WiderFaceDetection(data.Dataset):
7 | def __init__(self, txt_path, preproc=None):
8 | self.preproc = preproc
9 | self.imgs_path = []
10 | self.words = []
11 | f = open(txt_path, 'r')
12 | lines = f.readlines()
13 | isFirst = True
14 | labels = []
15 | for line in lines:
16 | line = line.rstrip()
17 | if line.startswith('#'):
18 | if isFirst is True:
19 | isFirst = False
20 | else:
21 | labels_copy = labels.copy()
22 | self.words.append(labels_copy)
23 | labels.clear()
24 | path = line[2:]
25 | path = txt_path.replace('label.txt', 'images/') + path
26 | self.imgs_path.append(path)
27 | else:
28 | line = line.split(' ')
29 | label = [float(x) for x in line]
30 | labels.append(label)
31 |
32 | self.words.append(labels)
33 |
34 | def __len__(self):
35 | return len(self.imgs_path)
36 |
37 | def __getitem__(self, index):
38 | img = cv2.imread(self.imgs_path[index])
39 | height, width, _ = img.shape
40 |
41 | labels = self.words[index]
42 | annotations = np.zeros((0, 15))
43 | if len(labels) == 0:
44 | return annotations
45 | for idx, label in enumerate(labels):
46 | annotation = np.zeros((1, 15))
47 | # bbox
48 | annotation[0, 0] = label[0] # x1
49 | annotation[0, 1] = label[1] # y1
50 | annotation[0, 2] = label[0] + label[2] # x2
51 | annotation[0, 3] = label[1] + label[3] # y2
52 |
53 | # landmarks
54 | annotation[0, 4] = label[4] # l0_x
55 | annotation[0, 5] = label[5] # l0_y
56 | annotation[0, 6] = label[7] # l1_x
57 | annotation[0, 7] = label[8] # l1_y
58 | annotation[0, 8] = label[10] # l2_x
59 | annotation[0, 9] = label[11] # l2_y
60 | annotation[0, 10] = label[13] # l3_x
61 | annotation[0, 11] = label[14] # l3_y
62 | annotation[0, 12] = label[16] # l4_x
63 | annotation[0, 13] = label[17] # l4_y
64 | if (annotation[0, 4] < 0):
65 | annotation[0, 14] = -1
66 | else:
67 | annotation[0, 14] = 1
68 |
69 | annotations = np.append(annotations, annotation, axis=0)
70 | target = np.array(annotations)
71 | if self.preproc is not None:
72 | img, target = self.preproc(img, target)
73 |
74 | return torch.from_numpy(img), target
75 |
76 |
77 | def detection_collate(batch):
78 | """Custom collate fn for dealing with batches of images that have a different
79 | number of associated object annotations (bounding boxes).
80 |
81 | Arguments:
82 | batch: (tuple) A tuple of tensor images and lists of annotations
83 |
84 | Return:
85 | A tuple containing:
86 | 1) (tensor) batch of images stacked on their 0 dim
87 | 2) (list of tensors) annotations for a given image are stacked on 0 dim
88 | """
89 | targets = []
90 | imgs = []
91 | for _, sample in enumerate(batch):
92 | for _, tup in enumerate(sample):
93 | if torch.is_tensor(tup):
94 | imgs.append(tup)
95 | elif isinstance(tup, type(np.empty(0))):
96 | annos = torch.from_numpy(tup).float()
97 | targets.append(annos)
98 |
99 | return (torch.stack(imgs, 0), targets)
100 |
--------------------------------------------------------------------------------
/retinaface/detector.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function
2 |
3 | import numpy as np
4 | import torch
5 | import torch.backends.cudnn as cudnn
6 |
7 | from retinaface.data import cfg_mnet
8 | from retinaface.layers.functions.prior_box import PriorBox
9 | from retinaface.loader import load_model
10 | from retinaface.utils.box_utils import decode, decode_landm
11 | from retinaface.utils.nms.py_cpu_nms import py_cpu_nms
12 |
13 | cudnn.benchmark = True
14 | device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
15 | # device = torch.device('cpu')
16 | model = load_model().to(device)
17 | model.eval()
18 |
19 |
20 | def detect_faces(img_raw, confidence_threshold=0.9, top_k=5000, nms_threshold=0.4, keep_top_k=750, resize=1):
21 | img = np.float32(img_raw)
22 | im_height, im_width = img.shape[:2]
23 | scale = torch.Tensor([img.shape[1], img.shape[0], img.shape[1], img.shape[0]])
24 | img -= (104, 117, 123)
25 | img = img.transpose(2, 0, 1)
26 | img = torch.from_numpy(img).unsqueeze(0)
27 | img = img.to(device)
28 | scale = scale.to(device)
29 |
30 | # tic = time.time()
31 | with torch.no_grad():
32 | loc, conf, landms = model(img) # forward pass
33 | # print('net forward time: {:.4f}'.format(time.time() - tic))
34 |
35 | priorbox = PriorBox(cfg_mnet, image_size=(im_height, im_width))
36 | priors = priorbox.forward()
37 | priors = priors.to(device)
38 | prior_data = priors.data
39 | boxes = decode(loc.data.squeeze(0), prior_data, cfg_mnet['variance'])
40 | boxes = boxes * scale / resize
41 | boxes = boxes.cpu().numpy()
42 | scores = conf.squeeze(0).data.cpu().numpy()[:, 1]
43 | landms = decode_landm(landms.data.squeeze(0), prior_data, cfg_mnet['variance'])
44 | scale1 = torch.Tensor([img.shape[3], img.shape[2], img.shape[3], img.shape[2],
45 | img.shape[3], img.shape[2], img.shape[3], img.shape[2],
46 | img.shape[3], img.shape[2]])
47 | scale1 = scale1.to(device)
48 | landms = landms * scale1 / resize
49 | landms = landms.cpu().numpy()
50 |
51 | # ignore low scores
52 | inds = np.where(scores > confidence_threshold)[0]
53 | boxes = boxes[inds]
54 | landms = landms[inds]
55 | scores = scores[inds]
56 |
57 | # keep top-K before NMS
58 | order = scores.argsort()[::-1][:top_k]
59 | boxes = boxes[order]
60 | landms = landms[order]
61 | scores = scores[order]
62 |
63 | # do NMS
64 | dets = np.hstack((boxes, scores[:, np.newaxis])).astype(np.float32, copy=False)
65 | keep = py_cpu_nms(dets, nms_threshold)
66 | # keep = nms(dets, args.nms_threshold,force_cpu=args.cpu)
67 | dets = dets[keep, :]
68 | landms = landms[keep]
69 |
70 | # keep top-K faster NMS
71 | dets = dets[:keep_top_k, :]
72 | landms = landms[:keep_top_k, :]
73 | # print(landms.shape)
74 | landms = landms.reshape((-1, 5, 2))
75 | # print(landms.shape)
76 | landms = landms.transpose((0, 2, 1))
77 | # print(landms.shape)
78 | landms = landms.reshape(-1, 10, )
79 | # print(landms.shape)
80 |
81 | return dets, landms
82 |
--------------------------------------------------------------------------------
/retinaface/layers/__init__.py:
--------------------------------------------------------------------------------
1 | from .functions import *
2 | from .modules import *
3 |
--------------------------------------------------------------------------------
/retinaface/layers/functions/prior_box.py:
--------------------------------------------------------------------------------
1 | from itertools import product as product
2 | from math import ceil
3 |
4 | import torch
5 |
6 |
7 | class PriorBox(object):
8 | def __init__(self, cfg, image_size=None, phase='train'):
9 | super(PriorBox, self).__init__()
10 | self.min_sizes = cfg['min_sizes']
11 | self.steps = cfg['steps']
12 | self.clip = cfg['clip']
13 | self.image_size = image_size
14 | self.feature_maps = [[ceil(self.image_size[0] / step), ceil(self.image_size[1] / step)] for step in self.steps]
15 | self.name = "s"
16 |
17 | def forward(self):
18 | anchors = []
19 | for k, f in enumerate(self.feature_maps):
20 | min_sizes = self.min_sizes[k]
21 | for i, j in product(range(f[0]), range(f[1])):
22 | for min_size in min_sizes:
23 | s_kx = min_size / self.image_size[1]
24 | s_ky = min_size / self.image_size[0]
25 | dense_cx = [x * self.steps[k] / self.image_size[1] for x in [j + 0.5]]
26 | dense_cy = [y * self.steps[k] / self.image_size[0] for y in [i + 0.5]]
27 | for cy, cx in product(dense_cy, dense_cx):
28 | anchors += [cx, cy, s_kx, s_ky]
29 |
30 | # back to torch land
31 | output = torch.Tensor(anchors).view(-1, 4)
32 | if self.clip:
33 | output.clamp_(max=1, min=0)
34 | return output
35 |
--------------------------------------------------------------------------------
/retinaface/layers/modules/__init__.py:
--------------------------------------------------------------------------------
1 | from .multibox_loss import MultiBoxLoss
2 |
3 | __all__ = ['MultiBoxLoss']
4 |
--------------------------------------------------------------------------------
/retinaface/layers/modules/multibox_loss.py:
--------------------------------------------------------------------------------
1 | import torch
2 | import torch.nn as nn
3 | import torch.nn.functional as F
4 |
5 | from retinaface.data import cfg_mnet
6 | from retinaface.utils.box_utils import match, log_sum_exp
7 |
8 | GPU = cfg_mnet['gpu_train']
9 |
10 |
11 | class MultiBoxLoss(nn.Module):
12 | """SSD Weighted Loss Function
13 | Compute Targets:
14 | 1) Produce Confidence Target Indices by matching ground truth boxes
15 | with (default) 'priorboxes' that have jaccard index > threshold parameter
16 | (default threshold: 0.5).
17 | 2) Produce localization target by 'encoding' variance into offsets of ground
18 | truth boxes and their matched 'priorboxes'.
19 | 3) Hard negative mining to filter the excessive number of negative examples
20 | that comes with using a large number of default bounding boxes.
21 | (default negative:positive ratio 3:1)
22 | Objective Loss:
23 | L(x,c,l,g) = (Lconf(x, c) + αLloc(x,l,g)) / N
24 | Where, Lconf is the CrossEntropy Loss and Lloc is the SmoothL1 Loss
25 | weighted by α which is set to 1 by cross val.
26 | Args:
27 | c: class confidences,
28 | l: predicted boxes,
29 | g: ground truth boxes
30 | N: number of matched default boxes
31 | See: https://arxiv.org/pdf/1512.02325.pdf for more details.
32 | """
33 |
34 | def __init__(self, num_classes, overlap_thresh, prior_for_matching, bkg_label, neg_mining, neg_pos, neg_overlap,
35 | encode_target):
36 | super(MultiBoxLoss, self).__init__()
37 | self.num_classes = num_classes
38 | self.threshold = overlap_thresh
39 | self.background_label = bkg_label
40 | self.encode_target = encode_target
41 | self.use_prior_for_matching = prior_for_matching
42 | self.do_neg_mining = neg_mining
43 | self.negpos_ratio = neg_pos
44 | self.neg_overlap = neg_overlap
45 | self.variance = [0.1, 0.2]
46 |
47 | def forward(self, predictions, priors, targets):
48 | """Multibox Loss
49 | Args:
50 | predictions (tuple): A tuple containing loc preds, conf preds,
51 | and prior boxes from SSD net.
52 | conf shape: torch.size(batch_size,num_priors,num_classes)
53 | loc shape: torch.size(batch_size,num_priors,4)
54 | priors shape: torch.size(num_priors,4)
55 |
56 | ground_truth (tensor): Ground truth boxes and labels for a batch,
57 | shape: [batch_size,num_objs,5] (last idx is the label).
58 | """
59 |
60 | loc_data, conf_data, landm_data = predictions
61 | priors = priors
62 | num = loc_data.size(0)
63 | num_priors = (priors.size(0))
64 |
65 | # match priors (default boxes) and ground truth boxes
66 | loc_t = torch.Tensor(num, num_priors, 4)
67 | landm_t = torch.Tensor(num, num_priors, 10)
68 | conf_t = torch.LongTensor(num, num_priors)
69 | for idx in range(num):
70 | truths = targets[idx][:, :4].data
71 | labels = targets[idx][:, -1].data
72 | landms = targets[idx][:, 4:14].data
73 | defaults = priors.data
74 | match(self.threshold, truths, defaults, self.variance, labels, landms, loc_t, conf_t, landm_t, idx)
75 | if GPU:
76 | loc_t = loc_t.cuda()
77 | conf_t = conf_t.cuda()
78 | landm_t = landm_t.cuda()
79 |
80 | zeros = torch.tensor(0).cuda()
81 | # landm Loss (Smooth L1)
82 | # Shape: [batch,num_priors,10]
83 | pos1 = conf_t > zeros
84 | num_pos_landm = pos1.long().sum(1, keepdim=True)
85 | N1 = max(num_pos_landm.data.sum().float(), 1)
86 | pos_idx1 = pos1.unsqueeze(pos1.dim()).expand_as(landm_data)
87 | landm_p = landm_data[pos_idx1].view(-1, 10)
88 | landm_t = landm_t[pos_idx1].view(-1, 10)
89 | loss_landm = F.smooth_l1_loss(landm_p, landm_t, reduction='sum')
90 |
91 | pos = conf_t != zeros
92 | conf_t[pos] = 1
93 |
94 | # Localization Loss (Smooth L1)
95 | # Shape: [batch,num_priors,4]
96 | pos_idx = pos.unsqueeze(pos.dim()).expand_as(loc_data)
97 | loc_p = loc_data[pos_idx].view(-1, 4)
98 | loc_t = loc_t[pos_idx].view(-1, 4)
99 | loss_l = F.smooth_l1_loss(loc_p, loc_t, reduction='sum')
100 |
101 | # Compute max conf across batch for hard negative mining
102 | batch_conf = conf_data.view(-1, self.num_classes)
103 | loss_c = log_sum_exp(batch_conf) - batch_conf.gather(1, conf_t.view(-1, 1))
104 |
105 | # Hard Negative Mining
106 | loss_c[pos.view(-1, 1)] = 0 # filter out pos boxes for now
107 | loss_c = loss_c.view(num, -1)
108 | _, loss_idx = loss_c.sort(1, descending=True)
109 | _, idx_rank = loss_idx.sort(1)
110 | num_pos = pos.long().sum(1, keepdim=True)
111 | num_neg = torch.clamp(self.negpos_ratio * num_pos, max=pos.size(1) - 1)
112 | neg = idx_rank < num_neg.expand_as(idx_rank)
113 |
114 | # Confidence Loss Including Positive and Negative Examples
115 | pos_idx = pos.unsqueeze(2).expand_as(conf_data)
116 | neg_idx = neg.unsqueeze(2).expand_as(conf_data)
117 | conf_p = conf_data[(pos_idx + neg_idx).gt(0)].view(-1, self.num_classes)
118 | targets_weighted = conf_t[(pos + neg).gt(0)]
119 | loss_c = F.cross_entropy(conf_p, targets_weighted, reduction='sum')
120 |
121 | # Sum of losses: L(x,c,l,g) = (Lconf(x, c) + αLloc(x,l,g)) / N
122 | N = max(num_pos.data.sum().float(), 1)
123 | loss_l /= N
124 | loss_c /= N
125 | loss_landm /= N1
126 |
127 | return loss_l, loss_c, loss_landm
128 |
--------------------------------------------------------------------------------
/retinaface/loader.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function
2 |
3 | import torch
4 |
5 | from retinaface.data import cfg_mnet
6 | from retinaface.models.retinaface import RetinaFace
7 |
8 |
9 | def check_keys(model, pretrained_state_dict):
10 | ckpt_keys = set(pretrained_state_dict.keys())
11 | model_keys = set(model.state_dict().keys())
12 | used_pretrained_keys = model_keys & ckpt_keys
13 | unused_pretrained_keys = ckpt_keys - model_keys
14 | missing_keys = model_keys - ckpt_keys
15 | # print('Missing keys:{}'.format(len(missing_keys)))
16 | # print('Unused checkpoint keys:{}'.format(len(unused_pretrained_keys)))
17 | # print('Used keys:{}'.format(len(used_pretrained_keys)))
18 | assert len(used_pretrained_keys) > 0, 'load NONE from pretrained checkpoint'
19 | return True
20 |
21 |
22 | def remove_prefix(state_dict, prefix):
23 | ''' Old style model is stored with all names of parameters sharing common prefix 'module.' '''
24 | # print('remove prefix \'{}\''.format(prefix))
25 | f = lambda x: x.split(prefix, 1)[-1] if x.startswith(prefix) else x
26 | return {f(key): value for key, value in state_dict.items()}
27 |
28 |
29 | def load_model():
30 | pretrained_path = 'retinaface/weights/mobilenet0.25_Final.pth'
31 | # print('Loading pretrained model from {}'.format(pretrained_path))
32 | model = RetinaFace(cfg=cfg_mnet, phase='test')
33 |
34 | device = torch.cuda.current_device()
35 | pretrained_dict = torch.load(pretrained_path, map_location=lambda storage, loc: storage.cuda(device))
36 | if "state_dict" in pretrained_dict.keys():
37 | pretrained_dict = remove_prefix(pretrained_dict['state_dict'], 'module.')
38 | else:
39 | pretrained_dict = remove_prefix(pretrained_dict, 'module.')
40 | check_keys(model, pretrained_dict)
41 | model.load_state_dict(pretrained_dict, strict=False)
42 | # print('Finished loading model!')
43 | return model
44 |
--------------------------------------------------------------------------------
/retinaface/models/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/foamliu/Face-Attributes-Mobile/5ad6186312308f95495a6bf17e9fa9b4f4f4604f/retinaface/models/__init__.py
--------------------------------------------------------------------------------
/retinaface/models/net.py:
--------------------------------------------------------------------------------
1 | import torch
2 | import torch.nn as nn
3 | import torch.nn.functional as F
4 |
5 |
6 | def conv_bn(inp, oup, stride=1, leaky=0):
7 | return nn.Sequential(
8 | nn.Conv2d(inp, oup, 3, stride, 1, bias=False),
9 | nn.BatchNorm2d(oup),
10 | nn.LeakyReLU(negative_slope=leaky, inplace=True)
11 | )
12 |
13 |
14 | def conv_bn_no_relu(inp, oup, stride):
15 | return nn.Sequential(
16 | nn.Conv2d(inp, oup, 3, stride, 1, bias=False),
17 | nn.BatchNorm2d(oup),
18 | )
19 |
20 |
21 | def conv_bn1X1(inp, oup, stride, leaky=0):
22 | return nn.Sequential(
23 | nn.Conv2d(inp, oup, 1, stride, padding=0, bias=False),
24 | nn.BatchNorm2d(oup),
25 | nn.LeakyReLU(negative_slope=leaky, inplace=True)
26 | )
27 |
28 |
29 | def conv_dw(inp, oup, stride, leaky=0.1):
30 | return nn.Sequential(
31 | nn.Conv2d(inp, inp, 3, stride, 1, groups=inp, bias=False),
32 | nn.BatchNorm2d(inp),
33 | nn.LeakyReLU(negative_slope=leaky, inplace=True),
34 |
35 | nn.Conv2d(inp, oup, 1, 1, 0, bias=False),
36 | nn.BatchNorm2d(oup),
37 | nn.LeakyReLU(negative_slope=leaky, inplace=True),
38 | )
39 |
40 |
41 | class SSH(nn.Module):
42 | def __init__(self, in_channel, out_channel):
43 | super(SSH, self).__init__()
44 | assert out_channel % 4 == 0
45 | leaky = 0
46 | if (out_channel <= 64):
47 | leaky = 0.1
48 | self.conv3X3 = conv_bn_no_relu(in_channel, out_channel // 2, stride=1)
49 |
50 | self.conv5X5_1 = conv_bn(in_channel, out_channel // 4, stride=1, leaky=leaky)
51 | self.conv5X5_2 = conv_bn_no_relu(out_channel // 4, out_channel // 4, stride=1)
52 |
53 | self.conv7X7_2 = conv_bn(out_channel // 4, out_channel // 4, stride=1, leaky=leaky)
54 | self.conv7x7_3 = conv_bn_no_relu(out_channel // 4, out_channel // 4, stride=1)
55 |
56 | def forward(self, input):
57 | conv3X3 = self.conv3X3(input)
58 |
59 | conv5X5_1 = self.conv5X5_1(input)
60 | conv5X5 = self.conv5X5_2(conv5X5_1)
61 |
62 | conv7X7_2 = self.conv7X7_2(conv5X5_1)
63 | conv7X7 = self.conv7x7_3(conv7X7_2)
64 |
65 | out = torch.cat([conv3X3, conv5X5, conv7X7], dim=1)
66 | out = F.relu(out)
67 | return out
68 |
69 |
70 | class FPN(nn.Module):
71 | def __init__(self, in_channels_list, out_channels):
72 | super(FPN, self).__init__()
73 | leaky = 0
74 | if (out_channels <= 64):
75 | leaky = 0.1
76 | self.output1 = conv_bn1X1(in_channels_list[0], out_channels, stride=1, leaky=leaky)
77 | self.output2 = conv_bn1X1(in_channels_list[1], out_channels, stride=1, leaky=leaky)
78 | self.output3 = conv_bn1X1(in_channels_list[2], out_channels, stride=1, leaky=leaky)
79 |
80 | self.merge1 = conv_bn(out_channels, out_channels, leaky=leaky)
81 | self.merge2 = conv_bn(out_channels, out_channels, leaky=leaky)
82 |
83 | def forward(self, input):
84 | # names = list(input.keys())
85 | input = list(input.values())
86 |
87 | output1 = self.output1(input[0])
88 | output2 = self.output2(input[1])
89 | output3 = self.output3(input[2])
90 |
91 | up3 = F.interpolate(output3, size=[output2.size(2), output2.size(3)], mode="nearest")
92 | output2 = output2 + up3
93 | output2 = self.merge2(output2)
94 |
95 | up2 = F.interpolate(output2, size=[output1.size(2), output1.size(3)], mode="nearest")
96 | output1 = output1 + up2
97 | output1 = self.merge1(output1)
98 |
99 | out = [output1, output2, output3]
100 | return out
101 |
102 |
103 | class MobileNetV1(nn.Module):
104 | def __init__(self):
105 | super(MobileNetV1, self).__init__()
106 | self.stage1 = nn.Sequential(
107 | conv_bn(3, 8, 2, leaky=0.1), # 3
108 | conv_dw(8, 16, 1), # 7
109 | conv_dw(16, 32, 2), # 11
110 | conv_dw(32, 32, 1), # 19
111 | conv_dw(32, 64, 2), # 27
112 | conv_dw(64, 64, 1), # 43
113 | )
114 | self.stage2 = nn.Sequential(
115 | conv_dw(64, 128, 2), # 43 + 16 = 59
116 | conv_dw(128, 128, 1), # 59 + 32 = 91
117 | conv_dw(128, 128, 1), # 91 + 32 = 123
118 | conv_dw(128, 128, 1), # 123 + 32 = 155
119 | conv_dw(128, 128, 1), # 155 + 32 = 187
120 | conv_dw(128, 128, 1), # 187 + 32 = 219
121 | )
122 | self.stage3 = nn.Sequential(
123 | conv_dw(128, 256, 2), # 219 +3 2 = 241
124 | conv_dw(256, 256, 1), # 241 + 64 = 301
125 | )
126 | self.avg = nn.AdaptiveAvgPool2d((1, 1))
127 | self.fc = nn.Linear(256, 1000)
128 |
129 | def forward(self, x):
130 | x = self.stage1(x)
131 | x = self.stage2(x)
132 | x = self.stage3(x)
133 | x = self.avg(x)
134 | # x = self.model(x)
135 | x = x.view(-1, 256)
136 | x = self.fc(x)
137 | return x
138 |
--------------------------------------------------------------------------------
/retinaface/models/retinaface.py:
--------------------------------------------------------------------------------
1 | import torch
2 | import torch.nn as nn
3 | import torch.nn.functional as F
4 | import torchvision.models._utils as _utils
5 |
6 | from retinaface.models.net import FPN as FPN
7 | from retinaface.models.net import MobileNetV1 as MobileNetV1
8 | from retinaface.models.net import SSH as SSH
9 |
10 |
11 | class ClassHead(nn.Module):
12 | def __init__(self, inchannels=512, num_anchors=3):
13 | super(ClassHead, self).__init__()
14 | self.num_anchors = num_anchors
15 | self.conv1x1 = nn.Conv2d(inchannels, self.num_anchors * 2, kernel_size=(1, 1), stride=1, padding=0)
16 |
17 | def forward(self, x):
18 | out = self.conv1x1(x)
19 | out = out.permute(0, 2, 3, 1).contiguous()
20 |
21 | return out.view(out.shape[0], -1, 2)
22 |
23 |
24 | class BboxHead(nn.Module):
25 | def __init__(self, inchannels=512, num_anchors=3):
26 | super(BboxHead, self).__init__()
27 | self.conv1x1 = nn.Conv2d(inchannels, num_anchors * 4, kernel_size=(1, 1), stride=1, padding=0)
28 |
29 | def forward(self, x):
30 | out = self.conv1x1(x)
31 | out = out.permute(0, 2, 3, 1).contiguous()
32 |
33 | return out.view(out.shape[0], -1, 4)
34 |
35 |
36 | class LandmarkHead(nn.Module):
37 | def __init__(self, inchannels=512, num_anchors=3):
38 | super(LandmarkHead, self).__init__()
39 | self.conv1x1 = nn.Conv2d(inchannels, num_anchors * 10, kernel_size=(1, 1), stride=1, padding=0)
40 |
41 | def forward(self, x):
42 | out = self.conv1x1(x)
43 | out = out.permute(0, 2, 3, 1).contiguous()
44 |
45 | return out.view(out.shape[0], -1, 10)
46 |
47 |
48 | class RetinaFace(nn.Module):
49 | def __init__(self, cfg=None, phase='train'):
50 | """
51 | :param cfg: Network related settings.
52 | :param phase: train or test.
53 | """
54 | super(RetinaFace, self).__init__()
55 | self.phase = phase
56 | backbone = MobileNetV1()
57 | # if cfg['name'] == 'mobilenet0.25':
58 | # backbone = MobileNetV1()
59 | # if cfg['pretrain']:
60 | # checkpoint = torch.load("./weights/mobilenetV1X0.25_pretrain.tar", map_location=torch.device('cpu'))
61 | # from collections import OrderedDict
62 | # new_state_dict = OrderedDict()
63 | # for k, v in checkpoint['state_dict'].items():
64 | # name = k[7:] # remove module.
65 | # new_state_dict[name] = v
66 | # # load params
67 | # backbone.load_state_dict(new_state_dict)
68 | # elif cfg['name'] == 'Resnet50':
69 | # import torchvision.models as models
70 | # backbone = models.resnet50(pretrained=cfg['pretrain'])
71 |
72 | self.body = _utils.IntermediateLayerGetter(backbone, cfg['return_layers'])
73 | in_channels_stage2 = cfg['in_channel']
74 | in_channels_list = [
75 | in_channels_stage2 * 2,
76 | in_channels_stage2 * 4,
77 | in_channels_stage2 * 8,
78 | ]
79 | out_channels = cfg['out_channel']
80 | self.fpn = FPN(in_channels_list, out_channels)
81 | self.ssh1 = SSH(out_channels, out_channels)
82 | self.ssh2 = SSH(out_channels, out_channels)
83 | self.ssh3 = SSH(out_channels, out_channels)
84 |
85 | self.ClassHead = self._make_class_head(fpn_num=3, inchannels=cfg['out_channel'])
86 | self.BboxHead = self._make_bbox_head(fpn_num=3, inchannels=cfg['out_channel'])
87 | self.LandmarkHead = self._make_landmark_head(fpn_num=3, inchannels=cfg['out_channel'])
88 |
89 | def _make_class_head(self, fpn_num=3, inchannels=64, anchor_num=2):
90 | classhead = nn.ModuleList()
91 | for i in range(fpn_num):
92 | classhead.append(ClassHead(inchannels, anchor_num))
93 | return classhead
94 |
95 | def _make_bbox_head(self, fpn_num=3, inchannels=64, anchor_num=2):
96 | bboxhead = nn.ModuleList()
97 | for i in range(fpn_num):
98 | bboxhead.append(BboxHead(inchannels, anchor_num))
99 | return bboxhead
100 |
101 | def _make_landmark_head(self, fpn_num=3, inchannels=64, anchor_num=2):
102 | landmarkhead = nn.ModuleList()
103 | for i in range(fpn_num):
104 | landmarkhead.append(LandmarkHead(inchannels, anchor_num))
105 | return landmarkhead
106 |
107 | def forward(self, inputs):
108 | out = self.body(inputs)
109 |
110 | # FPN
111 | fpn = self.fpn(out)
112 |
113 | # SSH
114 | feature1 = self.ssh1(fpn[0])
115 | feature2 = self.ssh2(fpn[1])
116 | feature3 = self.ssh3(fpn[2])
117 | features = [feature1, feature2, feature3]
118 |
119 | bbox_regressions = torch.cat([self.BboxHead[i](feature) for i, feature in enumerate(features)], dim=1)
120 | classifications = torch.cat([self.ClassHead[i](feature) for i, feature in enumerate(features)], dim=1)
121 | ldm_regressions = torch.cat([self.LandmarkHead[i](feature) for i, feature in enumerate(features)], dim=1)
122 |
123 | if self.phase == 'train':
124 | output = (bbox_regressions, classifications, ldm_regressions)
125 | else:
126 | output = (bbox_regressions, F.softmax(classifications, dim=-1), ldm_regressions)
127 | return output
128 |
--------------------------------------------------------------------------------
/retinaface/utils/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/foamliu/Face-Attributes-Mobile/5ad6186312308f95495a6bf17e9fa9b4f4f4604f/retinaface/utils/__init__.py
--------------------------------------------------------------------------------
/retinaface/utils/box_utils.py:
--------------------------------------------------------------------------------
1 | import torch
2 | import numpy as np
3 |
4 |
5 | def point_form(boxes):
6 | """ Convert prior_boxes to (xmin, ymin, xmax, ymax)
7 | representation for comparison to point form ground truth data.
8 | Args:
9 | boxes: (tensor) center-size default boxes from priorbox layers.
10 | Return:
11 | boxes: (tensor) Converted xmin, ymin, xmax, ymax form of boxes.
12 | """
13 | return torch.cat((boxes[:, :2] - boxes[:, 2:]/2, # xmin, ymin
14 | boxes[:, :2] + boxes[:, 2:]/2), 1) # xmax, ymax
15 |
16 |
17 | def center_size(boxes):
18 | """ Convert prior_boxes to (cx, cy, w, h)
19 | representation for comparison to center-size form ground truth data.
20 | Args:
21 | boxes: (tensor) point_form boxes
22 | Return:
23 | boxes: (tensor) Converted xmin, ymin, xmax, ymax form of boxes.
24 | """
25 | return torch.cat((boxes[:, 2:] + boxes[:, :2])/2, # cx, cy
26 | boxes[:, 2:] - boxes[:, :2], 1) # w, h
27 |
28 |
29 | def intersect(box_a, box_b):
30 | """ We resize both tensors to [A,B,2] without new malloc:
31 | [A,2] -> [A,1,2] -> [A,B,2]
32 | [B,2] -> [1,B,2] -> [A,B,2]
33 | Then we compute the area of intersect between box_a and box_b.
34 | Args:
35 | box_a: (tensor) bounding boxes, Shape: [A,4].
36 | box_b: (tensor) bounding boxes, Shape: [B,4].
37 | Return:
38 | (tensor) intersection area, Shape: [A,B].
39 | """
40 | A = box_a.size(0)
41 | B = box_b.size(0)
42 | max_xy = torch.min(box_a[:, 2:].unsqueeze(1).expand(A, B, 2),
43 | box_b[:, 2:].unsqueeze(0).expand(A, B, 2))
44 | min_xy = torch.max(box_a[:, :2].unsqueeze(1).expand(A, B, 2),
45 | box_b[:, :2].unsqueeze(0).expand(A, B, 2))
46 | inter = torch.clamp((max_xy - min_xy), min=0)
47 | return inter[:, :, 0] * inter[:, :, 1]
48 |
49 |
50 | def jaccard(box_a, box_b):
51 | """Compute the jaccard overlap of two sets of boxes. The jaccard overlap
52 | is simply the intersection over union of two boxes. Here we operate on
53 | ground truth boxes and default boxes.
54 | E.g.:
55 | A ∩ B / A ∪ B = A ∩ B / (area(A) + area(B) - A ∩ B)
56 | Args:
57 | box_a: (tensor) Ground truth bounding boxes, Shape: [num_objects,4]
58 | box_b: (tensor) Prior boxes from priorbox layers, Shape: [num_priors,4]
59 | Return:
60 | jaccard overlap: (tensor) Shape: [box_a.size(0), box_b.size(0)]
61 | """
62 | inter = intersect(box_a, box_b)
63 | area_a = ((box_a[:, 2]-box_a[:, 0]) *
64 | (box_a[:, 3]-box_a[:, 1])).unsqueeze(1).expand_as(inter) # [A,B]
65 | area_b = ((box_b[:, 2]-box_b[:, 0]) *
66 | (box_b[:, 3]-box_b[:, 1])).unsqueeze(0).expand_as(inter) # [A,B]
67 | union = area_a + area_b - inter
68 | return inter / union # [A,B]
69 |
70 |
71 | def matrix_iou(a, b):
72 | """
73 | return iou of a and b, numpy version for data augenmentation
74 | """
75 | lt = np.maximum(a[:, np.newaxis, :2], b[:, :2])
76 | rb = np.minimum(a[:, np.newaxis, 2:], b[:, 2:])
77 |
78 | area_i = np.prod(rb - lt, axis=2) * (lt < rb).all(axis=2)
79 | area_a = np.prod(a[:, 2:] - a[:, :2], axis=1)
80 | area_b = np.prod(b[:, 2:] - b[:, :2], axis=1)
81 | return area_i / (area_a[:, np.newaxis] + area_b - area_i)
82 |
83 |
84 | def matrix_iof(a, b):
85 | """
86 | return iof of a and b, numpy version for data augenmentation
87 | """
88 | lt = np.maximum(a[:, np.newaxis, :2], b[:, :2])
89 | rb = np.minimum(a[:, np.newaxis, 2:], b[:, 2:])
90 |
91 | area_i = np.prod(rb - lt, axis=2) * (lt < rb).all(axis=2)
92 | area_a = np.prod(a[:, 2:] - a[:, :2], axis=1)
93 | return area_i / np.maximum(area_a[:, np.newaxis], 1)
94 |
95 |
96 | def match(threshold, truths, priors, variances, labels, landms, loc_t, conf_t, landm_t, idx):
97 | """Match each prior box with the ground truth box of the highest jaccard
98 | overlap, encode the bounding boxes, then return the matched indices
99 | corresponding to both confidence and location preds.
100 | Args:
101 | threshold: (float) The overlap threshold used when mathing boxes.
102 | truths: (tensor) Ground truth boxes, Shape: [num_obj, 4].
103 | priors: (tensor) Prior boxes from priorbox layers, Shape: [n_priors,4].
104 | variances: (tensor) Variances corresponding to each prior coord,
105 | Shape: [num_priors, 4].
106 | labels: (tensor) All the class labels for the image, Shape: [num_obj].
107 | landms: (tensor) Ground truth landms, Shape [num_obj, 10].
108 | loc_t: (tensor) Tensor to be filled w/ endcoded location targets.
109 | conf_t: (tensor) Tensor to be filled w/ matched indices for conf preds.
110 | landm_t: (tensor) Tensor to be filled w/ endcoded landm targets.
111 | idx: (int) current batch index
112 | Return:
113 | The matched indices corresponding to 1)location 2)confidence 3)landm preds.
114 | """
115 | # jaccard index
116 | overlaps = jaccard(
117 | truths,
118 | point_form(priors)
119 | )
120 | # (Bipartite Matching)
121 | # [1,num_objects] best prior for each ground truth
122 | best_prior_overlap, best_prior_idx = overlaps.max(1, keepdim=True)
123 |
124 | # ignore hard gt
125 | valid_gt_idx = best_prior_overlap[:, 0] >= 0.2
126 | best_prior_idx_filter = best_prior_idx[valid_gt_idx, :]
127 | if best_prior_idx_filter.shape[0] <= 0:
128 | loc_t[idx] = 0
129 | conf_t[idx] = 0
130 | return
131 |
132 | # [1,num_priors] best ground truth for each prior
133 | best_truth_overlap, best_truth_idx = overlaps.max(0, keepdim=True)
134 | best_truth_idx.squeeze_(0)
135 | best_truth_overlap.squeeze_(0)
136 | best_prior_idx.squeeze_(1)
137 | best_prior_idx_filter.squeeze_(1)
138 | best_prior_overlap.squeeze_(1)
139 | best_truth_overlap.index_fill_(0, best_prior_idx_filter, 2) # ensure best prior
140 | # TODO refactor: index best_prior_idx with long tensor
141 | # ensure every gt matches with its prior of max overlap
142 | for j in range(best_prior_idx.size(0)): # 判别此anchor是预测哪一个boxes
143 | best_truth_idx[best_prior_idx[j]] = j
144 | matches = truths[best_truth_idx] # Shape: [num_priors,4] 此处为每一个anchor对应的bbox取出来
145 | conf = labels[best_truth_idx] # Shape: [num_priors] 此处为每一个anchor对应的label取出来
146 | conf[best_truth_overlap < threshold] = 0 # label as background overlap<0.35的全部作为负样本
147 | loc = encode(matches, priors, variances)
148 |
149 | matches_landm = landms[best_truth_idx]
150 | landm = encode_landm(matches_landm, priors, variances)
151 | loc_t[idx] = loc # [num_priors,4] encoded offsets to learn
152 | conf_t[idx] = conf # [num_priors] top class label for each prior
153 | landm_t[idx] = landm
154 |
155 |
156 | def encode(matched, priors, variances):
157 | """Encode the variances from the priorbox layers into the ground truth boxes
158 | we have matched (based on jaccard overlap) with the prior boxes.
159 | Args:
160 | matched: (tensor) Coords of ground truth for each prior in point-form
161 | Shape: [num_priors, 4].
162 | priors: (tensor) Prior boxes in center-offset form
163 | Shape: [num_priors,4].
164 | variances: (list[float]) Variances of priorboxes
165 | Return:
166 | encoded boxes (tensor), Shape: [num_priors, 4]
167 | """
168 |
169 | # dist b/t match center and prior's center
170 | g_cxcy = (matched[:, :2] + matched[:, 2:])/2 - priors[:, :2]
171 | # encode variance
172 | g_cxcy /= (variances[0] * priors[:, 2:])
173 | # match wh / prior wh
174 | g_wh = (matched[:, 2:] - matched[:, :2]) / priors[:, 2:]
175 | g_wh = torch.log(g_wh) / variances[1]
176 | # return target for smooth_l1_loss
177 | return torch.cat([g_cxcy, g_wh], 1) # [num_priors,4]
178 |
179 | def encode_landm(matched, priors, variances):
180 | """Encode the variances from the priorbox layers into the ground truth boxes
181 | we have matched (based on jaccard overlap) with the prior boxes.
182 | Args:
183 | matched: (tensor) Coords of ground truth for each prior in point-form
184 | Shape: [num_priors, 10].
185 | priors: (tensor) Prior boxes in center-offset form
186 | Shape: [num_priors,4].
187 | variances: (list[float]) Variances of priorboxes
188 | Return:
189 | encoded landm (tensor), Shape: [num_priors, 10]
190 | """
191 |
192 | # dist b/t match center and prior's center
193 | matched = torch.reshape(matched, (matched.size(0), 5, 2))
194 | priors_cx = priors[:, 0].unsqueeze(1).expand(matched.size(0), 5).unsqueeze(2)
195 | priors_cy = priors[:, 1].unsqueeze(1).expand(matched.size(0), 5).unsqueeze(2)
196 | priors_w = priors[:, 2].unsqueeze(1).expand(matched.size(0), 5).unsqueeze(2)
197 | priors_h = priors[:, 3].unsqueeze(1).expand(matched.size(0), 5).unsqueeze(2)
198 | priors = torch.cat([priors_cx, priors_cy, priors_w, priors_h], dim=2)
199 | g_cxcy = matched[:, :, :2] - priors[:, :, :2]
200 | # encode variance
201 | g_cxcy /= (variances[0] * priors[:, :, 2:])
202 | # g_cxcy /= priors[:, :, 2:]
203 | g_cxcy = g_cxcy.reshape(g_cxcy.size(0), -1)
204 | # return target for smooth_l1_loss
205 | return g_cxcy
206 |
207 |
208 | # Adapted from https://github.com/Hakuyume/chainer-ssd
209 | def decode(loc, priors, variances):
210 | """Decode locations from predictions using priors to undo
211 | the encoding we did for offset regression at train time.
212 | Args:
213 | loc (tensor): location predictions for loc layers,
214 | Shape: [num_priors,4]
215 | priors (tensor): Prior boxes in center-offset form.
216 | Shape: [num_priors,4].
217 | variances: (list[float]) Variances of priorboxes
218 | Return:
219 | decoded bounding box predictions
220 | """
221 |
222 | boxes = torch.cat((
223 | priors[:, :2] + loc[:, :2] * variances[0] * priors[:, 2:],
224 | priors[:, 2:] * torch.exp(loc[:, 2:] * variances[1])), 1)
225 | boxes[:, :2] -= boxes[:, 2:] / 2
226 | boxes[:, 2:] += boxes[:, :2]
227 | return boxes
228 |
229 | def decode_landm(pre, priors, variances):
230 | """Decode landm from predictions using priors to undo
231 | the encoding we did for offset regression at train time.
232 | Args:
233 | pre (tensor): landm predictions for loc layers,
234 | Shape: [num_priors,10]
235 | priors (tensor): Prior boxes in center-offset form.
236 | Shape: [num_priors,4].
237 | variances: (list[float]) Variances of priorboxes
238 | Return:
239 | decoded landm predictions
240 | """
241 | landms = torch.cat((priors[:, :2] + pre[:, :2] * variances[0] * priors[:, 2:],
242 | priors[:, :2] + pre[:, 2:4] * variances[0] * priors[:, 2:],
243 | priors[:, :2] + pre[:, 4:6] * variances[0] * priors[:, 2:],
244 | priors[:, :2] + pre[:, 6:8] * variances[0] * priors[:, 2:],
245 | priors[:, :2] + pre[:, 8:10] * variances[0] * priors[:, 2:],
246 | ), dim=1)
247 | return landms
248 |
249 |
250 | def log_sum_exp(x):
251 | """Utility function for computing log_sum_exp while determining
252 | This will be used to determine unaveraged confidence loss across
253 | all examples in a batch.
254 | Args:
255 | x (Variable(tensor)): conf_preds from conf layers
256 | """
257 | x_max = x.data.max()
258 | return torch.log(torch.sum(torch.exp(x-x_max), 1, keepdim=True)) + x_max
259 |
260 |
261 | # Original author: Francisco Massa:
262 | # https://github.com/fmassa/object-detection.torch
263 | # Ported to PyTorch by Max deGroot (02/01/2017)
264 | def nms(boxes, scores, overlap=0.5, top_k=200):
265 | """Apply non-maximum suppression at test time to avoid detecting too many
266 | overlapping bounding boxes for a given object.
267 | Args:
268 | boxes: (tensor) The location preds for the img, Shape: [num_priors,4].
269 | scores: (tensor) The class predscores for the img, Shape:[num_priors].
270 | overlap: (float) The overlap thresh for suppressing unnecessary boxes.
271 | top_k: (int) The Maximum number of box preds to consider.
272 | Return:
273 | The indices of the kept boxes with respect to num_priors.
274 | """
275 |
276 | keep = torch.Tensor(scores.size(0)).fill_(0).long()
277 | if boxes.numel() == 0:
278 | return keep
279 | x1 = boxes[:, 0]
280 | y1 = boxes[:, 1]
281 | x2 = boxes[:, 2]
282 | y2 = boxes[:, 3]
283 | area = torch.mul(x2 - x1, y2 - y1)
284 | v, idx = scores.sort(0) # sort in ascending order
285 | # I = I[v >= 0.01]
286 | idx = idx[-top_k:] # indices of the top-k largest vals
287 | xx1 = boxes.new()
288 | yy1 = boxes.new()
289 | xx2 = boxes.new()
290 | yy2 = boxes.new()
291 | w = boxes.new()
292 | h = boxes.new()
293 |
294 | # keep = torch.Tensor()
295 | count = 0
296 | while idx.numel() > 0:
297 | i = idx[-1] # index of current largest val
298 | # keep.append(i)
299 | keep[count] = i
300 | count += 1
301 | if idx.size(0) == 1:
302 | break
303 | idx = idx[:-1] # remove kept element from view
304 | # load bboxes of next highest vals
305 | torch.index_select(x1, 0, idx, out=xx1)
306 | torch.index_select(y1, 0, idx, out=yy1)
307 | torch.index_select(x2, 0, idx, out=xx2)
308 | torch.index_select(y2, 0, idx, out=yy2)
309 | # store element-wise max with next highest score
310 | xx1 = torch.clamp(xx1, min=x1[i])
311 | yy1 = torch.clamp(yy1, min=y1[i])
312 | xx2 = torch.clamp(xx2, max=x2[i])
313 | yy2 = torch.clamp(yy2, max=y2[i])
314 | w.resize_as_(xx2)
315 | h.resize_as_(yy2)
316 | w = xx2 - xx1
317 | h = yy2 - yy1
318 | # check sizes of xx1 and xx2.. after each iteration
319 | w = torch.clamp(w, min=0.0)
320 | h = torch.clamp(h, min=0.0)
321 | inter = w*h
322 | # IoU = i / (area(a) + area(b) - i)
323 | rem_areas = torch.index_select(area, 0, idx) # load remaining areas)
324 | union = (rem_areas - inter) + area[i]
325 | IoU = inter/union # store result in iou
326 | # keep only elements with an IoU <= overlap
327 | idx = idx[IoU.le(overlap)]
328 | return keep, count
329 |
330 |
331 |
--------------------------------------------------------------------------------
/retinaface/utils/nms/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/foamliu/Face-Attributes-Mobile/5ad6186312308f95495a6bf17e9fa9b4f4f4604f/retinaface/utils/nms/__init__.py
--------------------------------------------------------------------------------
/retinaface/utils/nms/py_cpu_nms.py:
--------------------------------------------------------------------------------
1 | # --------------------------------------------------------
2 | # Fast R-CNN
3 | # Copyright (c) 2015 Microsoft
4 | # Licensed under The MIT License [see LICENSE for details]
5 | # Written by Ross Girshick
6 | # --------------------------------------------------------
7 |
8 | import numpy as np
9 |
10 | def py_cpu_nms(dets, thresh):
11 | """Pure Python NMS baseline."""
12 | x1 = dets[:, 0]
13 | y1 = dets[:, 1]
14 | x2 = dets[:, 2]
15 | y2 = dets[:, 3]
16 | scores = dets[:, 4]
17 |
18 | areas = (x2 - x1 + 1) * (y2 - y1 + 1)
19 | order = scores.argsort()[::-1]
20 |
21 | keep = []
22 | while order.size > 0:
23 | i = order[0]
24 | keep.append(i)
25 | xx1 = np.maximum(x1[i], x1[order[1:]])
26 | yy1 = np.maximum(y1[i], y1[order[1:]])
27 | xx2 = np.minimum(x2[i], x2[order[1:]])
28 | yy2 = np.minimum(y2[i], y2[order[1:]])
29 |
30 | w = np.maximum(0.0, xx2 - xx1 + 1)
31 | h = np.maximum(0.0, yy2 - yy1 + 1)
32 | inter = w * h
33 | ovr = inter / (areas[i] + areas[order[1:]] - inter)
34 |
35 | inds = np.where(ovr <= thresh)[0]
36 | order = order[inds + 1]
37 |
38 | return keep
39 |
--------------------------------------------------------------------------------
/retinaface/utils/timer.py:
--------------------------------------------------------------------------------
1 | # --------------------------------------------------------
2 | # Fast R-CNN
3 | # Copyright (c) 2015 Microsoft
4 | # Licensed under The MIT License [see LICENSE for details]
5 | # Written by Ross Girshick
6 | # --------------------------------------------------------
7 |
8 | import time
9 |
10 |
11 | class Timer(object):
12 | """A simple timer."""
13 | def __init__(self):
14 | self.total_time = 0.
15 | self.calls = 0
16 | self.start_time = 0.
17 | self.diff = 0.
18 | self.average_time = 0.
19 |
20 | def tic(self):
21 | # using time.time instead of time.clock because time time.clock
22 | # does not normalize for multithreading
23 | self.start_time = time.time()
24 |
25 | def toc(self, average=True):
26 | self.diff = time.time() - self.start_time
27 | self.total_time += self.diff
28 | self.calls += 1
29 | self.average_time = self.total_time / self.calls
30 | if average:
31 | return self.average_time
32 | else:
33 | return self.diff
34 |
35 | def clear(self):
36 | self.total_time = 0.
37 | self.calls = 0
38 | self.start_time = 0.
39 | self.diff = 0.
40 | self.average_time = 0.
41 |
--------------------------------------------------------------------------------
/retinaface/weights/mobilenet0.25_Final.pth:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/foamliu/Face-Attributes-Mobile/5ad6186312308f95495a6bf17e9fa9b4f4f4604f/retinaface/weights/mobilenet0.25_Final.pth
--------------------------------------------------------------------------------
/rotating_cube.py:
--------------------------------------------------------------------------------
1 | """
2 | PyTeapot module for drawing rotating cube using OpenGL as per
3 | quaternion or yaw, pitch, roll angles received over serial port.
4 | """
5 |
6 | import json
7 | import math
8 |
9 | import pygame
10 | from OpenGL.GL import *
11 | from OpenGL.GLU import *
12 | from pygame.locals import *
13 |
14 |
15 | def main():
16 | pygame.init()
17 | screen = pygame.display.set_mode((640, 480), OPENGL)
18 | pygame.display.set_caption("Face attributes orientation visualization")
19 | resizewin(640, 480)
20 | init()
21 |
22 | with open('sample_preds.json', 'r', encoding="utf-8") as file:
23 | data = json.load(file)
24 |
25 | for i in range(10):
26 | item = data[i]
27 | pitch = item['pitch_out']
28 | roll = item['roll_out']
29 | yaw = -item['yaw_out']
30 | draw(1, yaw, pitch, roll)
31 | pygame.image.save(screen, "images/{}_angle.jpg".format(i))
32 |
33 |
34 | def resizewin(width, height):
35 | """
36 | For resizing window
37 | """
38 | if height == 0:
39 | height = 1
40 | glViewport(0, 0, width, height)
41 | glMatrixMode(GL_PROJECTION)
42 | glLoadIdentity()
43 | gluPerspective(45, 1.0 * width / height, 0.1, 100.0)
44 | glMatrixMode(GL_MODELVIEW)
45 | glLoadIdentity()
46 |
47 |
48 | def init():
49 | glShadeModel(GL_SMOOTH)
50 | glClearColor(0.0, 0.0, 0.0, 0.0)
51 | glClearDepth(1.0)
52 | glEnable(GL_DEPTH_TEST)
53 | glDepthFunc(GL_LEQUAL)
54 | glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)
55 |
56 |
57 | def draw(w, nx, ny, nz):
58 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
59 | glLoadIdentity()
60 | glTranslatef(0, 0.0, -7.0)
61 |
62 | drawText((-2.6, 1.8, 2), "Face Attributes", 18)
63 | drawText((-2.6, 1.6, 2), "Module to Euler angles data", 16)
64 | drawText((-2.6, -2, 2), "Press Escape to exit.", 16)
65 |
66 | yaw = nx
67 | pitch = ny
68 | roll = nz
69 | drawText((-2.6, -1.8, 2), "Yaw: %f, Pitch: %f, Roll: %f" % (yaw, pitch, roll), 16)
70 | glRotatef(-roll, 0.00, 0.00, 1.00)
71 | glRotatef(pitch, 1.00, 0.00, 0.00)
72 | glRotatef(yaw, 0.00, 1.00, 0.00)
73 |
74 | glBegin(GL_QUADS)
75 | glColor3f(0.0, 1.0, 0.0)
76 | glVertex3f(1.0, 0.2, -1.0)
77 | glVertex3f(-1.0, 0.2, -1.0)
78 | glVertex3f(-1.0, 0.2, 1.0)
79 | glVertex3f(1.0, 0.2, 1.0)
80 |
81 | glColor3f(1.0, 0.5, 0.0)
82 | glVertex3f(1.0, -0.2, 1.0)
83 | glVertex3f(-1.0, -0.2, 1.0)
84 | glVertex3f(-1.0, -0.2, -1.0)
85 | glVertex3f(1.0, -0.2, -1.0)
86 |
87 | glColor3f(1.0, 0.0, 0.0)
88 | glVertex3f(1.0, 0.2, 1.0)
89 | glVertex3f(-1.0, 0.2, 1.0)
90 | glVertex3f(-1.0, -0.2, 1.0)
91 | glVertex3f(1.0, -0.2, 1.0)
92 |
93 | glColor3f(1.0, 1.0, 0.0)
94 | glVertex3f(1.0, -0.2, -1.0)
95 | glVertex3f(-1.0, -0.2, -1.0)
96 | glVertex3f(-1.0, 0.2, -1.0)
97 | glVertex3f(1.0, 0.2, -1.0)
98 |
99 | glColor3f(0.0, 0.0, 1.0)
100 | glVertex3f(-1.0, 0.2, 1.0)
101 | glVertex3f(-1.0, 0.2, -1.0)
102 | glVertex3f(-1.0, -0.2, -1.0)
103 | glVertex3f(-1.0, -0.2, 1.0)
104 |
105 | glColor3f(1.0, 0.0, 1.0)
106 | glVertex3f(1.0, 0.2, -1.0)
107 | glVertex3f(1.0, 0.2, 1.0)
108 | glVertex3f(1.0, -0.2, 1.0)
109 | glVertex3f(1.0, -0.2, -1.0)
110 | glEnd()
111 |
112 |
113 | def drawText(position, textString, size):
114 | font = pygame.font.SysFont("Courier", size, True)
115 | textSurface = font.render(textString, True, (255, 255, 255, 255), (0, 0, 0, 255))
116 | textData = pygame.image.tostring(textSurface, "RGBA", True)
117 | glRasterPos3d(*position)
118 | glDrawPixels(textSurface.get_width(), textSurface.get_height(), GL_RGBA, GL_UNSIGNED_BYTE, textData)
119 |
120 |
121 | def quat_to_ypr(q):
122 | yaw = math.atan2(2.0 * (q[1] * q[2] + q[0] * q[3]), q[0] * q[0] + q[1] * q[1] - q[2] * q[2] - q[3] * q[3])
123 | pitch = -math.sin(2.0 * (q[1] * q[3] - q[0] * q[2]))
124 | roll = math.atan2(2.0 * (q[0] * q[1] + q[2] * q[3]), q[0] * q[0] - q[1] * q[1] - q[2] * q[2] + q[3] * q[3])
125 | pitch *= 180.0 / math.pi
126 | yaw *= 180.0 / math.pi
127 | # yaw -= -0.13 # Declination at Chandrapur, Maharashtra is - 0 degress 13 min
128 | roll *= 180.0 / math.pi
129 | return [yaw, pitch, roll]
130 |
131 |
132 | if __name__ == '__main__':
133 | main()
134 |
--------------------------------------------------------------------------------
/sample_preds.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "i": 0,
4 | "age_true": 32,
5 | "pitch_true": -4.77,
6 | "roll_true": 1.15,
7 | "yaw_true": -26.22,
8 | "beauty_true": 57.96,
9 | "expression_true": "none",
10 | "face_prob_true": 1,
11 | "face_shape_true": "oval",
12 | "face_type_true": "human",
13 | "gender_true": "female",
14 | "glasses_true": "none",
15 | "race_true": "white",
16 | "age_out": 31,
17 | "pitch_out": -5.58,
18 | "roll_out": 0.83,
19 | "yaw_out": -24.83,
20 | "beauty_out": 47.2,
21 | "expression_out": "none",
22 | "gender_out": "female",
23 | "glasses_out": "none",
24 | "race_out": "white"
25 | },
26 | {
27 | "i": 1,
28 | "age_true": 31,
29 | "pitch_true": 13.28,
30 | "roll_true": -5.81,
31 | "yaw_true": -18.85,
32 | "beauty_true": 65.91,
33 | "expression_true": "none",
34 | "face_prob_true": 1,
35 | "face_shape_true": "oval",
36 | "face_type_true": "human",
37 | "gender_true": "male",
38 | "glasses_true": "none",
39 | "race_true": "white",
40 | "age_out": 32,
41 | "pitch_out": 10.87,
42 | "roll_out": -4.92,
43 | "yaw_out": -20.07,
44 | "beauty_out": 66.32,
45 | "expression_out": "none",
46 | "gender_out": "male",
47 | "glasses_out": "none",
48 | "race_out": "white"
49 | },
50 | {
51 | "i": 2,
52 | "age_true": 42,
53 | "pitch_true": 13.01,
54 | "roll_true": -0.03,
55 | "yaw_true": -16.77,
56 | "beauty_true": 50.19,
57 | "expression_true": "none",
58 | "face_prob_true": 1,
59 | "face_shape_true": "round",
60 | "face_type_true": "human",
61 | "gender_true": "male",
62 | "glasses_true": "none",
63 | "race_true": "white",
64 | "age_out": 38,
65 | "pitch_out": 12.82,
66 | "roll_out": -0.2,
67 | "yaw_out": -12.13,
68 | "beauty_out": 35.49,
69 | "expression_out": "none",
70 | "gender_out": "male",
71 | "glasses_out": "none",
72 | "race_out": "white"
73 | },
74 | {
75 | "i": 3,
76 | "age_true": 23,
77 | "pitch_true": 5.51,
78 | "roll_true": -7.73,
79 | "yaw_true": 18.73,
80 | "beauty_true": 45.36,
81 | "expression_true": "none",
82 | "face_prob_true": 1,
83 | "face_shape_true": "round",
84 | "face_type_true": "human",
85 | "gender_true": "female",
86 | "glasses_true": "sun",
87 | "race_true": "white",
88 | "age_out": 22,
89 | "pitch_out": 4.57,
90 | "roll_out": -7.73,
91 | "yaw_out": 23.17,
92 | "beauty_out": 43.42,
93 | "expression_out": "none",
94 | "gender_out": "female",
95 | "glasses_out": "none",
96 | "race_out": "white"
97 | },
98 | {
99 | "i": 4,
100 | "age_true": 37,
101 | "pitch_true": 7.48,
102 | "roll_true": -6.35,
103 | "yaw_true": -0.35,
104 | "beauty_true": 62.51,
105 | "expression_true": "none",
106 | "face_prob_true": 1,
107 | "face_shape_true": "oval",
108 | "face_type_true": "human",
109 | "gender_true": "male",
110 | "glasses_true": "none",
111 | "race_true": "white",
112 | "age_out": 34,
113 | "pitch_out": 8.17,
114 | "roll_out": -5.39,
115 | "yaw_out": -0.97,
116 | "beauty_out": 60.92,
117 | "expression_out": "none",
118 | "gender_out": "male",
119 | "glasses_out": "none",
120 | "race_out": "white"
121 | },
122 | {
123 | "i": 5,
124 | "age_true": 28,
125 | "pitch_true": 7.41,
126 | "roll_true": 12.21,
127 | "yaw_true": -38.69,
128 | "beauty_true": 48.13,
129 | "expression_true": "none",
130 | "face_prob_true": 1,
131 | "face_shape_true": "oval",
132 | "face_type_true": "human",
133 | "gender_true": "female",
134 | "glasses_true": "none",
135 | "race_true": "white",
136 | "age_out": 28,
137 | "pitch_out": 9.68,
138 | "roll_out": 11.88,
139 | "yaw_out": -40.47,
140 | "beauty_out": 49.96,
141 | "expression_out": "none",
142 | "gender_out": "female",
143 | "glasses_out": "none",
144 | "race_out": "white"
145 | },
146 | {
147 | "i": 6,
148 | "age_true": 37,
149 | "pitch_true": 17.99,
150 | "roll_true": -4.34,
151 | "yaw_true": -7.96,
152 | "beauty_true": 66.77,
153 | "expression_true": "none",
154 | "face_prob_true": 1,
155 | "face_shape_true": "heart",
156 | "face_type_true": "human",
157 | "gender_true": "female",
158 | "glasses_true": "none",
159 | "race_true": "white",
160 | "age_out": 35,
161 | "pitch_out": 17.0,
162 | "roll_out": -5.98,
163 | "yaw_out": -3.54,
164 | "beauty_out": 70.58,
165 | "expression_out": "none",
166 | "gender_out": "female",
167 | "glasses_out": "none",
168 | "race_out": "white"
169 | },
170 | {
171 | "i": 7,
172 | "age_true": 28,
173 | "pitch_true": 19.27,
174 | "roll_true": 13.28,
175 | "yaw_true": -26.46,
176 | "beauty_true": 58.69,
177 | "expression_true": "smile",
178 | "face_prob_true": 0.94,
179 | "face_shape_true": "oval",
180 | "face_type_true": "human",
181 | "gender_true": "male",
182 | "glasses_true": "none",
183 | "race_true": "white",
184 | "age_out": 30,
185 | "pitch_out": 20.61,
186 | "roll_out": 12.72,
187 | "yaw_out": -22.68,
188 | "beauty_out": 59.12,
189 | "expression_out": "smile",
190 | "gender_out": "male",
191 | "glasses_out": "none",
192 | "race_out": "white"
193 | },
194 | {
195 | "i": 8,
196 | "age_true": 45,
197 | "pitch_true": 8.26,
198 | "roll_true": -1.08,
199 | "yaw_true": 20.05,
200 | "beauty_true": 61.68,
201 | "expression_true": "none",
202 | "face_prob_true": 1,
203 | "face_shape_true": "oval",
204 | "face_type_true": "human",
205 | "gender_true": "male",
206 | "glasses_true": "none",
207 | "race_true": "white",
208 | "age_out": 46,
209 | "pitch_out": 11.58,
210 | "roll_out": -3.16,
211 | "yaw_out": 19.05,
212 | "beauty_out": 56.29,
213 | "expression_out": "none",
214 | "gender_out": "male",
215 | "glasses_out": "none",
216 | "race_out": "white"
217 | },
218 | {
219 | "i": 9,
220 | "age_true": 34,
221 | "pitch_true": 18.41,
222 | "roll_true": -0.76,
223 | "yaw_true": -5.72,
224 | "beauty_true": 55.57,
225 | "expression_true": "none",
226 | "face_prob_true": 1,
227 | "face_shape_true": "oval",
228 | "face_type_true": "human",
229 | "gender_true": "male",
230 | "glasses_true": "none",
231 | "race_true": "white",
232 | "age_out": 34,
233 | "pitch_out": 17.02,
234 | "roll_out": -1.11,
235 | "yaw_out": -3.17,
236 | "beauty_out": 62.15,
237 | "expression_out": "none",
238 | "gender_out": "male",
239 | "glasses_out": "none",
240 | "race_out": "white"
241 | }
242 | ]
--------------------------------------------------------------------------------
/screenshot.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/foamliu/Face-Attributes-Mobile/5ad6186312308f95495a6bf17e9fa9b4f4f4604f/screenshot.jpg
--------------------------------------------------------------------------------
/test_angles.py:
--------------------------------------------------------------------------------
1 | import pickle
2 | import random
3 |
4 | import cv2 as cv
5 |
6 | from config import im_size, pickle_file_landmarks, train_ratio
7 | from utils import crop_image
8 | from utils_aip import get_face_attributes
9 |
10 |
11 | def save_images(full_path, i, bbox):
12 | img = cv.imread(full_path)
13 | img = crop_image(img, bbox)
14 | img = cv.resize(img, (im_size, im_size))
15 | img_path1 = 'images/img_norm_{}.jpg'.format(i)
16 | cv.imwrite(img_path1, img)
17 |
18 | img = cv.flip(img, 1)
19 | img_path2 = 'images/img_flip_{}.jpg'.format(i)
20 | cv.imwrite(img_path2, img)
21 | return img_path1, img_path2
22 |
23 |
24 | if __name__ == "__main__":
25 | with open(pickle_file_landmarks, 'rb') as file:
26 | data = pickle.load(file)
27 |
28 | samples = data['samples']
29 |
30 | num_samples = len(samples)
31 | num_train = int(train_ratio * num_samples)
32 | samples = samples[num_train:]
33 | samples = random.sample(samples, 10)
34 |
35 | for i, sample in enumerate(samples):
36 | full_path = sample['full_path']
37 | bbox = sample['bboxes'][0]
38 | print(full_path)
39 | img_path1, img_path2 = save_images(full_path, i, bbox)
40 |
41 | attr = get_face_attributes(img_path1)
42 | if attr:
43 | print(attr['angle'])
44 |
45 | attr = get_face_attributes(img_path2)
46 | if attr:
47 | print(attr['angle'])
48 |
--------------------------------------------------------------------------------
/train.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | import torch
3 | from torch import nn
4 | from torch.utils.tensorboard import SummaryWriter
5 |
6 | from config import device, grad_clip, print_freq, loss_ratio
7 | from data_gen import FaceAttributesDataset
8 | from models import FaceAttributeModel
9 | from utils import parse_args, save_checkpoint, AverageMeter, clip_gradient, get_logger, accuracy, adjust_learning_rate
10 |
11 |
12 | def train_net(args):
13 | torch.manual_seed(7)
14 | np.random.seed(7)
15 | checkpoint = args.checkpoint
16 | start_epoch = 0
17 | best_loss = float('inf')
18 | writer = SummaryWriter()
19 | epochs_since_improvement = 0
20 |
21 | # Initialize / load checkpoint
22 | if checkpoint is None:
23 | model = FaceAttributeModel()
24 | model = nn.DataParallel(model)
25 |
26 | if args.optimizer == 'sgd':
27 | optimizer = torch.optim.SGD([{'params': model.parameters()}],
28 | lr=args.lr, momentum=args.mom, weight_decay=args.weight_decay)
29 | else:
30 | optimizer = torch.optim.Adam([{'params': model.parameters()}],
31 | lr=args.lr, weight_decay=args.weight_decay)
32 |
33 | else:
34 | checkpoint = torch.load(checkpoint)
35 | start_epoch = checkpoint['epoch'] + 1
36 | epochs_since_improvement = checkpoint['epochs_since_improvement']
37 | model = checkpoint['model']
38 | optimizer = checkpoint['optimizer']
39 |
40 | logger = get_logger()
41 |
42 | # Move to GPU, if available
43 | model = model.to(device)
44 |
45 | # Loss function
46 | L1Loss = nn.L1Loss().to(device)
47 | CrossEntropyLoss = nn.CrossEntropyLoss().to(device)
48 |
49 | # Custom dataloaders
50 | train_dataset = FaceAttributesDataset('train')
51 | train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=args.batch_size, shuffle=True, num_workers=4)
52 | valid_dataset = FaceAttributesDataset('valid')
53 | valid_loader = torch.utils.data.DataLoader(valid_dataset, batch_size=args.batch_size, shuffle=False, num_workers=4)
54 |
55 | # scheduler = StepLR(optimizer, step_size=args.lr_step, gamma=0.1)
56 |
57 | # Epochs
58 | for epoch in range(start_epoch, args.end_epoch):
59 | # Decay learning rate if there is no improvement for 8 consecutive epochs, and terminate training after 20
60 | if epochs_since_improvement == 20:
61 | break
62 | if epochs_since_improvement > 0 and epochs_since_improvement % 8 == 0:
63 | adjust_learning_rate(optimizer, 0.8)
64 |
65 | # One epoch's training
66 | train_loss = train(train_loader=train_loader,
67 | model=model,
68 | criterions=(L1Loss, CrossEntropyLoss),
69 | optimizer=optimizer,
70 | epoch=epoch,
71 | logger=logger)
72 |
73 | writer.add_scalar('model/train_Loss', train_loss, epoch)
74 |
75 | # One epoch's validation
76 | valid_loss = valid(valid_loader=valid_loader,
77 | model=model,
78 | criterions=(L1Loss, CrossEntropyLoss),
79 | logger=logger)
80 |
81 | writer.add_scalar('model/valid_Loss', valid_loss, epoch)
82 |
83 | # Check if there was an improvement
84 | is_best = valid_loss < best_loss
85 | best_loss = min(valid_loss, best_loss)
86 | if not is_best:
87 | epochs_since_improvement += 1
88 | print("\nEpochs since last improvement: %d\n" % (epochs_since_improvement,))
89 | else:
90 | epochs_since_improvement = 0
91 |
92 | # Save checkpoint
93 | save_checkpoint(epoch, epochs_since_improvement, model, optimizer, best_loss, is_best)
94 |
95 |
96 | def train(train_loader, model, criterions, optimizer, epoch, logger):
97 | model.train() # train mode (dropout and batchnorm is used)
98 |
99 | losses = AverageMeter()
100 |
101 | reg_losses = AverageMeter()
102 | expression_accs = AverageMeter()
103 | gender_accs = AverageMeter()
104 | glasses_accs = AverageMeter()
105 | race_accs = AverageMeter()
106 |
107 | L1Loss, CrossEntropyLoss = criterions
108 |
109 | # Batches
110 | for i, (img, reg, expression, gender, glasses, race) in enumerate(train_loader):
111 | # Move to GPU, if available
112 | img = img.to(device)
113 | reg_label = reg.type(torch.FloatTensor).to(device) # [N, 5]
114 | expression_label = expression.type(torch.LongTensor).to(device) # [N, 3]
115 | gender_label = gender.type(torch.LongTensor).to(device) # [N, 2]
116 | glasses_label = glasses.type(torch.LongTensor).to(device) # [N, 3]
117 | race_label = race.type(torch.LongTensor).to(device) # [N, 4]
118 |
119 | # Forward prop.
120 | reg_out, expression_out, gender_out, glasses_out, race_out = model(img) # embedding => [N, 17]
121 |
122 | # Calculate loss
123 | reg_loss = L1Loss(reg_out, reg_label) * loss_ratio
124 | expression_loss = CrossEntropyLoss(expression_out, expression_label)
125 | gender_loss = CrossEntropyLoss(gender_out, gender_label)
126 | glasses_loss = CrossEntropyLoss(glasses_out, glasses_label)
127 | race_loss = CrossEntropyLoss(race_out, race_label)
128 |
129 | loss = reg_loss + expression_loss + gender_loss + glasses_loss + race_loss
130 |
131 | # Back prop.
132 | optimizer.zero_grad()
133 | loss.backward()
134 |
135 | # Clip gradients
136 | clip_gradient(optimizer, grad_clip)
137 |
138 | # Update weights
139 | optimizer.step()
140 |
141 | # Keep track of metrics
142 | losses.update(loss.item())
143 |
144 | reg_losses.update(reg_loss.item())
145 | expression_accuracy = accuracy(expression_out, expression_label)
146 | expression_accs.update(expression_accuracy)
147 | gender_accuracy = accuracy(gender_out, gender_label)
148 | gender_accs.update(gender_accuracy)
149 | glasses_accuracy = accuracy(glasses_out, glasses_label)
150 | glasses_accs.update(glasses_accuracy)
151 | race_accuracy = accuracy(race_out, race_label)
152 | race_accs.update(race_accuracy)
153 |
154 | # Print status
155 |
156 | if i % print_freq == 0:
157 | status = 'Epoch: [{0}][{1}/{2}]\t' \
158 | 'Loss {loss.val:.4f} ({loss.avg:.4f})\t' \
159 | 'Reg Loss {reg_loss.val:.4f} ({reg_loss.avg:.4f})\t' \
160 | 'Expression Accuracy {expression_acc.val:.4f} ({expression_acc.avg:.4f})\t' \
161 | 'Gender Accuracy {gender_acc.val:.4f} ({gender_acc.avg:.4f})\t' \
162 | 'Glasses Accuracy {expression_acc.val:.4f} ({expression_acc.avg:.4f})\t' \
163 | 'Race Accuracy {expression_acc.val:.4f} ({expression_acc.avg:.4f})\t'.format(epoch, i,
164 | len(train_loader),
165 | loss=losses,
166 | reg_loss=reg_losses,
167 | expression_acc=expression_accs,
168 | gender_acc=gender_accs,
169 | glasses_acc=glasses_accs,
170 | race_acc=race_accs)
171 | logger.info(status)
172 |
173 | return losses.avg
174 |
175 |
176 | def valid(valid_loader, model, criterions, logger):
177 | model.eval() # eval mode (dropout and batchnorm is NOT used)
178 |
179 | losses = AverageMeter()
180 |
181 | reg_losses = AverageMeter()
182 | expression_accs = AverageMeter()
183 | gender_accs = AverageMeter()
184 | glasses_accs = AverageMeter()
185 | race_accs = AverageMeter()
186 |
187 | L1Loss, CrossEntropyLoss = criterions
188 |
189 | # Batches
190 | for i, (img, reg, expression, gender, glasses, race) in enumerate(valid_loader):
191 | # Move to GPU, if available
192 | img = img.to(device)
193 | reg_label = reg.type(torch.FloatTensor).to(device) # [N, 5]
194 | expression_label = expression.type(torch.LongTensor).to(device) # [N, 3]
195 | gender_label = gender.type(torch.LongTensor).to(device) # [N, 2]
196 | glasses_label = glasses.type(torch.LongTensor).to(device) # [N, 3]
197 | race_label = race.type(torch.LongTensor).to(device) # [N, 4]
198 |
199 | # Forward prop.
200 | reg_out, expression_out, gender_out, glasses_out, race_out = model(img)
201 |
202 | # Calculate loss
203 | reg_loss = L1Loss(reg_out, reg_label) * loss_ratio
204 | expression_loss = CrossEntropyLoss(expression_out, expression_label)
205 | gender_loss = CrossEntropyLoss(gender_out, gender_label)
206 | glasses_loss = CrossEntropyLoss(glasses_out, glasses_label)
207 | race_loss = CrossEntropyLoss(race_out, race_label)
208 |
209 | loss = reg_loss + expression_loss + gender_loss + glasses_loss + race_loss
210 |
211 | # Keep track of metrics
212 | losses.update(loss.item())
213 |
214 | reg_losses.update(reg_loss.item())
215 | expression_accuracy = accuracy(expression_out, expression_label)
216 | expression_accs.update(expression_accuracy)
217 | gender_accuracy = accuracy(gender_out, gender_label)
218 | gender_accs.update(gender_accuracy)
219 | glasses_accuracy = accuracy(glasses_out, glasses_label)
220 | glasses_accs.update(glasses_accuracy)
221 | race_accuracy = accuracy(race_out, race_label)
222 | race_accs.update(race_accuracy)
223 |
224 | # Print status
225 | status = 'Validation: Loss {loss.avg:.4f}\t' \
226 | 'Reg Loss {reg_loss.val:.4f} ({reg_loss.avg:.4f})\t' \
227 | 'Expression Accuracy {expression_acc.val:.4f} ({expression_acc.avg:.4f})\t' \
228 | 'Gender Accuracy {gender_acc.val:.4f} ({gender_acc.avg:.4f})\t' \
229 | 'Glasses Accuracy {expression_acc.val:.4f} ({expression_acc.avg:.4f})\t' \
230 | 'Race Accuracy {expression_acc.val:.4f} ({expression_acc.avg:.4f})\n'.format(loss=losses,
231 | reg_loss=reg_losses,
232 | expression_acc=expression_accs,
233 | gender_acc=gender_accs,
234 | glasses_acc=glasses_accs,
235 | race_acc=race_accs)
236 |
237 | logger.info(status)
238 |
239 | return losses.avg
240 |
241 |
242 | def main():
243 | global args
244 | args = parse_args()
245 | train_net(args)
246 |
247 |
248 | if __name__ == '__main__':
249 | main()
250 |
--------------------------------------------------------------------------------
/utils.py:
--------------------------------------------------------------------------------
1 | import argparse
2 | import logging
3 |
4 | import torch
5 |
6 | from config import expression_dict, face_shape_dict, face_type_dict, gender_dict, glasses_dict, race_dict
7 |
8 |
9 | def clip_gradient(optimizer, grad_clip):
10 | """
11 | Clips gradients computed during backpropagation to avoid explosion of gradients.
12 | :param optimizer: optimizer with the gradients to be clipped
13 | :param grad_clip: clip value
14 | """
15 | for group in optimizer.param_groups:
16 | for param in group['params']:
17 | if param.grad is not None:
18 | param.grad.data.clamp_(-grad_clip, grad_clip)
19 |
20 |
21 | def save_checkpoint(epoch, epochs_since_improvement, model, optimizer, loss, is_best):
22 | state = {'epoch': epoch,
23 | 'epochs_since_improvement': epochs_since_improvement,
24 | 'loss': loss,
25 | 'model': model,
26 | 'optimizer': optimizer}
27 | # filename = 'checkpoint_' + str(epoch) + '_' + str(loss) + '.tar'
28 | filename = 'checkpoint.tar'
29 | torch.save(state, filename)
30 | # If this checkpoint is the best so far, store a copy so it doesn't get overwritten by a worse checkpoint
31 | if is_best:
32 | torch.save(state, 'BEST_checkpoint.tar')
33 |
34 |
35 | class AverageMeter(object):
36 | """
37 | Keeps track of most recent, average, sum, and count of a metric.
38 | """
39 |
40 | def __init__(self):
41 | self.reset()
42 |
43 | def reset(self):
44 | self.val = 0
45 | self.avg = 0
46 | self.sum = 0
47 | self.count = 0
48 |
49 | def update(self, val, n=1):
50 | self.val = val
51 | self.sum += val * n
52 | self.count += n
53 | self.avg = self.sum / self.count
54 |
55 |
56 | class LossMeterBag(object):
57 |
58 | def __init__(self, name_list):
59 | self.meter_dict = dict()
60 | self.name_list = name_list
61 | for name in self.name_list:
62 | self.meter_dict[name] = AverageMeter()
63 |
64 | def update(self, val_list):
65 | for i, name in enumerate(self.name_list):
66 | val = val_list[i]
67 | self.meter_dict[name].update(val)
68 |
69 | def __str__(self):
70 | ret = ''
71 | for name in self.name_list:
72 | ret += '{0}:\t {1:.4f}({2:.4f})\t'.format(name, self.meter_dict[name].val, self.meter_dict[name].avg)
73 |
74 | return ret
75 |
76 |
77 | def adjust_learning_rate(optimizer, shrink_factor):
78 | """
79 | Shrinks learning rate by a specified factor.
80 | :param optimizer: optimizer whose learning rate must be shrunk.
81 | :param shrink_factor: factor in interval (0, 1) to multiply learning rate with.
82 | """
83 |
84 | print("\nDECAYING learning rate.")
85 | for param_group in optimizer.param_groups:
86 | param_group['lr'] = param_group['lr'] * shrink_factor
87 | print("The new learning rate is %f\n" % (optimizer.param_groups[0]['lr'],))
88 |
89 |
90 | def accuracy(scores, targets, k=1):
91 | batch_size = targets.size(0)
92 | _, ind = scores.topk(k, 1, True, True)
93 | correct = ind.eq(targets.view(-1, 1).expand_as(ind))
94 | correct_total = correct.view(-1).float().sum() # 0D tensor
95 | return correct_total.item() * (100.0 / batch_size)
96 |
97 |
98 | def parse_args():
99 | parser = argparse.ArgumentParser(description='Train face network')
100 | # general
101 | parser.add_argument('--end-epoch', type=int, default=1000, help='training epoch size.')
102 | parser.add_argument('--lr', type=float, default=0.001, help='start learning rate')
103 | parser.add_argument('--lr-step', type=int, default=10, help='period of learning rate decay')
104 | parser.add_argument('--optimizer', default='sgd', help='optimizer')
105 | parser.add_argument('--weight-decay', type=float, default=0.0005, help='weight decay')
106 | parser.add_argument('--mom', type=float, default=0.9, help='momentum')
107 | parser.add_argument('--batch-size', type=int, default=32, help='batch size in each context')
108 | parser.add_argument('--checkpoint', type=str, default=None, help='checkpoint')
109 | parser.add_argument('--pretrained', type=bool, default=False, help='pretrained model')
110 | args = parser.parse_args()
111 | return args
112 |
113 |
114 | def get_logger():
115 | logger = logging.getLogger()
116 | handler = logging.StreamHandler()
117 | formatter = logging.Formatter("%(asctime)s %(levelname)s \t%(message)s")
118 | handler.setFormatter(formatter)
119 | logger.addHandler(handler)
120 | logger.setLevel(logging.DEBUG)
121 | return logger
122 |
123 |
124 | def idx2name(idx, tag):
125 | name = None
126 | if tag == 'expression':
127 | name = expression_dict[idx]
128 | elif tag == 'face_shape':
129 | name = face_shape_dict[idx]
130 | elif tag == 'face_type':
131 | name = face_type_dict[idx]
132 | elif tag == 'gender':
133 | name = gender_dict[idx]
134 | elif tag == 'glasses':
135 | name = glasses_dict[idx]
136 | elif tag == 'race':
137 | name = race_dict[idx]
138 | return name
139 |
140 |
141 | def name2idx(name):
142 | lookup_table = {'none': 0, 'smile': 1, 'laugh': 2,
143 | 'square': 0, 'oval': 1, 'heart': 2, 'round': 3, 'triangle': 4,
144 | 'human': 0, 'cartoon': 1,
145 | 'female': 0, 'male': 1,
146 | 'sun': 1, 'common': 2,
147 | 'yellow': 0, 'white': 1, 'black': 2, 'arabs': 3}
148 |
149 | return lookup_table[name]
150 |
151 |
152 | def crop_image(img, bbox):
153 | # print(bbox.shape)
154 | x1 = max(int(round(bbox[0])), 0)
155 | y1 = max(int(round(bbox[1])), 0)
156 | x2 = max(int(round(bbox[2])), 0)
157 | y2 = max(int(round(bbox[3])), 0)
158 |
159 | crop_img = img[y1:y2, x1:x2]
160 | return crop_img
161 |
162 |
163 | def ensure_folder(folder):
164 | import os
165 | if not os.path.isdir(folder):
166 | os.mkdir(folder)
167 |
--------------------------------------------------------------------------------
/utils_aip.py:
--------------------------------------------------------------------------------
1 | import base64
2 |
3 | from aip.face import AipFace
4 |
5 |
6 | def get_file_content(filePath):
7 | with open(filePath, 'rb') as fp:
8 | return fp.read()
9 |
10 |
11 | def get_face_attributes(filePath):
12 | appId = '16217748'
13 | apiKey = 'fq8w67yHRje2Tmr1UKhD9lCs'
14 | secretKey = 'srTGstYbXL4cDmbGM8iVF7amyqFbxPfN'
15 |
16 | aipFace = AipFace(appId, apiKey, secretKey)
17 |
18 | options = {}
19 | options["face_field"] = "age,beauty,expression,faceshape,gender,glasses,race,quality,facetype"
20 | options["max_face_num"] = 1
21 | options["face_type"] = "LIVE"
22 |
23 | image = base64.b64encode(get_file_content(filePath)).decode()
24 | result = aipFace.detect(image=image, image_type="BASE64", options=options)
25 | attr = {}
26 | if result is not None and 'result' in result and result['result'] is not None:
27 | face = result['result']['face_list'][0]
28 | attr['location'] = face['location']
29 | attr['face_probability'] = face['face_probability']
30 | attr['angle'] = face['angle']
31 | attr['age'] = face['age']
32 | attr['beauty'] = face['beauty']
33 | attr['expression'] = face['expression']
34 | attr['face_shape'] = face['face_shape']
35 | attr['gender'] = face['gender']
36 | attr['glasses'] = face['glasses']
37 | attr['race'] = face['race']
38 | attr['quality'] = face['quality']
39 | attr['face_type'] = face['face_type']
40 | return attr
41 |
--------------------------------------------------------------------------------