├── .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 | ![image](https://github.com/foamliu/Face-Attributes-v2/raw/master/images/gender_dist.png) 17 | 18 | ### Age 19 | 20 | ![image](https://github.com/foamliu/Face-Attributes-v2/raw/master/images/age_dist.png) 21 | 22 | ### Euler angles: 23 | 24 | ![image](https://github.com/foamliu/Face-Attributes-v2/raw/master/images/euler_angles.png) 25 | 26 | Pitch: 27 | 28 | ![image](https://github.com/foamliu/Face-Attributes-v2/raw/master/images/angle_pitch_dist.png) 29 | 30 | Yaw: 31 | 32 | ![image](https://github.com/foamliu/Face-Attributes-v2/raw/master/images/angle_yaw_dist.png) 33 | 34 | Roll: 35 | 36 | ![image](https://github.com/foamliu/Face-Attributes-v2/raw/master/images/angle_roll_dist.png) 37 | 38 | ### Beauty 39 | 40 | ![image](https://github.com/foamliu/Face-Attributes-v2/raw/master/images/beauty_dist.png) 41 | 42 | ### Expression 43 | 44 | ![image](https://github.com/foamliu/Face-Attributes-v2/raw/master/images/expression_dist.png) 45 | 46 | ### Face shape 47 | 48 | ![image](https://github.com/foamliu/Face-Attributes-v2/raw/master/images/face_shape_dist.png) 49 | 50 | ### Face type 51 | 52 | ![image](https://github.com/foamliu/Face-Attributes-v2/raw/master/images/face_type_dist.png) 53 | 54 | ### Glasses 55 | 56 | ![image](https://github.com/foamliu/Face-Attributes-v2/raw/master/images/glasses_dist.png) 57 | 58 | ### Race 59 | 60 | ![image](https://github.com/foamliu/Face-Attributes-v2/raw/master/images/race_dist.png) 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 | ![image](https://github.com/foamliu/Face-Attributes-v2/raw/master/images/learning_curve.jpg) 80 | 81 | Image | Aligned | Out | True | 82 | |---|---|---|---| 83 | |![image](https://github.com/foamliu/Face-Attributes-v2/raw/master/images/0_raw.jpg)|![image](https://github.com/foamliu/Face-Attributes-v2/raw/master/images/0_img.jpg)|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 | |![image](https://github.com/foamliu/Face-Attributes-v2/raw/master/images/1_raw.jpg)|![image](https://github.com/foamliu/Face-Attributes-v2/raw/master/images/1_img.jpg)|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 | |![image](https://github.com/foamliu/Face-Attributes-v2/raw/master/images/2_raw.jpg)|![image](https://github.com/foamliu/Face-Attributes-v2/raw/master/images/2_img.jpg)|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 | |![image](https://github.com/foamliu/Face-Attributes-v2/raw/master/images/3_raw.jpg)|![image](https://github.com/foamliu/Face-Attributes-v2/raw/master/images/3_img.jpg)|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 | |![image](https://github.com/foamliu/Face-Attributes-v2/raw/master/images/4_raw.jpg)|![image](https://github.com/foamliu/Face-Attributes-v2/raw/master/images/4_img.jpg)|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 | |![image](https://github.com/foamliu/Face-Attributes-v2/raw/master/images/5_raw.jpg)|![image](https://github.com/foamliu/Face-Attributes-v2/raw/master/images/5_img.jpg)|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 | |![image](https://github.com/foamliu/Face-Attributes-v2/raw/master/images/6_raw.jpg)|![image](https://github.com/foamliu/Face-Attributes-v2/raw/master/images/6_img.jpg)|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 | |![image](https://github.com/foamliu/Face-Attributes-v2/raw/master/images/7_raw.jpg)|![image](https://github.com/foamliu/Face-Attributes-v2/raw/master/images/7_img.jpg)|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 | |![image](https://github.com/foamliu/Face-Attributes-v2/raw/master/images/8_raw.jpg)|![image](https://github.com/foamliu/Face-Attributes-v2/raw/master/images/8_img.jpg)|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 | |![image](https://github.com/foamliu/Face-Attributes-v2/raw/master/images/9_raw.jpg)|![image](https://github.com/foamliu/Face-Attributes-v2/raw/master/images/9_img.jpg)|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 | ![image](https://github.com/foamliu/Face-Attributes-v2/raw/master/images/gender_dist.png) 17 | 18 | ### Age 19 | 20 | ![image](https://github.com/foamliu/Face-Attributes-v2/raw/master/images/age_dist.png) 21 | 22 | ### Euler angles: 23 | 24 | ![image](https://github.com/foamliu/Face-Attributes-v2/raw/master/images/euler_angles.png) 25 | 26 | Pitch: 27 | 28 | ![image](https://github.com/foamliu/Face-Attributes-v2/raw/master/images/angle_pitch_dist.png) 29 | 30 | Yaw: 31 | 32 | ![image](https://github.com/foamliu/Face-Attributes-v2/raw/master/images/angle_yaw_dist.png) 33 | 34 | Roll: 35 | 36 | ![image](https://github.com/foamliu/Face-Attributes-v2/raw/master/images/angle_roll_dist.png) 37 | 38 | ### Beauty 39 | 40 | ![image](https://github.com/foamliu/Face-Attributes-v2/raw/master/images/beauty_dist.png) 41 | 42 | ### Expression 43 | 44 | ![image](https://github.com/foamliu/Face-Attributes-v2/raw/master/images/expression_dist.png) 45 | 46 | ### Face shape 47 | 48 | ![image](https://github.com/foamliu/Face-Attributes-v2/raw/master/images/face_shape_dist.png) 49 | 50 | ### Face type 51 | 52 | ![image](https://github.com/foamliu/Face-Attributes-v2/raw/master/images/face_type_dist.png) 53 | 54 | ### Glasses 55 | 56 | ![image](https://github.com/foamliu/Face-Attributes-v2/raw/master/images/glasses_dist.png) 57 | 58 | ### Race 59 | 60 | ![image](https://github.com/foamliu/Face-Attributes-v2/raw/master/images/race_dist.png) 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 | ![image](https://github.com/foamliu/Face-Attributes-v2/raw/master/images/learning_curve.jpg) 80 | 81 | Image | Aligned | Out | True | 82 | |---|---|---|---| 83 | |![image](https://github.com/foamliu/Face-Attributes-v2/raw/master/images/0_raw.jpg)|![image](https://github.com/foamliu/Face-Attributes-v2/raw/master/images/0_img.jpg)|$(result_out_0)|$(result_true_0)| 84 | |![image](https://github.com/foamliu/Face-Attributes-v2/raw/master/images/1_raw.jpg)|![image](https://github.com/foamliu/Face-Attributes-v2/raw/master/images/1_img.jpg)|$(result_out_1)|$(result_true_1)| 85 | |![image](https://github.com/foamliu/Face-Attributes-v2/raw/master/images/2_raw.jpg)|![image](https://github.com/foamliu/Face-Attributes-v2/raw/master/images/2_img.jpg)|$(result_out_2)|$(result_true_2)| 86 | |![image](https://github.com/foamliu/Face-Attributes-v2/raw/master/images/3_raw.jpg)|![image](https://github.com/foamliu/Face-Attributes-v2/raw/master/images/3_img.jpg)|$(result_out_3)|$(result_true_3)| 87 | |![image](https://github.com/foamliu/Face-Attributes-v2/raw/master/images/4_raw.jpg)|![image](https://github.com/foamliu/Face-Attributes-v2/raw/master/images/4_img.jpg)|$(result_out_4)|$(result_true_4)| 88 | |![image](https://github.com/foamliu/Face-Attributes-v2/raw/master/images/5_raw.jpg)|![image](https://github.com/foamliu/Face-Attributes-v2/raw/master/images/5_img.jpg)|$(result_out_5)|$(result_true_5)| 89 | |![image](https://github.com/foamliu/Face-Attributes-v2/raw/master/images/6_raw.jpg)|![image](https://github.com/foamliu/Face-Attributes-v2/raw/master/images/6_img.jpg)|$(result_out_6)|$(result_true_6)| 90 | |![image](https://github.com/foamliu/Face-Attributes-v2/raw/master/images/7_raw.jpg)|![image](https://github.com/foamliu/Face-Attributes-v2/raw/master/images/7_img.jpg)|$(result_out_7)|$(result_true_7)| 91 | |![image](https://github.com/foamliu/Face-Attributes-v2/raw/master/images/8_raw.jpg)|![image](https://github.com/foamliu/Face-Attributes-v2/raw/master/images/8_img.jpg)|$(result_out_8)|$(result_true_8)| 92 | |![image](https://github.com/foamliu/Face-Attributes-v2/raw/master/images/9_raw.jpg)|![image](https://github.com/foamliu/Face-Attributes-v2/raw/master/images/9_img.jpg)|$(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 | --------------------------------------------------------------------------------