├── FaceBoxes_epoch_90.pth ├── LICENSE ├── LabelFaceBox.py ├── MyTrain.py ├── README.md ├── data ├── AnimeData.py ├── __init__.py ├── __pycache__ │ ├── AnimeData.cpython-36.pyc │ ├── __init__.cpython-36.pyc │ ├── config.cpython-36.pyc │ └── data_augment.cpython-36.pyc ├── config.py └── data_augment.py ├── eval.py ├── faceboxes ├── layers ├── __init__.py ├── __pycache__ │ └── __init__.cpython-36.pyc ├── functions │ ├── __pycache__ │ │ └── prior_box.cpython-36.pyc │ └── prior_box.py └── modules │ ├── __init__.py │ ├── __pycache__ │ ├── __init__.cpython-36.pyc │ └── multibox_loss.cpython-36.pyc │ └── multibox_loss.py ├── make.sh ├── models ├── __init__.py ├── __pycache__ │ ├── __init__.cpython-36.pyc │ └── faceboxes.cpython-36.pyc └── faceboxes.py ├── out.png ├── utils ├── __init__.py ├── __pycache__ │ ├── __init__.cpython-36.pyc │ ├── box_utils.cpython-36.pyc │ ├── nms_wrapper.cpython-36.pyc │ └── timer.cpython-36.pyc ├── box_utils.py ├── build.py ├── build │ └── temp.linux-x86_64-3.6 │ │ └── nms │ │ ├── cpu_nms.o │ │ ├── gpu_nms.o │ │ └── nms_kernel.o ├── nms │ ├── __init__.py │ ├── __pycache__ │ │ └── __init__.cpython-36.pyc │ ├── cpu_nms.c │ ├── cpu_nms.cpython-36m-x86_64-linux-gnu.so │ ├── cpu_nms.pyx │ ├── gpu_nms.cpp │ ├── gpu_nms.cpython-36m-x86_64-linux-gnu.so │ ├── gpu_nms.hpp │ ├── gpu_nms.pyx │ ├── nms_kernel.cu │ └── py_cpu_nms.py ├── nms_wrapper.py └── timer.py └── weightsBK └── FaceBoxesProd.pth /FaceBoxes_epoch_90.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WynMew/AnimeFaceBoxes/025b5e0a265e971d03cf850d67a52dad2ab392c6/FaceBoxes_epoch_90.pth -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. -------------------------------------------------------------------------------- /LabelFaceBox.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import cv2 3 | import os 4 | import os.path as osp 5 | import matplotlib.pyplot as plt 6 | from matplotlib.patches import Rectangle 7 | 8 | class Annotate(object): 9 | def __init__(self): 10 | self.ax = plt.gca() 11 | self.rect = Rectangle((0,0), 1, 1) 12 | self.x0 = None 13 | self.y0 = None 14 | self.x1 = None 15 | self.y1 = None 16 | self.ax.add_patch(self.rect) 17 | self.ax.figure.canvas.mpl_connect('button_press_event', self.on_press) 18 | self.ax.figure.canvas.mpl_connect('button_release_event', self.on_release) 19 | def on_press(self, event): 20 | print('press') 21 | self.x0 = event.xdata 22 | self.y0 = event.ydata 23 | def on_release(self, event): 24 | print('release') 25 | self.x1 = event.xdata 26 | self.y1 = event.ydata 27 | self.rect.set_width(self.x1 - self.x0) 28 | self.rect.set_height(self.y1 - self.y0) 29 | self.rect.set_xy((self.x0, self.y0)) 30 | self.ax.figure.canvas.draw() 31 | 32 | def add(x, logfile): 33 | with open(logfile,"a+") as outfile: 34 | outfile.write(x + "\n") 35 | 36 | photolist = '/home/wynmew/data/downloads/danbooru2018/origAll' 37 | log = 'faceboxes' 38 | 39 | idx=[] 40 | for line in open(osp.join(photolist)): 41 | idx.append((os.path.join(line.strip()))) 42 | 43 | for i in range(len(idx)): 44 | #i=0 45 | img = idx[i] 46 | print(i, img) 47 | ims = cv2.cvtColor(cv2.imread(img), cv2.COLOR_RGB2BGR) 48 | 49 | plt.imshow(ims) 50 | a = Annotate() 51 | plt.show() 52 | if a.x0 is not None: 53 | x1, y1, x2, y2, w, h =a.x0,a.y0, a.x1, a.y1,a.x1-a.x0,a.y1-a.y0 54 | line = img +' ' + str(int(x1)) + ' ' + str(int(y1)) + ' ' + str(int(x2)) + ' ' + str(int(y2))+ ' ' + str(int(w)) + ' '+ str(int(h)) 55 | #print(img, int(x1), int(y1), int(x2), int(y2), int(w), int(h)) 56 | add(line,log) 57 | print(line) 58 | else: 59 | print(img, 'pass') 60 | -------------------------------------------------------------------------------- /MyTrain.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | import os 3 | import torch 4 | import torch.optim as optim 5 | import torch.backends.cudnn as cudnn 6 | import argparse 7 | import torch.utils.data as data 8 | from data import AnnotationTransform, AnimeDetection, detection_collate, preproc, cfg 9 | from layers.modules import MultiBoxLoss 10 | from layers.functions.prior_box import PriorBox 11 | import time 12 | import datetime 13 | import math 14 | from models.faceboxes import FaceBoxes 15 | 16 | parser = argparse.ArgumentParser(description='FaceBoxes Training') 17 | parser.add_argument('--training_dataset', default='./data/WIDER_FACE', help='Training dataset directory') 18 | parser.add_argument('-b', '--batch_size', default=8, type=int, help='Batch size for training') 19 | parser.add_argument('--num_workers', default=4, type=int, help='Number of workers used in dataloading') 20 | #parser.add_argument('--ngpu', default=1, type=int, help='gpus') 21 | parser.add_argument('--lr', '--learning-rate', default=1e-3, type=float, help='initial learning rate') 22 | parser.add_argument('--momentum', default=0.9, type=float, help='momentum') 23 | #parser.add_argument('--resume_net', default=None, help='resume net for retraining') 24 | parser.add_argument('--resume_net', default='weightsBK/FaceBoxesProd.pth', help='resume net for retraining') 25 | parser.add_argument('--resume_epoch', default=0, type=int, help='resume iter for retraining') 26 | parser.add_argument('-max', '--max_epoch', default=150, type=int, help='max epoch for retraining') 27 | parser.add_argument('--weight_decay', default=5e-4, type=float, help='Weight decay for SGD') 28 | parser.add_argument('--gamma', default=0.1, type=float, help='Gamma update for SGD') 29 | parser.add_argument('--save_folder', default='./weights/', help='Location to save checkpoint models') 30 | args = parser.parse_args() 31 | 32 | if not os.path.exists(args.save_folder): 33 | os.mkdir(args.save_folder) 34 | 35 | img_dim = 1024 # only 1024 is supported 36 | rgb_mean = (104, 117, 123) # bgr order 37 | num_classes = 2 38 | num_workers = args.num_workers 39 | batch_size = args.batch_size 40 | momentum = args.momentum 41 | weight_decay = args.weight_decay 42 | initial_lr = args.lr 43 | gamma = args.gamma 44 | max_epoch = args.max_epoch 45 | training_dataset = args.training_dataset 46 | save_folder = args.save_folder 47 | gpu_train = cfg['gpu_train'] 48 | 49 | net = FaceBoxes('train', img_dim, num_classes) 50 | print("Printing net...") 51 | print(net) 52 | 53 | filelist = 'faceboxes' 54 | 55 | if args.resume_net is not None: 56 | print('Loading resume network...') 57 | state_dict = torch.load(args.resume_net) 58 | # create new OrderedDict that does not contain `module.` 59 | from collections import OrderedDict 60 | new_state_dict = OrderedDict() 61 | for k, v in state_dict.items(): 62 | head = k[:7] 63 | if head == 'module.': 64 | name = k[7:] # remove `module.` 65 | else: 66 | name = k 67 | new_state_dict[name] = v 68 | net.load_state_dict(new_state_dict) 69 | 70 | 71 | os.environ['CUDA_VISIBLE_DEVICES']='1' 72 | device = torch.device('cuda:0' if gpu_train else 'cpu') 73 | cudnn.benchmark = True 74 | net = net.to(device) 75 | 76 | optimizer = optim.SGD(net.parameters(), lr=initial_lr, momentum=momentum, weight_decay=weight_decay) 77 | criterion = MultiBoxLoss(num_classes, 0.35, True, 0, True, 7, 0.35, False) 78 | 79 | priorbox = PriorBox(cfg, image_size=(img_dim, img_dim)) 80 | with torch.no_grad(): 81 | priors = priorbox.forward() 82 | priors = priors.to(device) 83 | 84 | 85 | def train(): 86 | net.train() 87 | epoch = 0 + args.resume_epoch 88 | print('Loading Dataset...') 89 | 90 | dataset = AnimeDetection(filelist, preproc(img_dim, rgb_mean), AnnotationTransform()) 91 | 92 | epoch_size = math.ceil(len(dataset) / batch_size) 93 | max_iter = max_epoch * epoch_size 94 | 95 | #stepvalues = (200 * epoch_size, 250 * epoch_size) 96 | stepvalues = (50 * epoch_size, 100 * epoch_size) 97 | step_index = 0 98 | 99 | if args.resume_epoch > 0: 100 | start_iter = args.resume_epoch * epoch_size 101 | else: 102 | start_iter = 0 103 | 104 | for iteration in range(start_iter, max_iter): 105 | if iteration % epoch_size == 0: 106 | # create batch iterator 107 | batch_iterator = iter(data.DataLoader(dataset, batch_size, shuffle=True, num_workers=num_workers, collate_fn=detection_collate)) 108 | if (epoch % 10 == 0 and epoch > 0) or (epoch % 5 == 0 and epoch > 200): 109 | torch.save(net.state_dict(), save_folder + 'FaceBoxes_epoch_' + str(epoch) + '.pth') 110 | epoch += 1 111 | 112 | load_t0 = time.time() 113 | if iteration in stepvalues: 114 | step_index += 1 115 | lr = adjust_learning_rate(optimizer, gamma, epoch, step_index, iteration, epoch_size) 116 | 117 | # load train data 118 | images, targets = next(batch_iterator) 119 | images = images.to(device) 120 | targets = [anno.to(device) for anno in targets] 121 | 122 | # forward 123 | out = net(images) 124 | 125 | # backprop 126 | optimizer.zero_grad() 127 | loss_l, loss_c = criterion(out, priors, targets) 128 | loss = cfg['loc_weight'] * loss_l + loss_c 129 | loss.backward() 130 | optimizer.step() 131 | load_t1 = time.time() 132 | batch_time = load_t1 - load_t0 133 | eta = int(batch_time * (max_iter - iteration)) 134 | print('{}/{}|{}/{}|{}/{}|L:{:.4f} C:{:.4f}|LR:{:.8f} |Batchtime:{:.4f}s|ETA:{}'.format(epoch, max_epoch, (iteration % epoch_size) + 1, epoch_size, iteration + 1, max_iter, loss_l.item(), loss_c.item(), lr, batch_time, str(datetime.timedelta(seconds=eta)))) 135 | 136 | torch.save(net.state_dict(), save_folder + 'Final_FaceBoxes.pth') 137 | 138 | 139 | def adjust_learning_rate(optimizer, gamma, epoch, step_index, iteration, epoch_size): 140 | """Sets the learning rate 141 | # Adapted from PyTorch Imagenet example: 142 | # https://github.com/pytorch/examples/blob/master/imagenet/main.py 143 | """ 144 | warmup_epoch = 1 145 | if epoch <= warmup_epoch: 146 | lr = 1e-6 + (initial_lr-1e-6) * iteration / (epoch_size * warmup_epoch) 147 | else: 148 | lr = initial_lr * (gamma ** (step_index)) 149 | for param_group in optimizer.param_groups: 150 | param_group['lr'] = lr 151 | #print('lr=', lr) 152 | return lr 153 | 154 | if __name__ == '__main__': 155 | train() 156 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AnimeFaceBoxes 2 | 3 | Super fast anime face detection (> 200 fps for 512x512 resolution, RTX2080 + i7 9700k) 4 | 5 | ## Dependencies 6 | - Python 3.6+ (Anaconda) 7 | - PyTorch-1.0 + 8 | - OpenCV3 (Python) 9 | 10 | ## Usage 11 | - build nms: sh make.sh 12 | - Manual data labeling: LabelFaceBox.py (you can skip this if you have danbooru2018 dataset) 13 | - labeled data: faceboxes (600+ labels for danbooru2018 dataset) 14 | - train: MyTrain.py 15 | - eval: eval.py 16 | 17 | ![alt text](https://github.com/WynMew/AnimeFaceBoxes/blob/master/out.png) 18 | 19 | 20 | codes borrowed a lot from [FaceBoxes.PyTorch](https://github.com/zisianw/FaceBoxes.PyTorch) 21 | -------------------------------------------------------------------------------- /data/AnimeData.py: -------------------------------------------------------------------------------- 1 | import os 2 | import os.path 3 | import sys 4 | import torch 5 | import torch.utils.data as data 6 | import cv2 7 | import numpy as np 8 | 9 | CLASSES = ( '__background__', 'face') 10 | 11 | class AnnotationTransform(object): 12 | 13 | """Transforms a VOC annotation into a Tensor of bbox coords and label index 14 | Initilized with a dictionary lookup of classnames to indexes 15 | 16 | Arguments: 17 | class_to_ind (dict, optional): dictionary lookup of classnames -> indexes 18 | (default: alphabetic indexing of VOC's 20 classes) 19 | keep_difficult (bool, optional): keep difficult instances or not 20 | (default: False) 21 | height (int): height 22 | width (int): width 23 | """ 24 | 25 | def __init__(self): 26 | self.class_to_ind = dict( zip(CLASSES, range(len(CLASSES)))) 27 | #self.keep_difficult = keep_difficult 28 | 29 | def __call__(self, target): 30 | """ 31 | Arguments: 32 | target (annotation) : the target annotation to be made usable 33 | will be an ET.Element 34 | Returns: 35 | a list containing lists of bounding boxes [bbox coords, class name] 36 | """ 37 | res = np.empty((0, 5)) 38 | #for obj in target.iter('object'): 39 | #difficult = int(obj.find('difficult').text) == 1 40 | #if not self.keep_difficult and difficult: 41 | # continue 42 | #name = obj.find('name').text.lower().strip() 43 | #bbox = obj.find('bndbox') 44 | #pts = ['xmin', 'ymin', 'xmax', 'ymax'] 45 | #bndbox = [] 46 | #for i, pt in enumerate(pts): 47 | # cur_pt = int(bbox.find(pt).text) 48 | # bndbox.append(cur_pt) 49 | #label_idx = self.class_to_ind[name] 50 | #bndbox.append(label_idx) 51 | #res = np.vstack((res, bndbox)) # [xmin, ymin, xmax, ymax, label_ind] 52 | label_idx = self.class_to_ind['face'] 53 | bndbox = [int(target[0]),int(target[1]),int(target[2]),int(target[3])] 54 | bndbox.append(label_idx) 55 | res = np.vstack((res, bndbox)) # [xmin, ymin, xmax, ymax, label_ind] 56 | return res 57 | 58 | 59 | class AnimeDetection(data.Dataset): 60 | 61 | """VOC Detection Dataset Object 62 | 63 | input is image, target is annotation 64 | 65 | Arguments: 66 | root (string): filepath to WIDER folder 67 | target_transform (callable, optional): transformation to perform on the 68 | target `annotation` 69 | (eg: take in caption string, return tensor of word indices) 70 | """ 71 | 72 | def __init__(self, filelist, preproc=None, target_transform=None): 73 | self.filelist = filelist 74 | self.preproc = preproc 75 | self.target_transform = target_transform 76 | #self._annopath = os.path.join(self.root, 'annotations', '%s') 77 | #self._imgpath = os.path.join(self.root, 'images', '%s') 78 | self.ids = list() 79 | with open(self.filelist, 'r') as f: 80 | self.ids = [tuple(line.split()) for line in f] 81 | 82 | def __getitem__(self, index): 83 | img_id = self.ids[index] 84 | #print(img_id) 85 | #target = ET.parse(self._annopath % img_id[1]).getroot() 86 | target = img_id[1:] 87 | img = cv2.imread(img_id[0], cv2.IMREAD_COLOR) 88 | height, width, _ = img.shape 89 | 90 | if self.target_transform is not None: 91 | target = self.target_transform(target) 92 | 93 | if self.preproc is not None: 94 | img, target = self.preproc(img, target) 95 | 96 | return torch.from_numpy(img), target 97 | 98 | def __len__(self): 99 | return len(self.ids) 100 | 101 | 102 | def detection_collate(batch): 103 | """Custom collate fn for dealing with batches of images that have a different 104 | number of associated object annotations (bounding boxes). 105 | 106 | Arguments: 107 | batch: (tuple) A tuple of tensor images and lists of annotations 108 | 109 | Return: 110 | A tuple containing: 111 | 1) (tensor) batch of images stacked on their 0 dim 112 | 2) (list of tensors) annotations for a given image are stacked on 0 dim 113 | """ 114 | targets = [] 115 | imgs = [] 116 | for _, sample in enumerate(batch): 117 | for _, tup in enumerate(sample): 118 | if torch.is_tensor(tup): 119 | imgs.append(tup) 120 | elif isinstance(tup, type(np.empty(0))): 121 | annos = torch.from_numpy(tup).float() 122 | targets.append(annos) 123 | 124 | return (torch.stack(imgs, 0), targets) 125 | -------------------------------------------------------------------------------- /data/__init__.py: -------------------------------------------------------------------------------- 1 | #from .wider_voc import VOCDetection, AnnotationTransform, detection_collate 2 | #from .data_augment import * 3 | #from .config import * 4 | 5 | from .AnimeData import AnimeDetection, AnnotationTransform, detection_collate 6 | from .data_augment import * 7 | from .config import * 8 | -------------------------------------------------------------------------------- /data/__pycache__/AnimeData.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WynMew/AnimeFaceBoxes/025b5e0a265e971d03cf850d67a52dad2ab392c6/data/__pycache__/AnimeData.cpython-36.pyc -------------------------------------------------------------------------------- /data/__pycache__/__init__.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WynMew/AnimeFaceBoxes/025b5e0a265e971d03cf850d67a52dad2ab392c6/data/__pycache__/__init__.cpython-36.pyc -------------------------------------------------------------------------------- /data/__pycache__/config.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WynMew/AnimeFaceBoxes/025b5e0a265e971d03cf850d67a52dad2ab392c6/data/__pycache__/config.cpython-36.pyc -------------------------------------------------------------------------------- /data/__pycache__/data_augment.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WynMew/AnimeFaceBoxes/025b5e0a265e971d03cf850d67a52dad2ab392c6/data/__pycache__/data_augment.cpython-36.pyc -------------------------------------------------------------------------------- /data/config.py: -------------------------------------------------------------------------------- 1 | # config.py 2 | 3 | cfg = { 4 | 'name': 'FaceBoxes', 5 | #'min_dim': 1024, 6 | #'feature_maps': [[32, 32], [16, 16], [8, 8]], 7 | # 'aspect_ratios': [[1], [1], [1]], 8 | 'min_sizes': [[32, 64, 128], [256], [512]], 9 | 'steps': [32, 64, 128], 10 | 'variance': [0.1, 0.2], 11 | 'clip': False, 12 | 'loc_weight': 2.0, 13 | 'gpu_train': True 14 | } 15 | -------------------------------------------------------------------------------- /data/data_augment.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | import numpy as np 3 | import random 4 | from utils.box_utils import matrix_iof 5 | 6 | 7 | def _crop(image, boxes, labels, img_dim): 8 | height, width, _ = image.shape 9 | pad_image_flag = True 10 | 11 | for _ in range(250): 12 | if random.uniform(0, 1) <= 0.2: 13 | scale = 1 14 | else: 15 | scale = random.uniform(0.3, 1.) 16 | short_side = min(width, height) 17 | w = int(scale * short_side) 18 | h = w 19 | 20 | if width == w: 21 | l = 0 22 | else: 23 | l = random.randrange(width - w) 24 | if height == h: 25 | t = 0 26 | else: 27 | t = random.randrange(height - h) 28 | roi = np.array((l, t, l + w, t + h)) 29 | 30 | value = matrix_iof(boxes, roi[np.newaxis]) 31 | flag = (value >= 1) 32 | if not flag.any(): 33 | continue 34 | 35 | centers = (boxes[:, :2] + boxes[:, 2:]) / 2 36 | mask_a = np.logical_and(roi[:2] < centers, centers < roi[2:]).all(axis=1) 37 | boxes_t = boxes[mask_a].copy() 38 | labels_t = labels[mask_a].copy() 39 | 40 | if boxes_t.shape[0] == 0: 41 | continue 42 | 43 | image_t = image[roi[1]:roi[3], roi[0]:roi[2]] 44 | 45 | boxes_t[:, :2] = np.maximum(boxes_t[:, :2], roi[:2]) 46 | boxes_t[:, :2] -= roi[:2] 47 | boxes_t[:, 2:] = np.minimum(boxes_t[:, 2:], roi[2:]) 48 | boxes_t[:, 2:] -= roi[:2] 49 | 50 | # make sure that the cropped image contains at least one face > 16 pixel at training image scale 51 | b_w_t = (boxes_t[:, 2] - boxes_t[:, 0] + 1) / w * img_dim 52 | b_h_t = (boxes_t[:, 3] - boxes_t[:, 1] + 1) / h * img_dim 53 | mask_b = np.minimum(b_w_t, b_h_t) > 16.0 54 | boxes_t = boxes_t[mask_b] 55 | labels_t = labels_t[mask_b] 56 | 57 | if boxes_t.shape[0] == 0: 58 | continue 59 | 60 | pad_image_flag = False 61 | 62 | return image_t, boxes_t, labels_t, pad_image_flag 63 | return image, boxes, labels, pad_image_flag 64 | 65 | 66 | def _distort(image): 67 | 68 | def _convert(image, alpha=1, beta=0): 69 | tmp = image.astype(float) * alpha + beta 70 | tmp[tmp < 0] = 0 71 | tmp[tmp > 255] = 255 72 | image[:] = tmp 73 | 74 | image = image.copy() 75 | 76 | if random.randrange(2): 77 | 78 | #brightness distortion 79 | if random.randrange(2): 80 | _convert(image, beta=random.uniform(-32, 32)) 81 | 82 | #contrast distortion 83 | if random.randrange(2): 84 | _convert(image, alpha=random.uniform(0.5, 1.5)) 85 | 86 | image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV) 87 | 88 | #saturation distortion 89 | if random.randrange(2): 90 | _convert(image[:, :, 1], alpha=random.uniform(0.5, 1.5)) 91 | 92 | #hue distortion 93 | if random.randrange(2): 94 | tmp = image[:, :, 0].astype(int) + random.randint(-18, 18) 95 | tmp %= 180 96 | image[:, :, 0] = tmp 97 | 98 | image = cv2.cvtColor(image, cv2.COLOR_HSV2BGR) 99 | 100 | else: 101 | 102 | #brightness distortion 103 | if random.randrange(2): 104 | _convert(image, beta=random.uniform(-32, 32)) 105 | 106 | image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV) 107 | 108 | #saturation distortion 109 | if random.randrange(2): 110 | _convert(image[:, :, 1], alpha=random.uniform(0.5, 1.5)) 111 | 112 | #hue distortion 113 | if random.randrange(2): 114 | tmp = image[:, :, 0].astype(int) + random.randint(-18, 18) 115 | tmp %= 180 116 | image[:, :, 0] = tmp 117 | 118 | image = cv2.cvtColor(image, cv2.COLOR_HSV2BGR) 119 | 120 | #contrast distortion 121 | if random.randrange(2): 122 | _convert(image, alpha=random.uniform(0.5, 1.5)) 123 | 124 | return image 125 | 126 | 127 | def _expand(image, boxes, fill, p): 128 | if random.randrange(2): 129 | return image, boxes 130 | 131 | height, width, depth = image.shape 132 | 133 | scale = random.uniform(1, p) 134 | w = int(scale * width) 135 | h = int(scale * height) 136 | 137 | left = random.randint(0, w - width) 138 | top = random.randint(0, h - height) 139 | 140 | boxes_t = boxes.copy() 141 | boxes_t[:, :2] += (left, top) 142 | boxes_t[:, 2:] += (left, top) 143 | expand_image = np.empty( 144 | (h, w, depth), 145 | dtype=image.dtype) 146 | expand_image[:, :] = fill 147 | expand_image[top:top + height, left:left + width] = image 148 | image = expand_image 149 | 150 | return image, boxes_t 151 | 152 | 153 | def _mirror(image, boxes): 154 | _, width, _ = image.shape 155 | if random.randrange(2): 156 | image = image[:, ::-1] 157 | boxes = boxes.copy() 158 | boxes[:, 0::2] = width - boxes[:, 2::-2] 159 | return image, boxes 160 | 161 | 162 | def _pad_to_square(image, rgb_mean, pad_image_flag): 163 | if not pad_image_flag: 164 | return image 165 | height, width, _ = image.shape 166 | long_side = max(width, height) 167 | image_t = np.empty((long_side, long_side, 3), dtype=image.dtype) 168 | image_t[:, :] = rgb_mean 169 | image_t[0:0 + height, 0:0 + width] = image 170 | return image_t 171 | 172 | 173 | def _resize_subtract_mean(image, insize, rgb_mean): 174 | interp_methods = [cv2.INTER_LINEAR, cv2.INTER_CUBIC, cv2.INTER_AREA, cv2.INTER_NEAREST, cv2.INTER_LANCZOS4] 175 | interp_method = interp_methods[random.randrange(5)] 176 | image = cv2.resize(image, (insize, insize), interpolation=interp_method) 177 | image = image.astype(np.float32) 178 | image -= rgb_mean 179 | return image.transpose(2, 0, 1) 180 | 181 | 182 | class preproc(object): 183 | 184 | def __init__(self, img_dim, rgb_means): 185 | self.img_dim = img_dim 186 | self.rgb_means = rgb_means 187 | 188 | def __call__(self, image, targets): 189 | assert targets.shape[0] > 0, "this image does not have gt" 190 | 191 | boxes = targets[:, :-1].copy() 192 | labels = targets[:, -1].copy() 193 | 194 | #image_t = _distort(image) 195 | #image_t, boxes_t = _expand(image_t, boxes, self.cfg['rgb_mean'], self.cfg['max_expand_ratio']) 196 | #image_t, boxes_t, labels_t = _crop(image_t, boxes, labels, self.img_dim, self.rgb_means) 197 | image_t, boxes_t, labels_t, pad_image_flag = _crop(image, boxes, labels, self.img_dim) 198 | image_t = _distort(image_t) 199 | image_t = _pad_to_square(image_t,self.rgb_means, pad_image_flag) 200 | image_t, boxes_t = _mirror(image_t, boxes_t) 201 | height, width, _ = image_t.shape 202 | image_t = _resize_subtract_mean(image_t, self.img_dim, self.rgb_means) 203 | boxes_t[:, 0::2] /= width 204 | boxes_t[:, 1::2] /= height 205 | 206 | labels_t = np.expand_dims(labels_t, 1) 207 | targets_t = np.hstack((boxes_t, labels_t)) 208 | 209 | return image_t, targets_t 210 | -------------------------------------------------------------------------------- /eval.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | import os 3 | import argparse 4 | import torch 5 | import torch.backends.cudnn as cudnn 6 | import numpy as np 7 | from data import cfg 8 | from layers.functions.prior_box import PriorBox 9 | from utils.nms_wrapper import nms 10 | #from utils.nms.py_cpu_nms import py_cpu_nms 11 | import cv2 12 | from models.faceboxes import FaceBoxes 13 | from utils.box_utils import decode 14 | from utils.timer import Timer 15 | 16 | def check_keys(model, pretrained_state_dict): 17 | ckpt_keys = set(pretrained_state_dict.keys()) 18 | model_keys = set(model.state_dict().keys()) 19 | used_pretrained_keys = model_keys & ckpt_keys 20 | unused_pretrained_keys = ckpt_keys - model_keys 21 | missing_keys = model_keys - ckpt_keys 22 | print('Missing keys:{}'.format(len(missing_keys))) 23 | print('Unused checkpoint keys:{}'.format(len(unused_pretrained_keys))) 24 | print('Used keys:{}'.format(len(used_pretrained_keys))) 25 | assert len(used_pretrained_keys) > 0, 'load NONE from pretrained checkpoint' 26 | return True 27 | 28 | def remove_prefix(state_dict, prefix): 29 | ''' Old style model is stored with all names of parameters sharing common prefix 'module.' ''' 30 | print('remove prefix \'{}\''.format(prefix)) 31 | f = lambda x: x.split(prefix, 1)[-1] if x.startswith(prefix) else x 32 | return {f(key): value for key, value in state_dict.items()} 33 | 34 | def load_model(model, pretrained_path, load_to_cpu): 35 | print('Loading pretrained model from {}'.format(pretrained_path)) 36 | if load_to_cpu: 37 | pretrained_dict = torch.load(pretrained_path, map_location=lambda storage, loc: storage) 38 | else: 39 | device = torch.cuda.current_device() 40 | pretrained_dict = torch.load(pretrained_path, map_location=lambda storage, loc: storage.cuda(device)) 41 | if "state_dict" in pretrained_dict.keys(): 42 | pretrained_dict = remove_prefix(pretrained_dict['state_dict'], 'module.') 43 | else: 44 | pretrained_dict = remove_prefix(pretrained_dict, 'module.') 45 | check_keys(model, pretrained_dict) 46 | model.load_state_dict(pretrained_dict, strict=False) 47 | return model 48 | weightfile = 'FaceBoxes_epoch_90.pth' 49 | 50 | cpu=False 51 | confidenceTh = 0.05 52 | nmsTh = 0.3 53 | keepTopK=750 54 | top_k = 5000 55 | 56 | os.environ['CUDA_VISIBLE_DEVICES']='1' 57 | torch.set_grad_enabled(False) 58 | # net and model 59 | net = FaceBoxes(phase='test', size=None, num_classes=2) # initialize detector 60 | net = load_model(net, weightfile, cpu) 61 | net.eval() 62 | #print('Finished loading model!') 63 | #print(net) 64 | cudnn.benchmark = True 65 | device = torch.device("cpu" if cpu else "cuda") 66 | net = net.to(device) 67 | 68 | image_path = 'danbooru2018/original/0795/1081795.jpg' 69 | imgOrig = cv2.imread(image_path, cv2.IMREAD_COLOR) 70 | img=np.float32(imgOrig) 71 | im_height, im_width, _ = img.shape 72 | scale = torch.Tensor([img.shape[1], img.shape[0], img.shape[1], img.shape[0]]) 73 | img -= (104, 117, 123) 74 | img = img.transpose(2, 0, 1) 75 | img = torch.from_numpy(img).unsqueeze(0) 76 | img = img.to(device) 77 | scale = scale.to(device) 78 | 79 | loc, conf = net(img) # forward pass 80 | priorbox = PriorBox(cfg, image_size=(im_height, im_width)) 81 | priors = priorbox.forward() 82 | priors = priors.to(device) 83 | prior_data = priors.data 84 | boxes = decode(loc.data.squeeze(0), prior_data, cfg['variance']) 85 | boxes = boxes * scale 86 | boxes = boxes.cpu().numpy() 87 | scores = conf.data.cpu().numpy()[:, 1] 88 | 89 | # ignore low scores 90 | inds = np.where(scores > confidenceTh)[0] 91 | boxes = boxes[inds] 92 | scores = scores[inds] 93 | 94 | # keep top-K before NMS 95 | order = scores.argsort()[::-1][:top_k] 96 | boxes = boxes[order] 97 | scores = scores[order] 98 | 99 | # do NMS 100 | dets = np.hstack((boxes, scores[:, np.newaxis])).astype(np.float32, copy=False) 101 | #keep = py_cpu_nms(dets, args.nms_threshold) 102 | keep = nms(dets, nmsTh,force_cpu=cpu) 103 | dets = dets[keep, :] 104 | 105 | # keep top-K faster NMS 106 | dets = dets[:keepTopK, :] 107 | 108 | for k in range(dets.shape[0]): 109 | xmin = dets[k, 0] 110 | ymin = dets[k, 1] 111 | xmax = dets[k, 2] 112 | ymax = dets[k, 3] 113 | ymin += 0.2 * (ymax - ymin + 1) 114 | score = dets[k, 4] 115 | print('{:s} {:.3f} {:.1f} {:.1f} {:.1f} {:.1f}\n'.format(image_path, score, xmin, ymin, xmax, ymax)) 116 | cv2.rectangle(imgOrig, (int(xmin), int(ymin)), (int(xmax), int(ymax)), (0, 0, 255), 15) 117 | 118 | 119 | cv2.imwrite('out.png', imgOrig) 120 | -------------------------------------------------------------------------------- /faceboxes: -------------------------------------------------------------------------------- 1 | /home/wynmew/data/downloads/danbooru2018/original/0016/3351016.jpg 105 5 702 522 596 517 2 | /home/wynmew/data/downloads/danbooru2018/original/0016/2164016.png 212 94 466 345 254 251 3 | /home/wynmew/data/downloads/danbooru2018/original/0016/2639016.jpg 236 22 520 268 283 246 4 | /home/wynmew/data/downloads/danbooru2018/original/0016/2378016.jpg 287 96 828 698 541 601 5 | /home/wynmew/data/downloads/danbooru2018/original/0016/2479016.jpg 617 36 1040 434 423 398 6 | /home/wynmew/data/downloads/danbooru2018/original/0016/2192016.jpg 538 64 1015 604 477 539 7 | /home/wynmew/data/downloads/danbooru2018/original/0016/3068016.jpg 1379 84 2273 958 894 874 8 | /home/wynmew/data/downloads/danbooru2018/original/0016/2088016.jpg 189 45 794 776 604 730 9 | /home/wynmew/data/downloads/danbooru2018/original/0016/1966016.jpg 85 29 320 285 234 256 10 | /home/wynmew/data/downloads/danbooru2018/original/0016/527016.jpg 322 288 439 413 116 124 11 | /home/wynmew/data/downloads/danbooru2018/original/0016/1748016.png 87 77 635 700 548 622 12 | /home/wynmew/data/downloads/danbooru2018/original/0016/2157016.jpg 519 31 1034 555 515 523 13 | /home/wynmew/data/downloads/danbooru2018/original/0016/567016.jpg 394 86 703 431 309 344 14 | /home/wynmew/data/downloads/danbooru2018/original/0016/1895016.png 197 14 577 342 379 327 15 | /home/wynmew/data/downloads/danbooru2018/original/0016/2798016.png 384 30 673 341 288 311 16 | /home/wynmew/data/downloads/danbooru2018/original/0016/2597016.jpg 30 10 394 351 363 340 17 | /home/wynmew/data/downloads/danbooru2018/original/0016/3345016.png 228 7 483 322 255 315 18 | /home/wynmew/data/downloads/danbooru2018/original/0016/661016.jpg 178 6 481 275 303 268 19 | /home/wynmew/data/downloads/danbooru2018/original/0016/3185016.jpg 219 179 535 444 316 265 20 | /home/wynmew/data/downloads/danbooru2018/original/0016/1901016.jpg 860 88 1401 676 540 588 21 | /home/wynmew/data/downloads/danbooru2018/original/0016/2051016.png 266 4 785 483 519 479 22 | /home/wynmew/data/downloads/danbooru2018/original/0016/813016.jpg 274 81 469 257 195 175 23 | /home/wynmew/data/downloads/danbooru2018/original/0016/1033016.jpg 227 96 528 411 301 315 24 | /home/wynmew/data/downloads/danbooru2018/original/0016/1728016.png 22 26 471 478 449 451 25 | /home/wynmew/data/downloads/danbooru2018/original/0016/2223016.png 687 94 1240 710 553 616 26 | /home/wynmew/data/downloads/danbooru2018/original/0016/2324016.jpg 542 11 794 281 252 269 27 | /home/wynmew/data/downloads/danbooru2018/original/0016/1135016.jpg 231 39 445 293 213 253 28 | /home/wynmew/data/downloads/danbooru2018/original/0016/704016.jpg 212 1 559 337 346 336 29 | /home/wynmew/data/downloads/danbooru2018/original/0016/2278016.jpg 170 54 542 472 371 418 30 | /home/wynmew/data/downloads/danbooru2018/original/0016/2582016.png 1119 243 1626 794 507 550 31 | /home/wynmew/data/downloads/danbooru2018/original/0016/17016.jpg 18 24 221 204 203 180 32 | /home/wynmew/data/downloads/danbooru2018/original/0016/1897016.jpg 181 1 779 513 597 511 33 | /home/wynmew/data/downloads/danbooru2018/original/0016/1315016.jpg 53 41 254 233 201 191 34 | /home/wynmew/data/downloads/danbooru2018/original/0016/2039016.png 315 198 604 527 289 328 35 | /home/wynmew/data/downloads/danbooru2018/original/0016/1840016.png 498 347 1445 1265 946 917 36 | /home/wynmew/data/downloads/danbooru2018/original/0016/648016.jpg 154 1321 1037 2162 883 840 37 | /home/wynmew/data/downloads/danbooru2018/original/0016/1160016.jpg 126 16 668 492 541 476 38 | /home/wynmew/data/downloads/danbooru2018/original/0016/2872016.png 329 82 753 535 424 453 39 | /home/wynmew/data/downloads/danbooru2018/original/0016/1953016.jpg 204 59 546 360 342 301 40 | /home/wynmew/data/downloads/danbooru2018/original/0016/2973016.jpg 180 30 744 644 563 614 41 | /home/wynmew/data/downloads/danbooru2018/original/0016/2784016.png 200 7 554 305 354 297 42 | /home/wynmew/data/downloads/danbooru2018/original/0016/2815016.jpg 534 379 758 615 224 235 43 | /home/wynmew/data/downloads/danbooru2018/original/0016/832016.png 145 122 1042 951 897 829 44 | /home/wynmew/data/downloads/danbooru2018/original/0016/2533016.png 487 77 1065 697 578 619 45 | /home/wynmew/data/downloads/danbooru2018/original/0016/2493016.png 512 214 1923 1582 1411 1368 46 | /home/wynmew/data/downloads/danbooru2018/original/0016/403016.jpg 209 25 456 259 246 234 47 | /home/wynmew/data/downloads/danbooru2018/original/0016/2383016.png 121 24 292 197 170 173 48 | /home/wynmew/data/downloads/danbooru2018/original/0016/614016.jpg 172 33 602 438 429 405 49 | /home/wynmew/data/downloads/danbooru2018/original/0016/1239016.jpg 335 190 945 723 610 533 50 | /home/wynmew/data/downloads/danbooru2018/original/0016/2336016.jpg 94 5 571 534 476 529 51 | /home/wynmew/data/downloads/danbooru2018/original/0016/3180016.jpg 418 108 746 424 327 316 52 | /home/wynmew/data/downloads/danbooru2018/original/0016/1407016.jpg 99 4 308 218 208 213 53 | /home/wynmew/data/downloads/danbooru2018/original/0016/2993016.jpg 145 13 810 739 665 726 54 | /home/wynmew/data/downloads/danbooru2018/original/0016/2904016.jpg 275 40 626 426 350 385 55 | /home/wynmew/data/downloads/danbooru2018/original/0016/535016.jpg 112 62 546 546 433 484 56 | /home/wynmew/data/downloads/danbooru2018/original/0016/2028016.jpg 169 70 448 361 279 291 57 | /home/wynmew/data/downloads/danbooru2018/original/0016/517016.jpg 39 53 401 380 361 327 58 | /home/wynmew/data/downloads/danbooru2018/original/0016/1398016.png 279 17 590 327 311 310 59 | /home/wynmew/data/downloads/danbooru2018/original/0016/3191016.jpg 228 8 638 452 410 443 60 | /home/wynmew/data/downloads/danbooru2018/original/0016/1613016.png 157 37 371 235 213 197 61 | /home/wynmew/data/downloads/danbooru2018/original/0016/735016.png 174 37 444 327 269 289 62 | /home/wynmew/data/downloads/danbooru2018/original/0016/329016.jpg 59 14 351 324 292 310 63 | /home/wynmew/data/downloads/danbooru2018/original/0016/2786016.png 459 106 776 507 317 401 64 | /home/wynmew/data/downloads/danbooru2018/original/0016/1687016.jpg 122 55 446 391 324 336 65 | /home/wynmew/data/downloads/danbooru2018/original/0016/1619016.jpg 48 46 235 251 186 204 66 | /home/wynmew/data/downloads/danbooru2018/original/0016/1389016.jpg 271 53 601 415 329 361 67 | /home/wynmew/data/downloads/danbooru2018/original/0016/89016.jpg 238 14 402 217 163 202 68 | /home/wynmew/data/downloads/danbooru2018/original/0016/2772016.jpg 143 5 498 373 355 368 69 | /home/wynmew/data/downloads/danbooru2018/original/0016/201016.jpg 211 12 481 252 270 239 70 | /home/wynmew/data/downloads/danbooru2018/original/0016/2729016.png 567 92 845 389 278 296 71 | /home/wynmew/data/downloads/danbooru2018/original/0016/2249016.png 618 113 990 468 371 354 72 | /home/wynmew/data/downloads/danbooru2018/original/0016/593016.jpg 468 66 703 306 234 239 73 | /home/wynmew/data/downloads/danbooru2018/original/0016/3049016.png 153 32 366 229 213 196 74 | /home/wynmew/data/downloads/danbooru2018/original/0016/2218016.jpg 253 52 614 406 360 353 75 | /home/wynmew/data/downloads/danbooru2018/original/0016/1566016.jpg 608 60 861 351 252 290 76 | /home/wynmew/data/downloads/danbooru2018/original/0016/1357016.jpg 437 91 764 390 327 299 77 | /home/wynmew/data/downloads/danbooru2018/original/0016/1583016.png 343 26 772 495 428 468 78 | /home/wynmew/data/downloads/danbooru2018/original/0016/109016.png 138 1 437 257 298 255 79 | /home/wynmew/data/downloads/danbooru2018/original/0016/428016.jpg 285 227 626 550 341 322 80 | /home/wynmew/data/downloads/danbooru2018/original/0016/1860016.jpg 118 87 397 359 279 272 81 | /home/wynmew/data/downloads/danbooru2018/original/0016/1425016.png 99 141 1417 1248 1317 1107 82 | /home/wynmew/data/downloads/danbooru2018/original/0016/2494016.jpg 240 26 823 674 583 647 83 | /home/wynmew/data/downloads/danbooru2018/original/0016/3361016.png 698 136 981 447 283 310 84 | /home/wynmew/data/downloads/danbooru2018/original/0016/2863016.jpg 197 24 652 526 455 501 85 | /home/wynmew/data/downloads/danbooru2018/original/0016/1059016.png 26 2 389 283 363 281 86 | /home/wynmew/data/downloads/danbooru2018/original/0016/3131016.png 115 3 430 287 314 284 87 | /home/wynmew/data/downloads/danbooru2018/original/0016/409016.jpg 148 121 441 397 293 276 88 | /home/wynmew/data/downloads/danbooru2018/original/0016/2477016.jpg 105 79 356 310 250 231 89 | /home/wynmew/data/downloads/danbooru2018/original/0016/2109016.png 541 301 1678 1303 1136 1001 90 | /home/wynmew/data/downloads/danbooru2018/original/0016/3284016.png 284 49 918 666 633 616 91 | /home/wynmew/data/downloads/danbooru2018/original/0016/3113016.png 559 167 1514 1371 954 1203 92 | /home/wynmew/data/downloads/danbooru2018/original/0016/3177016.jpg 851 67 1909 1208 1057 1140 93 | /home/wynmew/data/downloads/danbooru2018/original/0016/1621016.jpg 820 214 1260 698 439 484 94 | /home/wynmew/data/downloads/danbooru2018/original/0016/2072016.jpg 142 46 464 321 321 275 95 | /home/wynmew/data/downloads/danbooru2018/original/0016/2217016.jpg 229 2 428 192 198 190 96 | /home/wynmew/data/downloads/danbooru2018/original/0016/489016.jpg 282 42 1587 1395 1304 1352 97 | /home/wynmew/data/downloads/danbooru2018/original/0016/1418016.jpg 798 30 952 192 154 162 98 | /home/wynmew/data/downloads/danbooru2018/original/0016/2668016.png 324 9 583 278 259 269 99 | /home/wynmew/data/downloads/danbooru2018/original/0016/1544016.png 102 224 401 493 299 268 100 | /home/wynmew/data/downloads/danbooru2018/original/0016/962016.jpg 602 65 1080 543 477 477 101 | /home/wynmew/data/downloads/danbooru2018/original/0016/229016.jpg 154 56 305 179 151 123 102 | /home/wynmew/data/downloads/danbooru2018/original/0016/3089016.png 174 43 732 646 558 602 103 | /home/wynmew/data/downloads/danbooru2018/original/0016/228016.jpg 93 45 466 427 373 382 104 | /home/wynmew/data/downloads/danbooru2018/original/0016/1099016.png 268 67 577 333 308 266 105 | /home/wynmew/data/downloads/danbooru2018/original/0016/1140016.jpg 1095 257 1515 673 419 416 106 | /home/wynmew/data/downloads/danbooru2018/original/0016/2840016.jpg 1263 201 1553 511 289 310 107 | /home/wynmew/data/downloads/danbooru2018/original/0016/888016.jpg 1073 564 1779 1294 706 729 108 | /home/wynmew/data/downloads/danbooru2018/original/0016/3200016.jpg 607 153 1280 839 672 685 109 | /home/wynmew/data/downloads/danbooru2018/original/0016/652016.jpg 41 84 379 410 338 325 110 | /home/wynmew/data/downloads/danbooru2018/original/0016/2806016.jpg 420 5 1634 1047 1213 1042 111 | /home/wynmew/data/downloads/danbooru2018/original/0016/278016.jpg 81 25 256 172 175 146 112 | /home/wynmew/data/downloads/danbooru2018/original/0016/598016.jpg 193 129 355 247 161 117 113 | /home/wynmew/data/downloads/danbooru2018/original/0016/1310016.jpg 61 0 327 290 266 290 114 | /home/wynmew/data/downloads/danbooru2018/original/0016/1463016.png 423 538 1755 1826 1331 1287 115 | /home/wynmew/data/downloads/danbooru2018/original/0016/2814016.png 541 2 1169 704 628 701 116 | /home/wynmew/data/downloads/danbooru2018/original/0016/1290016.jpg 60 39 154 141 94 102 117 | /home/wynmew/data/downloads/danbooru2018/original/0016/1553016.jpg 151 6 536 446 385 439 118 | /home/wynmew/data/downloads/danbooru2018/original/0016/2073016.jpg 570 6 1189 665 618 659 119 | /home/wynmew/data/downloads/danbooru2018/original/0016/1578016.jpg 48 22 384 292 335 270 120 | /home/wynmew/data/downloads/danbooru2018/original/0016/2792016.jpg 238 108 821 811 583 703 121 | /home/wynmew/data/downloads/danbooru2018/original/0016/1911016.jpg 273 91 519 310 245 219 122 | /home/wynmew/data/downloads/danbooru2018/original/0016/1826016.jpg 90 95 374 382 284 286 123 | /home/wynmew/data/downloads/danbooru2018/original/0016/3296016.png 360 290 678 628 318 338 124 | /home/wynmew/data/downloads/danbooru2018/original/0016/3342016.jpg 277 12 756 564 478 551 125 | /home/wynmew/data/downloads/danbooru2018/original/0016/2356016.png 1687 47 3040 1605 1353 1557 126 | /home/wynmew/data/downloads/danbooru2018/original/0016/176016.jpg 209 24 406 227 196 202 127 | /home/wynmew/data/downloads/danbooru2018/original/0016/227016.jpg 158 60 348 251 189 190 128 | /home/wynmew/data/downloads/danbooru2018/original/0016/2514016.jpg 252 221 1818 1919 1565 1698 129 | /home/wynmew/data/downloads/danbooru2018/original/0016/1570016.jpg 321 89 531 301 209 212 130 | /home/wynmew/data/downloads/danbooru2018/original/0016/2822016.jpg 103 40 662 683 559 642 131 | /home/wynmew/data/downloads/danbooru2018/original/0016/2829016.jpg 2598 315 4064 1961 1466 1645 132 | /home/wynmew/data/downloads/danbooru2018/original/0016/3245016.jpg 344 27 863 585 519 558 133 | /home/wynmew/data/downloads/danbooru2018/original/0016/779016.png 360 69 553 279 192 210 134 | /home/wynmew/data/downloads/danbooru2018/original/0016/1390016.png 228 137 510 471 282 334 135 | /home/wynmew/data/downloads/danbooru2018/original/0016/2920016.jpg 311 26 550 300 239 273 136 | /home/wynmew/data/downloads/danbooru2018/original/0016/1849016.jpg 230 9 553 291 323 282 137 | /home/wynmew/data/downloads/danbooru2018/original/0016/2954016.jpg 96 8 521 371 424 362 138 | /home/wynmew/data/downloads/danbooru2018/original/0016/784016.jpg 309 203 648 576 339 372 139 | /home/wynmew/data/downloads/danbooru2018/original/0016/287016.jpg 883 326 1814 1317 931 990 140 | /home/wynmew/data/downloads/danbooru2018/original/0016/448016.jpg 73 64 265 278 191 213 141 | /home/wynmew/data/downloads/danbooru2018/original/0016/1208016.jpg 295 30 832 514 536 483 142 | /home/wynmew/data/downloads/danbooru2018/original/0016/1179016.jpg 120 4 397 265 277 260 143 | /home/wynmew/data/downloads/danbooru2018/original/0016/1121016.jpg 274 19 549 267 274 248 144 | /home/wynmew/data/downloads/danbooru2018/original/0016/578016.jpg 334 187 613 460 278 273 145 | /home/wynmew/data/downloads/danbooru2018/original/0016/2845016.jpg 149 118 323 305 173 186 146 | /home/wynmew/data/downloads/danbooru2018/original/0016/194016.png 304 11 629 373 325 362 147 | /home/wynmew/data/downloads/danbooru2018/original/0016/135016.jpg 16 20 434 382 418 362 148 | /home/wynmew/data/downloads/danbooru2018/original/0016/424016.jpg 352 81 485 235 132 154 149 | /home/wynmew/data/downloads/danbooru2018/original/0016/2974016.jpg 785 135 1196 620 411 484 150 | /home/wynmew/data/downloads/danbooru2018/original/0016/1195016.png 272 200 672 576 400 376 151 | /home/wynmew/data/downloads/danbooru2018/original/0016/2465016.jpg 516 37 2310 1676 1794 1638 152 | /home/wynmew/data/downloads/danbooru2018/original/0016/2067016.png 161 3 388 258 226 254 153 | /home/wynmew/data/downloads/danbooru2018/original/0016/911016.jpg 208 16 521 384 313 367 154 | /home/wynmew/data/downloads/danbooru2018/original/0016/1559016.jpg 325 2 649 308 323 305 155 | /home/wynmew/data/downloads/danbooru2018/original/0016/122016.jpg 848 124 1315 672 467 548 156 | /home/wynmew/data/downloads/danbooru2018/original/0016/1655016.jpg 365 77 1739 1358 1373 1280 157 | /home/wynmew/data/downloads/danbooru2018/original/0016/937016.jpg 915 266 1247 650 332 384 158 | /home/wynmew/data/downloads/danbooru2018/original/0016/2694016.jpg 249 51 468 271 219 220 159 | /home/wynmew/data/downloads/danbooru2018/original/0016/249016.jpg 223 13 455 243 232 230 160 | /home/wynmew/data/downloads/danbooru2018/original/0016/707016.jpg 180 25 362 242 182 216 161 | /home/wynmew/data/downloads/danbooru2018/original/0016/2120016.png 388 11 817 354 429 343 162 | /home/wynmew/data/downloads/danbooru2018/original/0016/1522016.png 420 93 819 525 399 432 163 | /home/wynmew/data/downloads/danbooru2018/original/0016/1378016.jpg 610 180 1867 1653 1256 1472 164 | /home/wynmew/data/downloads/danbooru2018/original/0016/3020016.png 536 10 1019 523 483 512 165 | /home/wynmew/data/downloads/danbooru2018/original/0016/2536016.jpg 249 1 499 258 249 257 166 | /home/wynmew/data/downloads/danbooru2018/original/0016/1614016.jpg 185 82 448 376 263 293 167 | /home/wynmew/data/downloads/danbooru2018/original/0016/63016.jpg 398 49 598 248 199 198 168 | /home/wynmew/data/downloads/danbooru2018/original/0016/1823016.jpg 236 133 427 340 191 206 169 | /home/wynmew/data/downloads/danbooru2018/original/0016/2055016.jpg 196 24 399 246 202 222 170 | /home/wynmew/data/downloads/danbooru2018/original/0016/2681016.jpg 280 19 796 543 516 524 171 | /home/wynmew/data/downloads/danbooru2018/original/0016/909016.jpg 469 200 731 446 261 245 172 | /home/wynmew/data/downloads/danbooru2018/original/0016/2859016.jpg 217 65 606 427 389 362 173 | /home/wynmew/data/downloads/danbooru2018/original/0016/273016.jpg 187 12 447 279 260 266 174 | /home/wynmew/data/downloads/danbooru2018/original/0016/884016.jpg 203 127 494 432 291 304 175 | /home/wynmew/data/downloads/danbooru2018/original/0016/1373016.jpg 197 109 368 314 171 204 176 | /home/wynmew/data/downloads/danbooru2018/original/0016/1647016.jpg 228 212 598 609 369 397 177 | /home/wynmew/data/downloads/danbooru2018/original/0016/809016.png 496 26 716 317 220 290 178 | /home/wynmew/data/downloads/danbooru2018/original/0016/1136016.jpg 154 6 325 199 171 193 179 | /home/wynmew/data/downloads/danbooru2018/original/0016/2379016.png 269 51 462 264 192 212 180 | /home/wynmew/data/downloads/danbooru2018/original/0016/1321016.jpg 434 13 1160 733 726 719 181 | /home/wynmew/data/downloads/danbooru2018/original/0016/1679016.png 279 203 601 507 322 303 182 | /home/wynmew/data/downloads/danbooru2018/original/0016/3302016.jpg 292 98 877 734 584 636 183 | /home/wynmew/data/downloads/danbooru2018/original/0016/2746016.jpg 265 298 662 724 396 425 184 | /home/wynmew/data/downloads/danbooru2018/original/0016/1174016.jpg 325 2 632 322 307 319 185 | /home/wynmew/data/downloads/danbooru2018/original/0016/294016.jpg 270 158 416 310 145 152 186 | /home/wynmew/data/downloads/danbooru2018/original/0016/2505016.jpg 267 12 495 256 228 244 187 | /home/wynmew/data/downloads/danbooru2018/original/0016/1787016.jpg 259 40 572 358 312 317 188 | /home/wynmew/data/downloads/danbooru2018/original/0016/3051016.png 39 58 375 375 336 317 189 | /home/wynmew/data/downloads/danbooru2018/original/0016/2155016.png 217 1 526 306 309 305 190 | /home/wynmew/data/downloads/danbooru2018/original/0016/1395016.jpg 10 17 227 234 217 216 191 | /home/wynmew/data/downloads/danbooru2018/original/0016/2330016.jpg 54 38 275 298 221 260 192 | /home/wynmew/data/downloads/danbooru2018/original/0016/833016.png 289 56 673 510 384 454 193 | /home/wynmew/data/downloads/danbooru2018/original/0016/434016.png 202 59 445 297 243 237 194 | /home/wynmew/data/downloads/danbooru2018/original/0016/3135016.jpg 267 100 728 638 460 537 195 | /home/wynmew/data/downloads/danbooru2018/original/0016/1572016.png 338 163 602 436 263 272 196 | /home/wynmew/data/downloads/danbooru2018/original/0016/181016.jpg 103 21 265 198 162 177 197 | /home/wynmew/data/downloads/danbooru2018/original/0016/2097016.jpg 268 13 459 230 191 217 198 | /home/wynmew/data/downloads/danbooru2018/original/0016/1221016.jpg 771 2 1227 422 456 420 199 | /home/wynmew/data/downloads/danbooru2018/original/0016/2483016.png 2074 437 2545 854 471 417 200 | /home/wynmew/data/downloads/danbooru2018/original/0016/1802016.png 534 568 862 1034 327 465 201 | /home/wynmew/data/downloads/danbooru2018/original/0016/886016.jpg 664 554 1006 974 341 419 202 | /home/wynmew/data/downloads/danbooru2018/original/0016/2965016.jpg 283 10 553 285 269 274 203 | /home/wynmew/data/downloads/danbooru2018/original/0016/2342016.png 47 29 573 584 525 555 204 | /home/wynmew/data/downloads/danbooru2018/original/0016/3096016.png 117 5 502 436 384 431 205 | /home/wynmew/data/downloads/danbooru2018/original/0016/1490016.jpg 574 105 1252 805 678 700 206 | /home/wynmew/data/downloads/danbooru2018/original/0016/955016.jpg 167 17 415 291 248 274 207 | /home/wynmew/data/downloads/danbooru2018/original/0016/2975016.jpg 469 108 1066 658 596 550 208 | /home/wynmew/data/downloads/danbooru2018/original/0016/2031016.png 88 3 343 303 255 299 209 | /home/wynmew/data/downloads/danbooru2018/original/0016/2573016.png 768 191 1280 794 511 603 210 | /home/wynmew/data/downloads/danbooru2018/original/0016/2581016.jpg 256 67 1321 1118 1064 1051 211 | /home/wynmew/data/downloads/danbooru2018/original/0016/2126016.jpg 191 3 463 264 272 260 212 | /home/wynmew/data/downloads/danbooru2018/original/0016/2613016.jpg 340 43 640 345 300 302 213 | /home/wynmew/data/downloads/danbooru2018/original/0016/34016.jpg 228 43 385 218 156 174 214 | /home/wynmew/data/downloads/danbooru2018/original/0016/2650016.jpg 336 354 1284 1375 948 1021 215 | /home/wynmew/data/downloads/danbooru2018/original/0016/1706016.png 247 53 456 264 208 210 216 | /home/wynmew/data/downloads/danbooru2018/original/0016/3005016.png 233 57 384 211 150 154 217 | /home/wynmew/data/downloads/danbooru2018/original/0016/1640016.png 376 63 597 291 221 227 218 | /home/wynmew/data/downloads/danbooru2018/original/0016/1995016.png 344 14 641 332 296 318 219 | /home/wynmew/data/downloads/danbooru2018/original/0016/2427016.jpg 37 60 455 452 418 392 220 | /home/wynmew/data/downloads/danbooru2018/original/0016/2343016.png 998 74 1217 345 219 270 221 | /home/wynmew/data/downloads/danbooru2018/original/0016/2115016.png 165 22 446 329 281 306 222 | /home/wynmew/data/downloads/danbooru2018/original/0016/148016.jpg 241 4 486 219 244 214 223 | /home/wynmew/data/downloads/danbooru2018/original/0016/1056016.jpg 173 147 507 504 334 356 224 | /home/wynmew/data/downloads/danbooru2018/original/0016/355016.jpg 719 362 1559 1150 840 788 225 | /home/wynmew/data/downloads/danbooru2018/original/0016/2569016.png 250 63 527 379 277 316 226 | /home/wynmew/data/downloads/danbooru2018/original/0016/2211016.png 471 101 2053 1631 1581 1530 227 | /home/wynmew/data/downloads/danbooru2018/original/0016/1448016.jpg 194 89 395 273 201 184 228 | /home/wynmew/data/downloads/danbooru2018/original/0016/221016.jpg 314 19 517 222 202 203 229 | /home/wynmew/data/downloads/danbooru2018/original/0016/2761016.jpg 26 13 368 319 342 306 230 | /home/wynmew/data/downloads/danbooru2018/original/0016/1249016.png 206 89 404 285 198 196 231 | /home/wynmew/data/downloads/danbooru2018/original/0016/828016.jpg 426 127 626 390 200 262 232 | /home/wynmew/data/downloads/danbooru2018/original/0016/1150016.jpg 1377 8 2003 708 626 699 233 | /home/wynmew/data/downloads/danbooru2018/original/0016/2450016.png 86 5 719 642 632 636 234 | /home/wynmew/data/downloads/danbooru2018/original/0016/2698016.jpg 472 44 692 263 219 218 235 | /home/wynmew/data/downloads/danbooru2018/original/0016/3178016.png 401 31 1341 1084 939 1052 236 | /home/wynmew/data/downloads/danbooru2018/original/0016/1212016.jpg 307 130 481 291 174 160 237 | /home/wynmew/data/downloads/danbooru2018/original/0016/1651016.png 254 5 492 247 238 242 238 | /home/wynmew/data/downloads/danbooru2018/original/0016/2169016.jpg 81 16 204 134 122 117 239 | /home/wynmew/data/downloads/danbooru2018/original/0016/182016.jpg 192 4 284 110 92 106 240 | /home/wynmew/data/downloads/danbooru2018/original/0016/1972016.jpg 99 6 346 261 246 254 241 | /home/wynmew/data/downloads/danbooru2018/original/0016/305016.jpg 258 11 580 326 321 314 242 | /home/wynmew/data/downloads/danbooru2018/original/0016/1187016.jpg 324 100 514 338 189 238 243 | /home/wynmew/data/downloads/danbooru2018/original/0016/639016.jpg 101 41 393 379 292 337 244 | /home/wynmew/data/downloads/danbooru2018/original/0016/1958016.png 172 122 385 315 212 193 245 | /home/wynmew/data/downloads/danbooru2018/original/0016/643016.jpg 155 14 259 138 103 124 246 | /home/wynmew/data/downloads/danbooru2018/original/0016/2145016.png 125 21 434 298 309 276 247 | /home/wynmew/data/downloads/danbooru2018/original/0016/263016.jpg 133 10 377 260 243 250 248 | /home/wynmew/data/downloads/danbooru2018/original/0016/2704016.jpg 306 49 555 368 248 319 249 | /home/wynmew/data/downloads/danbooru2018/original/0016/2293016.png 161 17 362 228 201 210 250 | /home/wynmew/data/downloads/danbooru2018/original/0016/3027016.jpg 928 22 1329 435 401 412 251 | /home/wynmew/data/downloads/danbooru2018/original/0016/3186016.jpg 137 56 488 441 350 384 252 | /home/wynmew/data/downloads/danbooru2018/original/0016/2185016.jpg 219 71 618 478 398 407 253 | /home/wynmew/data/downloads/danbooru2018/original/0016/2972016.jpg 97 97 275 288 178 190 254 | /home/wynmew/data/downloads/danbooru2018/original/0016/1710016.jpg 113 121 675 800 561 678 255 | /home/wynmew/data/downloads/danbooru2018/original/0016/215016.jpg 166 57 355 268 189 210 256 | /home/wynmew/data/downloads/danbooru2018/original/0016/3308016.png 448 255 630 466 181 211 257 | /home/wynmew/data/downloads/danbooru2018/original/0016/218016.jpg 169 42 629 462 459 420 258 | /home/wynmew/data/downloads/danbooru2018/original/0016/2482016.jpg 76 0 482 382 405 381 259 | /home/wynmew/data/downloads/danbooru2018/original/0016/1189016.jpg 604 61 1026 500 422 438 260 | /home/wynmew/data/downloads/danbooru2018/original/0016/1674016.jpg 226 15 471 303 244 287 261 | /home/wynmew/data/downloads/danbooru2018/original/0016/1774016.jpg 243 151 423 353 179 201 262 | /home/wynmew/data/downloads/danbooru2018/original/0016/1077016.png 355 4 764 428 408 424 263 | /home/wynmew/data/downloads/danbooru2018/original/0016/1429016.jpg 515 190 832 556 316 366 264 | /home/wynmew/data/downloads/danbooru2018/original/0016/2534016.jpg 436 76 768 426 332 349 265 | /home/wynmew/data/downloads/danbooru2018/original/0016/1585016.jpg 13 34 447 480 433 446 266 | /home/wynmew/data/downloads/danbooru2018/original/0016/2365016.png 227 69 573 461 346 391 267 | /home/wynmew/data/downloads/danbooru2018/original/0016/823016.jpg 395 413 506 525 111 111 268 | /home/wynmew/data/downloads/danbooru2018/original/0016/1289016.jpg 379 79 638 346 259 267 269 | /home/wynmew/data/downloads/danbooru2018/original/0016/2369016.jpg 532 206 790 467 257 260 270 | /home/wynmew/data/downloads/danbooru2018/original/0016/905016.jpg 930 24 1304 422 373 397 271 | /home/wynmew/data/downloads/danbooru2018/original/0016/3278016.jpg 150 79 1184 1121 1033 1042 272 | /home/wynmew/data/downloads/danbooru2018/original/0016/2675016.jpg 353 28 880 532 527 503 273 | /home/wynmew/data/downloads/danbooru2018/original/0016/1631016.jpg 208 235 678 578 469 343 274 | /home/wynmew/data/downloads/danbooru2018/original/0016/2377016.jpg 331 117 553 331 222 213 275 | /home/wynmew/data/downloads/danbooru2018/original/0016/2121016.jpg 157 3 575 402 418 399 276 | /home/wynmew/data/downloads/danbooru2018/original/0016/2848016.jpg 262 43 669 448 406 404 277 | /home/wynmew/data/downloads/danbooru2018/original/0016/1273016.jpg 279 30 748 527 468 496 278 | /home/wynmew/data/downloads/danbooru2018/original/0016/3275016.jpg 160 54 500 503 340 449 279 | /home/wynmew/data/downloads/danbooru2018/original/0016/328016.jpg 581 38 719 229 138 190 280 | /home/wynmew/data/downloads/danbooru2018/original/0016/1711016.jpg 216 31 521 382 304 350 281 | /home/wynmew/data/downloads/danbooru2018/original/0016/345016.jpg 365 118 684 528 319 410 282 | /home/wynmew/data/downloads/danbooru2018/original/0016/624016.jpg 101 36 313 253 211 216 283 | /home/wynmew/data/downloads/danbooru2018/original/0016/284016.jpg 265 58 553 352 288 293 284 | /home/wynmew/data/downloads/danbooru2018/original/0016/1354016.jpg 282 19 445 216 163 196 285 | /home/wynmew/data/downloads/danbooru2018/original/0016/3032016.jpg 1023 108 1588 795 565 686 286 | /home/wynmew/data/downloads/danbooru2018/original/0016/2754016.jpg 297 73 1896 1863 1598 1790 287 | /home/wynmew/data/downloads/danbooru2018/original/0016/3097016.jpg 262 23 481 277 219 253 288 | /home/wynmew/data/downloads/danbooru2018/original/0016/1194016.png 94 26 504 433 409 407 289 | /home/wynmew/data/downloads/danbooru2018/original/0016/1509016.jpg 267 4 480 246 212 241 290 | /home/wynmew/data/downloads/danbooru2018/original/0016/3221016.jpg 388 64 642 382 253 317 291 | /home/wynmew/data/downloads/danbooru2018/original/0016/2042016.png 211 15 378 226 166 211 292 | /home/wynmew/data/downloads/danbooru2018/original/0016/1020016.jpg 236 18 569 366 333 348 293 | /home/wynmew/data/downloads/danbooru2018/original/0016/456016.jpg 257 87 411 242 153 155 294 | /home/wynmew/data/downloads/danbooru2018/original/0016/2050016.png 139 81 358 312 219 230 295 | /home/wynmew/data/downloads/danbooru2018/original/0016/2319016.png 232 40 639 454 406 413 296 | /home/wynmew/data/downloads/danbooru2018/original/0016/173016.jpg 457 18 891 470 434 451 297 | /home/wynmew/data/downloads/danbooru2018/original/0016/1247016.jpg 271 178 490 397 218 219 298 | /home/wynmew/data/downloads/danbooru2018/original/0016/9016.jpg 349 132 639 426 290 293 299 | /home/wynmew/data/downloads/danbooru2018/original/0016/2817016.png 151 86 439 364 288 277 300 | /home/wynmew/data/downloads/danbooru2018/original/0016/255016.jpg 627 36 922 298 295 261 301 | /home/wynmew/data/downloads/danbooru2018/original/0016/2466016.jpg 633 51 1865 1168 1231 1117 302 | /home/wynmew/data/downloads/danbooru2018/original/0016/545016.jpg 332 11 757 409 424 397 303 | /home/wynmew/data/downloads/danbooru2018/original/0016/684016.jpg 269 10 563 321 294 311 304 | /home/wynmew/data/downloads/danbooru2018/original/0016/235016.jpg 136 31 259 163 123 131 305 | /home/wynmew/data/downloads/danbooru2018/original/0016/2732016.jpg 316 115 543 422 227 307 306 | /home/wynmew/data/downloads/danbooru2018/original/0016/2375016.jpg 391 64 664 379 272 315 307 | /home/wynmew/data/downloads/danbooru2018/original/0016/773016.jpg 195 68 509 403 313 335 308 | /home/wynmew/data/downloads/danbooru2018/original/0016/2129016.jpg 378 22 790 464 411 441 309 | /home/wynmew/data/downloads/danbooru2018/original/0016/2285016.jpg 721 189 1108 567 386 378 310 | /home/wynmew/data/downloads/danbooru2018/original/0016/908016.png 2 58 556 638 554 580 311 | /home/wynmew/data/downloads/danbooru2018/original/0016/1000016.png 376 31 575 248 199 216 312 | /home/wynmew/data/downloads/danbooru2018/original/0016/679016.jpg 324 19 592 290 267 270 313 | /home/wynmew/data/downloads/danbooru2018/original/0016/609016.jpg 444 62 636 255 191 192 314 | /home/wynmew/data/downloads/danbooru2018/original/0016/1661016.jpg 196 38 438 262 242 224 315 | /home/wynmew/data/downloads/danbooru2018/original/0016/2143016.jpg 157 248 487 589 330 340 316 | /home/wynmew/data/downloads/danbooru2018/original/0016/914016.jpg 161 48 460 331 299 282 317 | /home/wynmew/data/downloads/danbooru2018/original/0016/1238016.jpg 185 58 407 295 222 237 318 | /home/wynmew/data/downloads/danbooru2018/original/0016/1278016.jpg 520 43 709 223 188 179 319 | /home/wynmew/data/downloads/danbooru2018/original/0016/289016.jpg 124 6 372 239 247 232 320 | /home/wynmew/data/downloads/danbooru2018/original/0016/1250016.jpg 183 12 543 385 360 372 321 | /home/wynmew/data/downloads/danbooru2018/original/0016/197016.jpg 218 48 737 615 518 566 322 | /home/wynmew/data/downloads/danbooru2018/original/0016/1685016.png 896 327 1780 1145 883 817 323 | /home/wynmew/data/downloads/danbooru2018/original/0016/319016.jpg 289 104 473 278 184 174 324 | /home/wynmew/data/downloads/danbooru2018/original/0016/3073016.png 627 69 1357 820 730 750 325 | /home/wynmew/data/downloads/danbooru2018/original/0016/1261016.png 44 114 487 560 442 445 326 | /home/wynmew/data/downloads/danbooru2018/original/0016/1616016.png 893 71 1779 981 886 910 327 | /home/wynmew/data/downloads/danbooru2018/original/0016/1226016.jpg 325 424 629 744 303 320 328 | /home/wynmew/data/downloads/danbooru2018/original/0016/19016.jpg 124 5 574 419 449 413 329 | /home/wynmew/data/downloads/danbooru2018/original/0016/727016.png 1027 18 1801 647 774 629 330 | /home/wynmew/data/downloads/danbooru2018/original/0016/2657016.png 542 166 1561 1011 1018 845 331 | /home/wynmew/data/downloads/danbooru2018/original/0016/1686016.jpg 204 26 475 348 270 321 332 | /home/wynmew/data/downloads/danbooru2018/original/0016/3101016.jpg 287 145 724 638 437 493 333 | /home/wynmew/data/downloads/danbooru2018/original/0016/446016.jpg 44 88 239 271 194 183 334 | /home/wynmew/data/downloads/danbooru2018/original/0016/1216016.jpg 221 3 433 220 211 217 335 | /home/wynmew/data/downloads/danbooru2018/original/0016/1996016.png 167 119 496 404 328 285 336 | /home/wynmew/data/downloads/danbooru2018/original/0016/1162016.jpg 232 133 891 746 658 612 337 | /home/wynmew/data/downloads/danbooru2018/original/0016/2978016.jpg 187 3 586 492 399 488 338 | /home/wynmew/data/downloads/danbooru2018/original/0016/2955016.jpg 268 54 644 484 376 429 339 | /home/wynmew/data/downloads/danbooru2018/original/0016/751016.jpg 164 101 554 518 390 416 340 | /home/wynmew/data/downloads/danbooru2018/original/0016/1865016.jpg 234 10 609 420 375 410 341 | /home/wynmew/data/downloads/danbooru2018/original/0016/585016.jpg 215 63 375 213 159 150 342 | /home/wynmew/data/downloads/danbooru2018/original/0016/459016.jpg 162 28 393 298 230 269 343 | /home/wynmew/data/downloads/danbooru2018/original/0016/736016.png 265 4 719 447 453 443 344 | /home/wynmew/data/downloads/danbooru2018/original/0016/3024016.png 202 47 435 314 233 266 345 | /home/wynmew/data/downloads/danbooru2018/original/0016/3255016.jpg 186 28 518 420 332 391 346 | /home/wynmew/data/downloads/danbooru2018/original/0016/743016.png 198 95 422 320 224 225 347 | /home/wynmew/data/downloads/danbooru2018/original/0016/488016.jpg 253 20 544 330 290 309 348 | /home/wynmew/data/downloads/danbooru2018/original/0016/1950016.png 200 38 584 461 383 423 349 | /home/wynmew/data/downloads/danbooru2018/original/0016/3243016.jpg 155 69 631 601 475 532 350 | /home/wynmew/data/downloads/danbooru2018/original/0016/2066016.jpg 195 26 511 382 316 355 351 | /home/wynmew/data/downloads/danbooru2018/original/0016/1845016.png 263 41 518 281 255 240 352 | /home/wynmew/data/downloads/danbooru2018/original/0016/2942016.png 179 80 495 414 315 333 353 | /home/wynmew/data/downloads/danbooru2018/original/0016/3165016.png 46 34 242 213 195 178 354 | /home/wynmew/data/downloads/danbooru2018/original/0016/2669016.jpg 107 5 612 486 504 480 355 | /home/wynmew/data/downloads/danbooru2018/original/0016/1500016.jpg 464 62 783 387 318 325 356 | /home/wynmew/data/downloads/danbooru2018/original/0016/3285016.jpg 361 107 816 663 455 556 357 | /home/wynmew/data/downloads/danbooru2018/original/0016/1342016.jpg 268 170 501 423 232 253 358 | /home/wynmew/data/downloads/danbooru2018/original/0016/2710016.jpg 985 372 2035 1444 1049 1072 359 | /home/wynmew/data/downloads/danbooru2018/original/0016/2919016.png 615 72 923 440 307 367 360 | /home/wynmew/data/downloads/danbooru2018/original/0016/2274016.png 180 105 395 358 214 252 361 | /home/wynmew/data/downloads/danbooru2018/original/0016/1639016.jpg 1245 7 1888 588 642 580 362 | /home/wynmew/data/downloads/danbooru2018/original/0016/1460016.jpg 234 31 462 291 228 260 363 | /home/wynmew/data/downloads/danbooru2018/original/0016/1367016.jpg 12 5 420 367 407 362 364 | /home/wynmew/data/downloads/danbooru2018/original/0016/2299016.png 233 78 409 259 175 180 365 | /home/wynmew/data/downloads/danbooru2018/original/0016/3219016.jpg 287 16 532 247 244 230 366 | /home/wynmew/data/downloads/danbooru2018/original/0016/957016.jpg 284 98 540 357 255 259 367 | /home/wynmew/data/downloads/danbooru2018/original/0016/1715016.jpg 87 7 835 722 748 714 368 | /home/wynmew/data/downloads/danbooru2018/original/0016/2170016.png 83 59 1158 965 1075 906 369 | /home/wynmew/data/downloads/danbooru2018/original/0016/2951016.jpg 736 69 1127 485 390 415 370 | /home/wynmew/data/downloads/danbooru2018/original/0016/2140016.jpg 388 10 827 490 439 480 371 | /home/wynmew/data/downloads/danbooru2018/original/0016/1365016.jpg 1341 27 3495 2321 2153 2294 372 | /home/wynmew/data/downloads/danbooru2018/original/0016/1129016.png 162 129 423 412 260 282 373 | /home/wynmew/data/downloads/danbooru2018/original/0016/2930016.png 386 72 827 564 441 492 374 | /home/wynmew/data/downloads/danbooru2018/original/0016/2535016.png 105 35 368 307 262 272 375 | /home/wynmew/data/downloads/danbooru2018/original/0016/2778016.jpg 59 36 337 354 278 318 376 | /home/wynmew/data/downloads/danbooru2018/original/0016/818016.jpg 449 62 653 270 204 207 377 | /home/wynmew/data/downloads/danbooru2018/original/0016/425016.jpg 183 47 379 243 196 196 378 | /home/wynmew/data/downloads/danbooru2018/original/0016/703016.jpg 241 24 459 250 218 226 379 | /home/wynmew/data/downloads/danbooru2018/original/0016/1861016.jpg 307 57 738 486 430 429 380 | /home/wynmew/data/downloads/danbooru2018/original/0016/2666016.png 200 88 517 471 316 382 381 | /home/wynmew/data/downloads/danbooru2018/original/0016/2855016.jpg 202 24 1021 815 818 790 382 | /home/wynmew/data/downloads/danbooru2018/original/0016/3254016.png 325 54 720 447 394 393 383 | /home/wynmew/data/downloads/danbooru2018/original/0016/1383016.jpg 201 98 588 514 386 415 384 | /home/wynmew/data/downloads/danbooru2018/original/0016/2563016.png 701 3 970 253 268 250 385 | /home/wynmew/data/downloads/danbooru2018/original/0016/2590016.jpg 243 10 642 432 399 421 386 | /home/wynmew/data/downloads/danbooru2018/original/0016/513016.jpg 117 5 546 416 428 411 387 | /home/wynmew/data/downloads/danbooru2018/original/0016/2134016.jpg 300 151 726 565 426 413 388 | /home/wynmew/data/downloads/danbooru2018/original/0016/1423016.jpg 142 68 348 272 206 204 389 | /home/wynmew/data/downloads/danbooru2018/original/0016/2999016.jpg 130 7 718 559 587 551 390 | /home/wynmew/data/downloads/danbooru2018/original/0016/1049016.png 258 27 584 362 325 335 391 | /home/wynmew/data/downloads/danbooru2018/original/0016/1630016.jpg 334 38 699 415 364 377 392 | /home/wynmew/data/downloads/danbooru2018/original/0016/1920016.png 264 37 580 395 315 358 393 | /home/wynmew/data/downloads/danbooru2018/original/0016/2041016.jpg 547 93 738 305 190 212 394 | /home/wynmew/data/downloads/danbooru2018/original/0016/3094016.jpg 242 16 548 357 305 340 395 | /home/wynmew/data/downloads/danbooru2018/original/0016/2747016.png 200 227 1568 1729 1367 1501 396 | /home/wynmew/data/downloads/danbooru2018/original/0016/2724016.jpg 287 61 465 247 178 186 397 | /home/wynmew/data/downloads/danbooru2018/original/0016/1960016.jpg 24 97 250 329 226 231 398 | /home/wynmew/data/downloads/danbooru2018/original/0016/1412016.png 628 60 910 358 282 298 399 | /home/wynmew/data/downloads/danbooru2018/original/0016/1038016.jpg 154 333 325 506 170 173 400 | /home/wynmew/data/downloads/danbooru2018/original/0016/904016.jpg 277 63 559 345 282 282 401 | /home/wynmew/data/downloads/danbooru2018/original/0016/320016.png 66 121 314 364 248 242 402 | /home/wynmew/data/downloads/danbooru2018/original/0016/2040016.png 329 34 604 295 275 261 403 | /home/wynmew/data/downloads/danbooru2018/original/0016/547016.jpg 322 17 960 651 638 633 404 | /home/wynmew/data/downloads/danbooru2018/original/0016/411016.jpg 1274 1076 2652 2567 1378 1491 405 | /home/wynmew/data/downloads/danbooru2018/original/0016/1355016.png 140 17 330 207 190 190 406 | /home/wynmew/data/downloads/danbooru2018/original/0016/2135016.jpg 241 79 410 265 169 186 407 | /home/wynmew/data/downloads/danbooru2018/original/0016/2415016.jpg 172 15 391 221 218 205 408 | /home/wynmew/data/downloads/danbooru2018/original/0016/2085016.png 1054 239 1519 708 465 468 409 | /home/wynmew/data/downloads/danbooru2018/original/0016/2500016.jpg 247 71 481 307 233 235 410 | /home/wynmew/data/downloads/danbooru2018/original/0016/2224016.jpg 195 67 499 367 303 300 411 | /home/wynmew/data/downloads/danbooru2018/original/0016/1636016.jpg 182 127 500 436 317 308 412 | /home/wynmew/data/downloads/danbooru2018/original/0016/1344016.jpg 660 200 1105 602 445 402 413 | /home/wynmew/data/downloads/danbooru2018/original/0016/1051016.jpg 37 3 286 212 249 209 414 | /home/wynmew/data/downloads/danbooru2018/original/0016/805016.jpg 167 11 498 310 330 299 415 | /home/wynmew/data/downloads/danbooru2018/original/0016/286016.jpg 219 100 369 233 149 133 416 | /home/wynmew/data/downloads/danbooru2018/original/0016/663016.jpg 2412 366 4116 2399 1703 2032 417 | /home/wynmew/data/downloads/danbooru2018/original/0016/107016.jpg 53 50 300 301 246 251 418 | /home/wynmew/data/downloads/danbooru2018/original/0016/2079016.jpg 335 98 883 589 547 491 419 | /home/wynmew/data/downloads/danbooru2018/original/0016/544016.jpg 82 81 428 475 346 393 420 | /home/wynmew/data/downloads/danbooru2018/original/0016/2957016.jpg 200 98 447 375 247 276 421 | /home/wynmew/data/downloads/danbooru2018/original/0016/168016.jpg 183 42 553 376 370 333 422 | /home/wynmew/data/downloads/danbooru2018/original/0016/2394016.png 535 150 834 573 298 423 423 | /home/wynmew/data/downloads/danbooru2018/original/0016/2826016.jpg 271 84 588 373 316 289 424 | /home/wynmew/data/downloads/danbooru2018/original/0016/623016.jpg 20 6 304 275 283 269 425 | /home/wynmew/data/downloads/danbooru2018/original/0016/117016.jpg 170 50 371 247 200 197 426 | /home/wynmew/data/downloads/danbooru2018/original/0016/2604016.png 580 574 1722 1630 1141 1056 427 | /home/wynmew/data/downloads/danbooru2018/original/0016/2127016.jpg 119 15 552 426 432 411 428 | /home/wynmew/data/downloads/danbooru2018/original/0016/3033016.jpg 464 126 955 623 491 496 429 | /home/wynmew/data/downloads/danbooru2018/original/0016/954016.jpg 149 64 524 435 375 371 430 | /home/wynmew/data/downloads/danbooru2018/original/0016/1518016.jpg 128 3 373 271 245 267 431 | /home/wynmew/data/downloads/danbooru2018/original/0016/2850016.jpg 819 67 1338 647 518 579 432 | /home/wynmew/data/downloads/danbooru2018/original/0016/2647016.jpg 416 54 635 292 219 238 433 | /home/wynmew/data/downloads/danbooru2018/original/0016/3037016.jpg 265 26 531 398 265 372 434 | /home/wynmew/data/downloads/danbooru2018/original/0016/3357016.png 271 50 706 506 435 456 435 | /home/wynmew/data/downloads/danbooru2018/original/0016/1375016.jpg 271 96 521 360 249 263 436 | /home/wynmew/data/downloads/danbooru2018/original/0016/1207016.jpg 297 82 639 408 342 326 437 | /home/wynmew/data/downloads/danbooru2018/original/0016/2800016.jpg 12 62 385 455 373 392 438 | /home/wynmew/data/downloads/danbooru2018/original/0016/2867016.png 608 76 1543 1077 935 1001 439 | /home/wynmew/data/downloads/danbooru2018/original/0016/3313016.png 318 107 654 436 335 328 440 | /home/wynmew/data/downloads/danbooru2018/original/0016/1985016.png 435 117 829 503 393 385 441 | /home/wynmew/data/downloads/danbooru2018/original/0016/452016.jpg 74 45 305 251 230 206 442 | /home/wynmew/data/downloads/danbooru2018/original/0016/2577016.jpg 121 25 694 521 572 496 443 | /home/wynmew/data/downloads/danbooru2018/original/0016/2745016.jpg 148 95 719 666 571 571 444 | /home/wynmew/data/downloads/danbooru2018/original/0016/844016.jpg 353 22 724 403 370 381 445 | /home/wynmew/data/downloads/danbooru2018/original/0016/983016.jpg 734 217 1232 798 498 581 446 | /home/wynmew/data/downloads/danbooru2018/original/0016/2380016.jpg 353 44 561 278 207 233 447 | /home/wynmew/data/downloads/danbooru2018/original/0016/2876016.jpg 552 72 857 374 305 301 448 | /home/wynmew/data/downloads/danbooru2018/original/0016/2791016.jpg 206 26 482 325 275 298 449 | /home/wynmew/data/downloads/danbooru2018/original/0016/124016.jpg 162 11 389 254 227 242 450 | /home/wynmew/data/downloads/danbooru2018/original/0016/2316016.png 343 8 714 440 371 431 451 | /home/wynmew/data/downloads/danbooru2018/original/0016/2580016.jpg 456 1227 1604 2651 1148 1423 452 | /home/wynmew/data/downloads/danbooru2018/original/0016/1132016.jpg 212 88 409 307 197 219 453 | /home/wynmew/data/downloads/danbooru2018/original/0016/2156016.jpg 149 21 376 293 226 271 454 | /home/wynmew/data/downloads/danbooru2018/original/0016/814016.jpg 499 74 705 309 206 235 455 | /home/wynmew/data/downloads/danbooru2018/original/0016/1109016.jpg 13 6 239 248 225 241 456 | /home/wynmew/data/downloads/danbooru2018/original/0016/336016.jpg 96 36 262 201 166 164 457 | /home/wynmew/data/downloads/danbooru2018/original/0016/2071016.jpg 685 118 1333 850 647 732 458 | /home/wynmew/data/downloads/danbooru2018/original/0016/163016.jpg 8 13 198 185 189 172 459 | /home/wynmew/data/downloads/danbooru2018/original/0016/1282016.jpg 447 58 668 249 220 190 460 | /home/wynmew/data/downloads/danbooru2018/original/0016/917016.jpg 177 81 453 336 275 254 461 | /home/wynmew/data/downloads/danbooru2018/original/0016/1991016.jpg 261 34 481 268 220 233 462 | /home/wynmew/data/downloads/danbooru2018/original/0016/2350016.jpg 113 71 403 396 290 324 463 | /home/wynmew/data/downloads/danbooru2018/original/0016/2146016.png 113 23 427 407 314 383 464 | /home/wynmew/data/downloads/danbooru2018/original/0016/3058016.png 271 34 605 338 333 304 465 | /home/wynmew/data/downloads/danbooru2018/original/0016/1146016.jpg 107 53 392 379 285 325 466 | /home/wynmew/data/downloads/danbooru2018/original/0016/781016.jpg 241 95 421 288 180 193 467 | /home/wynmew/data/downloads/danbooru2018/original/0016/3247016.png 269 54 656 438 386 383 468 | /home/wynmew/data/downloads/danbooru2018/original/0016/2296016.png 215 90 376 279 160 189 469 | /home/wynmew/data/downloads/danbooru2018/original/0016/383016.jpg 83 15 286 210 203 194 470 | /home/wynmew/data/downloads/danbooru2018/original/0016/642016.jpg 81 19 638 570 557 551 471 | /home/wynmew/data/downloads/danbooru2018/original/0016/2240016.jpg 456 15 1791 1393 1334 1378 472 | /home/wynmew/data/downloads/danbooru2018/original/0016/1335016.jpg 1155 169 1370 416 214 246 473 | /home/wynmew/data/downloads/danbooru2018/original/0016/1867016.jpg 174 30 482 357 308 327 474 | /home/wynmew/data/downloads/danbooru2018/original/0016/68016.jpg 258 75 452 316 193 240 475 | /home/wynmew/data/downloads/danbooru2018/original/0016/2235016.png 219 78 483 351 263 273 476 | /home/wynmew/data/downloads/danbooru2018/original/0016/2471016.jpg 153 74 388 354 235 279 477 | /home/wynmew/data/downloads/danbooru2018/original/0016/724016.jpg 431 58 691 387 259 329 478 | /home/wynmew/data/downloads/danbooru2018/original/0016/1938016.jpg 156 4 420 294 264 290 479 | /home/wynmew/data/downloads/danbooru2018/original/0016/3265016.jpg 421 111 735 480 314 369 480 | /home/wynmew/data/downloads/danbooru2018/original/0016/331016.png 422 81 595 263 172 182 481 | /home/wynmew/data/downloads/danbooru2018/original/0016/1041016.jpg 414 33 769 403 355 370 482 | /home/wynmew/data/downloads/danbooru2018/original/0016/1002016.jpg 205 6 421 257 215 250 483 | /home/wynmew/data/downloads/danbooru2018/original/0016/1822016.png 72 33 628 682 556 649 484 | /home/wynmew/data/downloads/danbooru2018/original/0016/1096016.jpg 573 105 1164 739 591 633 485 | /home/wynmew/data/downloads/danbooru2018/original/0016/2300016.png 351 147 579 397 228 250 486 | /home/wynmew/data/downloads/danbooru2018/original/0016/1147016.jpg 71 9 353 310 281 301 487 | /home/wynmew/data/downloads/danbooru2018/original/0016/55016.jpg 12 638 433 1051 420 413 488 | /home/wynmew/data/downloads/danbooru2018/original/0016/1326016.png 131 39 486 374 354 335 489 | /home/wynmew/data/downloads/danbooru2018/original/0016/2996016.jpg 458 151 1063 732 604 581 490 | /home/wynmew/data/downloads/danbooru2018/original/0016/3293016.png 124 32 529 427 405 395 491 | /home/wynmew/data/downloads/danbooru2018/original/0016/302016.jpg 120 23 329 237 209 214 492 | /home/wynmew/data/downloads/danbooru2018/original/0016/116016.jpg 103 10 284 184 181 173 493 | /home/wynmew/data/downloads/danbooru2018/original/0016/3044016.jpg 465 3 865 342 399 339 494 | /home/wynmew/data/downloads/danbooru2018/original/0016/685016.jpg 276 50 947 751 670 700 495 | /home/wynmew/data/downloads/danbooru2018/original/0016/2537016.png 336 28 574 283 237 255 496 | /home/wynmew/data/downloads/danbooru2018/original/0016/3109016.png 231 240 574 616 342 375 497 | /home/wynmew/data/downloads/danbooru2018/original/0016/1227016.jpg 459 75 656 307 196 231 498 | /home/wynmew/data/downloads/danbooru2018/original/0016/3129016.jpg 88 67 720 736 631 669 499 | /home/wynmew/data/downloads/danbooru2018/original/0016/1404016.jpg 238 125 622 570 383 444 500 | /home/wynmew/data/downloads/danbooru2018/original/0016/3110016.png 262 7 648 480 386 473 501 | /home/wynmew/data/downloads/danbooru2018/original/0016/150016.jpg 923 165 2259 1420 1336 1254 502 | /home/wynmew/data/downloads/danbooru2018/original/0016/693016.jpg 486 4 917 359 431 354 503 | /home/wynmew/data/downloads/danbooru2018/original/0016/2017016.jpg 211 74 621 473 409 398 504 | /home/wynmew/data/downloads/danbooru2018/original/0016/473016.jpg 249 82 458 329 208 247 505 | /home/wynmew/data/downloads/danbooru2018/original/0016/711016.jpg 12 24 246 242 233 218 506 | /home/wynmew/data/downloads/danbooru2018/original/0016/627016.jpg 197 17 372 201 175 183 507 | /home/wynmew/data/downloads/danbooru2018/original/0016/2801016.png 266 174 632 589 366 415 508 | /home/wynmew/data/downloads/danbooru2018/original/0016/1540016.png 485 243 1638 1553 1152 1309 509 | /home/wynmew/data/downloads/danbooru2018/original/0016/2230016.jpg 987 233 1531 811 543 577 510 | /home/wynmew/data/downloads/danbooru2018/original/0016/1520016.jpg 271 31 519 296 247 265 511 | /home/wynmew/data/downloads/danbooru2018/original/0016/2579016.jpg 270 325 445 519 175 193 512 | /home/wynmew/data/downloads/danbooru2018/original/0016/1131016.jpg 641 235 1429 1130 788 895 513 | /home/wynmew/data/downloads/danbooru2018/original/0016/232016.jpg 56 28 222 230 166 202 514 | /home/wynmew/data/downloads/danbooru2018/original/0016/2764016.jpg 185 50 462 322 277 272 515 | /home/wynmew/data/downloads/danbooru2018/original/0016/1632016.jpg 1049 28 3061 2011 2011 1982 516 | /home/wynmew/data/downloads/danbooru2018/original/0016/1366016.jpg 644 189 1272 944 628 754 517 | /home/wynmew/data/downloads/danbooru2018/original/0016/2521016.png 475 391 814 718 339 327 518 | /home/wynmew/data/downloads/danbooru2018/original/0016/2454016.jpg 200 66 703 616 503 550 519 | /home/wynmew/data/downloads/danbooru2018/original/0016/1918016.png 1082 456 1764 1246 682 789 520 | /home/wynmew/data/downloads/danbooru2018/original/0016/1314016.jpg 272 168 786 669 513 500 521 | /home/wynmew/data/downloads/danbooru2018/original/0016/3217016.jpg 57 188 307 402 250 214 522 | /home/wynmew/data/downloads/danbooru2018/original/0016/3107016.jpg 120 5 511 422 391 417 523 | /home/wynmew/data/downloads/danbooru2018/original/0016/588016.png 158 31 381 274 222 242 524 | /home/wynmew/data/downloads/danbooru2018/original/0016/1554016.png 261 37 428 206 166 168 525 | /home/wynmew/data/downloads/danbooru2018/original/0016/718016.jpg 317 262 473 433 155 170 526 | /home/wynmew/data/downloads/danbooru2018/original/0016/390016.jpg 230 50 407 234 176 184 527 | /home/wynmew/data/downloads/danbooru2018/original/0016/1143016.jpg 131 9 469 378 337 368 528 | /home/wynmew/data/downloads/danbooru2018/original/0016/2507016.png 327 81 684 501 357 419 529 | /home/wynmew/data/downloads/danbooru2018/original/0016/1477016.png 135 63 544 481 408 418 530 | /home/wynmew/data/downloads/danbooru2018/original/0016/2884016.png 253 16 663 453 409 437 531 | /home/wynmew/data/downloads/danbooru2018/original/0016/76016.jpg 449 45 719 362 270 317 532 | /home/wynmew/data/downloads/danbooru2018/original/0016/2335016.jpg 215 74 555 429 339 355 533 | /home/wynmew/data/downloads/danbooru2018/original/0016/901016.jpg 241 107 559 432 318 324 534 | /home/wynmew/data/downloads/danbooru2018/original/0016/1919016.jpg 156 88 577 481 420 393 535 | /home/wynmew/data/downloads/danbooru2018/original/0016/603016.jpg 117 32 417 294 300 261 536 | /home/wynmew/data/downloads/danbooru2018/original/0016/610016.png 236 156 536 478 299 322 537 | /home/wynmew/data/downloads/danbooru2018/original/0016/3269016.jpg 394 43 814 455 420 411 538 | /home/wynmew/data/downloads/danbooru2018/original/0016/2917016.jpg 38 127 431 467 393 339 539 | /home/wynmew/data/downloads/danbooru2018/original/0016/195016.jpg 113 24 351 256 238 231 540 | /home/wynmew/data/downloads/danbooru2018/original/0016/2837016.png 631 56 933 356 302 299 541 | /home/wynmew/data/downloads/danbooru2018/original/0016/2741016.png 206 3 594 344 388 340 542 | /home/wynmew/data/downloads/danbooru2018/original/0016/2158016.jpg 186 46 501 399 315 352 543 | /home/wynmew/data/downloads/danbooru2018/original/0016/2739016.jpg 155 13 352 226 196 212 544 | /home/wynmew/data/downloads/danbooru2018/original/0016/1434016.jpg 71 7 773 745 701 738 545 | /home/wynmew/data/downloads/danbooru2018/original/0016/3023016.jpg 94 28 500 345 405 317 546 | /home/wynmew/data/downloads/danbooru2018/original/0016/2966016.png 189 52 582 416 392 363 547 | /home/wynmew/data/downloads/danbooru2018/original/0016/1007016.jpg 165 32 526 335 361 303 548 | /home/wynmew/data/downloads/danbooru2018/original/0016/1202016.png 106 44 315 235 209 191 549 | /home/wynmew/data/downloads/danbooru2018/original/0016/936016.jpg 238 10 795 585 556 575 550 | /home/wynmew/data/downloads/danbooru2018/original/0016/1967016.jpg 387 30 703 322 316 292 551 | /home/wynmew/data/downloads/danbooru2018/original/0016/3249016.png 248 58 639 488 390 430 552 | /home/wynmew/data/downloads/danbooru2018/original/0016/1751016.png 441 94 742 408 301 313 553 | /home/wynmew/data/downloads/danbooru2018/original/0016/3253016.jpg 1196 425 2603 1962 1406 1536 554 | /home/wynmew/data/downloads/danbooru2018/original/0016/872016.jpg 718 162 1159 617 441 455 555 | /home/wynmew/data/downloads/danbooru2018/original/0016/1421016.jpg 25 22 512 567 487 545 556 | /home/wynmew/data/downloads/danbooru2018/original/0016/2915016.jpg 291 185 1026 867 735 681 557 | /home/wynmew/data/downloads/danbooru2018/original/0016/2716016.jpg 325 16 726 556 401 539 558 | /home/wynmew/data/downloads/danbooru2018/original/0016/79016.jpg 204 47 625 454 420 406 559 | /home/wynmew/data/downloads/danbooru2018/original/0016/314016.png 136 203 534 640 397 436 560 | /home/wynmew/data/downloads/danbooru2018/original/0016/3105016.png 1724 142 2238 653 513 511 561 | /home/wynmew/data/downloads/danbooru2018/original/0016/2727016.jpg 241 103 857 785 616 681 562 | /home/wynmew/data/downloads/danbooru2018/original/0016/536016.jpg 110 5 331 256 220 251 563 | /home/wynmew/data/downloads/danbooru2018/original/0016/1824016.png 524 127 815 471 291 344 564 | /home/wynmew/data/downloads/danbooru2018/original/0016/342016.jpg 198 28 820 644 622 616 565 | /home/wynmew/data/downloads/danbooru2018/original/0016/953016.jpg 285 53 485 274 200 220 566 | /home/wynmew/data/downloads/danbooru2018/original/0016/1780016.png 576 104 980 533 403 429 567 | /home/wynmew/data/downloads/danbooru2018/original/0016/577016.jpg 301 29 471 206 169 176 568 | /home/wynmew/data/downloads/danbooru2018/original/0016/118016.jpeg 275 9 420 169 144 160 569 | /home/wynmew/data/downloads/danbooru2018/original/0016/1979016.jpg 235 28 465 248 230 219 570 | /home/wynmew/data/downloads/danbooru2018/original/0016/907016.jpg 640 263 1134 746 494 482 571 | /home/wynmew/data/downloads/danbooru2018/original/0016/1128016.jpg 323 10 615 299 291 289 572 | /home/wynmew/data/downloads/danbooru2018/original/0016/1675016.jpg 193 15 384 234 191 218 573 | /home/wynmew/data/downloads/danbooru2018/original/0016/3031016.jpg 148 24 397 303 248 279 574 | /home/wynmew/data/downloads/danbooru2018/original/0016/1870016.jpg 425 39 813 426 388 386 575 | /home/wynmew/data/downloads/danbooru2018/original/0016/6016.jpg 522 68 848 397 325 328 576 | /home/wynmew/data/downloads/danbooru2018/original/0016/625016.jpg 618 7 773 166 154 158 577 | /home/wynmew/data/downloads/danbooru2018/original/0016/3193016.jpg 334 200 788 680 454 479 578 | /home/wynmew/data/downloads/danbooru2018/original/0016/3108016.jpg 199 44 789 677 589 632 579 | /home/wynmew/data/downloads/danbooru2018/original/0016/3295016.jpg 235 57 692 540 457 483 580 | /home/wynmew/data/downloads/danbooru2018/original/0016/3241016.jpg 588 7 1027 474 438 466 581 | /home/wynmew/data/downloads/danbooru2018/original/0016/2154016.jpg 14 10 366 318 351 307 582 | /home/wynmew/data/downloads/danbooru2018/original/0016/2463016.jpg 184 76 381 319 196 242 583 | /home/wynmew/data/downloads/danbooru2018/original/0016/2263016.jpg 203 42 432 269 229 226 584 | /home/wynmew/data/downloads/danbooru2018/original/0016/2472016.jpg 210 31 454 314 244 283 585 | /home/wynmew/data/downloads/danbooru2018/original/0016/1724016.jpg 194 72 382 264 187 191 586 | /home/wynmew/data/downloads/danbooru2018/original/0016/2524016.png 380 155 634 434 253 279 587 | /home/wynmew/data/downloads/danbooru2018/original/0016/2205016.jpg 705 10 1218 573 513 562 588 | /home/wynmew/data/downloads/danbooru2018/original/0016/1726016.jpg 1106 360 1369 599 262 239 589 | /home/wynmew/data/downloads/danbooru2018/original/0016/1470016.jpg 237 280 477 542 240 261 590 | /home/wynmew/data/downloads/danbooru2018/original/0016/2672016.png 221 101 715 641 494 539 591 | /home/wynmew/data/downloads/danbooru2018/original/0016/74016.jpg 143 30 353 239 210 208 592 | /home/wynmew/data/downloads/danbooru2018/original/0016/2077016.png 271 85 499 333 227 248 593 | /home/wynmew/data/downloads/danbooru2018/original/0016/986016.jpg 894 254 1394 781 499 527 594 | /home/wynmew/data/downloads/danbooru2018/original/0016/3155016.png 191 8 339 172 148 164 595 | /home/wynmew/data/downloads/danbooru2018/original/0016/1809016.jpg 239 153 455 389 215 236 596 | /home/wynmew/data/downloads/danbooru2018/original/0016/2875016.jpg 305 6 828 528 523 521 597 | /home/wynmew/data/downloads/danbooru2018/original/0016/2059016.jpg 152 24 519 383 367 359 598 | /home/wynmew/data/downloads/danbooru2018/original/0016/1334016.jpg 144 6 520 431 375 424 599 | /home/wynmew/data/downloads/danbooru2018/original/0016/2424016.jpg 312 35 634 411 321 376 600 | /home/wynmew/data/downloads/danbooru2018/original/0016/1698016.jpg 416 11 770 426 354 414 601 | /home/wynmew/data/downloads/danbooru2018/original/0016/1737016.jpg 384 26 786 476 402 449 602 | /home/wynmew/data/downloads/danbooru2018/original/0016/978016.jpg 396 1 642 262 245 260 603 | /home/wynmew/data/downloads/danbooru2018/original/0016/561016.jpg 188 81 438 360 250 279 604 | /home/wynmew/data/downloads/danbooru2018/original/0016/490016.jpg 105 47 496 479 390 431 605 | /home/wynmew/data/downloads/danbooru2018/original/0016/3297016.jpg 786 300 2247 1948 1461 1647 606 | /home/wynmew/data/downloads/danbooru2018/original/0016/3223016.jpg 1198 451 2012 1425 813 973 607 | /home/wynmew/data/downloads/danbooru2018/original/0016/1352016.png 360 18 819 436 458 418 608 | /home/wynmew/data/downloads/danbooru2018/original/0016/750016.jpg 1029 307 2060 1534 1030 1226 609 | /home/wynmew/data/downloads/danbooru2018/original/0016/2937016.jpg 392 68 751 451 358 383 610 | /home/wynmew/data/downloads/danbooru2018/original/0016/3161016.png 401 75 1084 854 682 779 611 | /home/wynmew/data/downloads/danbooru2018/original/0016/749016.jpg 141 394 491 774 350 379 612 | /home/wynmew/data/downloads/danbooru2018/original/0016/3090016.jpg 110 9 987 978 876 968 613 | /home/wynmew/data/downloads/danbooru2018/original/0016/3173016.png 342 5 675 334 333 329 614 | /home/wynmew/data/downloads/danbooru2018/original/0016/2349016.png 335 22 482 182 146 160 615 | /home/wynmew/data/downloads/danbooru2018/original/0016/3215016.jpg 189 27 690 557 500 530 616 | /home/wynmew/data/downloads/danbooru2018/original/0016/2934016.jpg 115 23 605 543 490 519 617 | /home/wynmew/data/downloads/danbooru2018/original/0016/70016.jpg 87 67 367 351 279 283 618 | /home/wynmew/data/downloads/danbooru2018/original/0016/1852016.jpg 440 276 770 610 329 334 619 | /home/wynmew/data/downloads/danbooru2018/original/0016/812016.jpg 161 40 620 448 459 408 620 | /home/wynmew/data/downloads/danbooru2018/original/0016/1992016.png 119 60 707 658 587 597 621 | /home/wynmew/data/downloads/danbooru2018/original/0016/2640016.png 305 20 831 591 525 571 622 | /home/wynmew/data/downloads/danbooru2018/original/0016/1608016.jpg 150 33 662 513 511 479 623 | /home/wynmew/data/downloads/danbooru2018/original/0016/2854016.jpg 600 305 1058 844 458 538 624 | /home/wynmew/data/downloads/danbooru2018/original/0016/3360016.jpg 918 56 1265 439 346 383 625 | /home/wynmew/data/downloads/danbooru2018/original/0016/1235016.jpg 183 49 477 401 293 352 626 | /home/wynmew/data/downloads/danbooru2018/original/0016/2400016.jpg 364 19 835 554 471 535 627 | /home/wynmew/data/downloads/danbooru2018/original/0016/1605016.jpg 788 304 1698 1279 909 974 628 | /home/wynmew/data/downloads/danbooru2018/original/0016/2268016.jpg 447 183 704 491 257 307 629 | /home/wynmew/data/downloads/danbooru2018/original/0016/1551016.png 52 5 371 336 319 330 630 | /home/wynmew/data/downloads/danbooru2018/original/0016/2386016.jpg 393 196 589 402 195 205 631 | /home/wynmew/data/downloads/danbooru2018/original/0016/2204016.png 111 30 309 241 198 211 632 | /home/wynmew/data/downloads/danbooru2018/original/0016/431016.jpg 114 3 273 172 158 168 633 | /home/wynmew/data/downloads/danbooru2018/original/0016/71016.jpg 153 152 445 429 292 277 634 | /home/wynmew/data/downloads/danbooru2018/original/0016/2282016.jpg 158 26 344 248 185 222 635 | /home/wynmew/data/downloads/danbooru2018/original/0016/2787016.png 230 14 580 459 349 445 636 | /home/wynmew/data/downloads/danbooru2018/original/0016/2847016.jpg 326 40 565 315 239 274 637 | /home/wynmew/data/downloads/danbooru2018/original/0016/2878016.png 288 48 442 250 154 201 638 | /home/wynmew/data/downloads/danbooru2018/original/0016/2250016.png 81 24 316 300 235 275 639 | /home/wynmew/data/downloads/danbooru2018/original/0016/867016.jpg 887 21 1144 292 257 271 640 | /home/wynmew/data/downloads/danbooru2018/original/0016/1955016.jpg 212 94 359 256 146 161 641 | /home/wynmew/data/downloads/danbooru2018/original/0016/1907016.jpg 145 3 401 288 255 284 642 | /home/wynmew/data/downloads/danbooru2018/original/0016/1287016.jpg 235 48 471 336 236 287 643 | /home/wynmew/data/downloads/danbooru2018/original/0016/2016016.jpg 140 14 373 278 232 263 644 | /home/wynmew/data/downloads/danbooru2018/original/0016/3214016.png 594 86 1542 1131 948 1045 645 | /home/wynmew/data/downloads/danbooru2018/original/0016/1104016.jpg 58 3 175 122 117 119 646 | /home/wynmew/data/downloads/danbooru2018/original/0016/1565016.jpg 209 68 409 312 200 244 647 | /home/wynmew/data/downloads/danbooru2018/original/0016/2220016.png 191 105 464 351 272 245 648 | /home/wynmew/data/downloads/danbooru2018/original/0016/929016.jpg 209 19 559 327 350 307 649 | /home/wynmew/data/downloads/danbooru2018/original/0016/2549016.jpg 218 51 455 324 236 272 650 | -------------------------------------------------------------------------------- /layers/__init__.py: -------------------------------------------------------------------------------- 1 | from .functions import * 2 | from .modules import * 3 | -------------------------------------------------------------------------------- /layers/__pycache__/__init__.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WynMew/AnimeFaceBoxes/025b5e0a265e971d03cf850d67a52dad2ab392c6/layers/__pycache__/__init__.cpython-36.pyc -------------------------------------------------------------------------------- /layers/functions/__pycache__/prior_box.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WynMew/AnimeFaceBoxes/025b5e0a265e971d03cf850d67a52dad2ab392c6/layers/functions/__pycache__/prior_box.cpython-36.pyc -------------------------------------------------------------------------------- /layers/functions/prior_box.py: -------------------------------------------------------------------------------- 1 | import torch 2 | from itertools import product as product 3 | import numpy as np 4 | from math import ceil 5 | 6 | 7 | class PriorBox(object): 8 | def __init__(self, cfg, image_size=None, phase='train'): 9 | super(PriorBox, self).__init__() 10 | #self.aspect_ratios = cfg['aspect_ratios'] 11 | self.min_sizes = cfg['min_sizes'] 12 | self.steps = cfg['steps'] 13 | self.clip = cfg['clip'] 14 | self.image_size = image_size 15 | self.feature_maps = [[ceil(self.image_size[0]/step), ceil(self.image_size[1]/step)] for step in self.steps] 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 | if min_size == 32: 26 | dense_cx = [x*self.steps[k]/self.image_size[1] for x in [j+0, j+0.25, j+0.5, j+0.75]] 27 | dense_cy = [y*self.steps[k]/self.image_size[0] for y in [i+0, i+0.25, i+0.5, i+0.75]] 28 | for cy, cx in product(dense_cy, dense_cx): 29 | anchors += [cx, cy, s_kx, s_ky] 30 | elif min_size == 64: 31 | dense_cx = [x*self.steps[k]/self.image_size[1] for x in [j+0, j+0.5]] 32 | dense_cy = [y*self.steps[k]/self.image_size[0] for y in [i+0, i+0.5]] 33 | for cy, cx in product(dense_cy, dense_cx): 34 | anchors += [cx, cy, s_kx, s_ky] 35 | else: 36 | cx = (j + 0.5) * self.steps[k] / self.image_size[1] 37 | cy = (i + 0.5) * self.steps[k] / self.image_size[0] 38 | anchors += [cx, cy, s_kx, s_ky] 39 | # back to torch land 40 | output = torch.Tensor(anchors).view(-1, 4) 41 | if self.clip: 42 | output.clamp_(max=1, min=0) 43 | return output 44 | -------------------------------------------------------------------------------- /layers/modules/__init__.py: -------------------------------------------------------------------------------- 1 | from .multibox_loss import MultiBoxLoss 2 | 3 | __all__ = ['MultiBoxLoss'] 4 | -------------------------------------------------------------------------------- /layers/modules/__pycache__/__init__.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WynMew/AnimeFaceBoxes/025b5e0a265e971d03cf850d67a52dad2ab392c6/layers/modules/__pycache__/__init__.cpython-36.pyc -------------------------------------------------------------------------------- /layers/modules/__pycache__/multibox_loss.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WynMew/AnimeFaceBoxes/025b5e0a265e971d03cf850d67a52dad2ab392c6/layers/modules/__pycache__/multibox_loss.cpython-36.pyc -------------------------------------------------------------------------------- /layers/modules/multibox_loss.py: -------------------------------------------------------------------------------- 1 | import torch 2 | import torch.nn as nn 3 | import torch.nn.functional as F 4 | from torch.autograd import Variable 5 | from utils.box_utils import match, log_sum_exp 6 | from data import cfg 7 | GPU = cfg['gpu_train'] 8 | 9 | class MultiBoxLoss(nn.Module): 10 | """SSD Weighted Loss Function 11 | Compute Targets: 12 | 1) Produce Confidence Target Indices by matching ground truth boxes 13 | with (default) 'priorboxes' that have jaccard index > threshold parameter 14 | (default threshold: 0.5). 15 | 2) Produce localization target by 'encoding' variance into offsets of ground 16 | truth boxes and their matched 'priorboxes'. 17 | 3) Hard negative mining to filter the excessive number of negative examples 18 | that comes with using a large number of default bounding boxes. 19 | (default negative:positive ratio 3:1) 20 | Objective Loss: 21 | L(x,c,l,g) = (Lconf(x, c) + αLloc(x,l,g)) / N 22 | Where, Lconf is the CrossEntropy Loss and Lloc is the SmoothL1 Loss 23 | weighted by α which is set to 1 by cross val. 24 | Args: 25 | c: class confidences, 26 | l: predicted boxes, 27 | g: ground truth boxes 28 | N: number of matched default boxes 29 | See: https://arxiv.org/pdf/1512.02325.pdf for more details. 30 | """ 31 | 32 | def __init__(self, num_classes, overlap_thresh, prior_for_matching, bkg_label, neg_mining, neg_pos, neg_overlap, encode_target): 33 | super(MultiBoxLoss, self).__init__() 34 | self.num_classes = num_classes 35 | self.threshold = overlap_thresh 36 | self.background_label = bkg_label 37 | self.encode_target = encode_target 38 | self.use_prior_for_matching = prior_for_matching 39 | self.do_neg_mining = neg_mining 40 | self.negpos_ratio = neg_pos 41 | self.neg_overlap = neg_overlap 42 | self.variance = [0.1, 0.2] 43 | 44 | def forward(self, predictions, priors, targets): 45 | """Multibox Loss 46 | Args: 47 | predictions (tuple): A tuple containing loc preds, conf preds, 48 | and prior boxes from SSD net. 49 | conf shape: torch.size(batch_size,num_priors,num_classes) 50 | loc shape: torch.size(batch_size,num_priors,4) 51 | priors shape: torch.size(num_priors,4) 52 | 53 | ground_truth (tensor): Ground truth boxes and labels for a batch, 54 | shape: [batch_size,num_objs,5] (last idx is the label). 55 | """ 56 | 57 | loc_data, conf_data = predictions 58 | priors = priors 59 | num = loc_data.size(0) 60 | num_priors = (priors.size(0)) 61 | 62 | # match priors (default boxes) and ground truth boxes 63 | loc_t = torch.Tensor(num, num_priors, 4) 64 | conf_t = torch.LongTensor(num, num_priors) 65 | for idx in range(num): 66 | truths = targets[idx][:, :-1].data 67 | labels = targets[idx][:, -1].data 68 | defaults = priors.data 69 | match(self.threshold, truths, defaults, self.variance, labels, loc_t, conf_t, idx) 70 | if GPU: 71 | loc_t = loc_t.cuda() 72 | conf_t = conf_t.cuda() 73 | 74 | pos = conf_t > 0 75 | 76 | # Localization Loss (Smooth L1) 77 | # Shape: [batch,num_priors,4] 78 | pos_idx = pos.unsqueeze(pos.dim()).expand_as(loc_data) 79 | loc_p = loc_data[pos_idx].view(-1, 4) 80 | loc_t = loc_t[pos_idx].view(-1, 4) 81 | loss_l = F.smooth_l1_loss(loc_p, loc_t, reduction='sum') 82 | 83 | # Compute max conf across batch for hard negative mining 84 | batch_conf = conf_data.view(-1, self.num_classes) 85 | loss_c = log_sum_exp(batch_conf) - batch_conf.gather(1, conf_t.view(-1, 1)) 86 | 87 | # Hard Negative Mining 88 | loss_c[pos.view(-1, 1)] = 0 # filter out pos boxes for now 89 | loss_c = loss_c.view(num, -1) 90 | _, loss_idx = loss_c.sort(1, descending=True) 91 | _, idx_rank = loss_idx.sort(1) 92 | num_pos = pos.long().sum(1, keepdim=True) 93 | num_neg = torch.clamp(self.negpos_ratio*num_pos, max=pos.size(1)-1) 94 | neg = idx_rank < num_neg.expand_as(idx_rank) 95 | 96 | # Confidence Loss Including Positive and Negative Examples 97 | pos_idx = pos.unsqueeze(2).expand_as(conf_data) 98 | neg_idx = neg.unsqueeze(2).expand_as(conf_data) 99 | conf_p = conf_data[(pos_idx+neg_idx).gt(0)].view(-1,self.num_classes) 100 | targets_weighted = conf_t[(pos+neg).gt(0)] 101 | loss_c = F.cross_entropy(conf_p, targets_weighted, reduction='sum') 102 | 103 | # Sum of losses: L(x,c,l,g) = (Lconf(x, c) + αLloc(x,l,g)) / N 104 | N = max(num_pos.data.sum().float(), 1) 105 | loss_l /= N 106 | loss_c /= N 107 | 108 | return loss_l, loss_c 109 | -------------------------------------------------------------------------------- /make.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | cd ./utils/ 3 | 4 | CUDA_PATH=/usr/local/cuda/ 5 | 6 | python3 build.py build_ext --inplace 7 | 8 | cd .. 9 | -------------------------------------------------------------------------------- /models/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WynMew/AnimeFaceBoxes/025b5e0a265e971d03cf850d67a52dad2ab392c6/models/__init__.py -------------------------------------------------------------------------------- /models/__pycache__/__init__.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WynMew/AnimeFaceBoxes/025b5e0a265e971d03cf850d67a52dad2ab392c6/models/__pycache__/__init__.cpython-36.pyc -------------------------------------------------------------------------------- /models/__pycache__/faceboxes.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WynMew/AnimeFaceBoxes/025b5e0a265e971d03cf850d67a52dad2ab392c6/models/__pycache__/faceboxes.cpython-36.pyc -------------------------------------------------------------------------------- /models/faceboxes.py: -------------------------------------------------------------------------------- 1 | import torch 2 | import torch.nn as nn 3 | import torch.nn.functional as F 4 | 5 | 6 | class BasicConv2d(nn.Module): 7 | 8 | def __init__(self, in_channels, out_channels, **kwargs): 9 | super(BasicConv2d, self).__init__() 10 | self.conv = nn.Conv2d(in_channels, out_channels, bias=False, **kwargs) 11 | self.bn = nn.BatchNorm2d(out_channels, eps=1e-5) 12 | 13 | def forward(self, x): 14 | x = self.conv(x) 15 | x = self.bn(x) 16 | return F.relu(x, inplace=True) 17 | 18 | 19 | class Inception(nn.Module): 20 | 21 | def __init__(self): 22 | super(Inception, self).__init__() 23 | self.branch1x1 = BasicConv2d(128, 32, kernel_size=1, padding=0) 24 | self.branch1x1_2 = BasicConv2d(128, 32, kernel_size=1, padding=0) 25 | self.branch3x3_reduce = BasicConv2d(128, 24, kernel_size=1, padding=0) 26 | self.branch3x3 = BasicConv2d(24, 32, kernel_size=3, padding=1) 27 | self.branch3x3_reduce_2 = BasicConv2d(128, 24, kernel_size=1, padding=0) 28 | self.branch3x3_2 = BasicConv2d(24, 32, kernel_size=3, padding=1) 29 | self.branch3x3_3 = BasicConv2d(32, 32, kernel_size=3, padding=1) 30 | 31 | def forward(self, x): 32 | branch1x1 = self.branch1x1(x) 33 | 34 | branch1x1_pool = F.avg_pool2d(x, kernel_size=3, stride=1, padding=1) 35 | branch1x1_2 = self.branch1x1_2(branch1x1_pool) 36 | 37 | branch3x3_reduce = self.branch3x3_reduce(x) 38 | branch3x3 = self.branch3x3(branch3x3_reduce) 39 | 40 | branch3x3_reduce_2 = self.branch3x3_reduce_2(x) 41 | branch3x3_2 = self.branch3x3_2(branch3x3_reduce_2) 42 | branch3x3_3 = self.branch3x3_3(branch3x3_2) 43 | 44 | outputs = [branch1x1, branch1x1_2, branch3x3, branch3x3_3] 45 | return torch.cat(outputs, 1) 46 | 47 | 48 | class CRelu(nn.Module): 49 | 50 | def __init__(self, in_channels, out_channels, **kwargs): 51 | super(CRelu, self).__init__() 52 | self.conv = nn.Conv2d(in_channels, out_channels, bias=False, **kwargs) 53 | self.bn = nn.BatchNorm2d(out_channels, eps=1e-5) 54 | 55 | def forward(self, x): 56 | x = self.conv(x) 57 | x = self.bn(x) 58 | x = torch.cat([x, -x], 1) 59 | x = F.relu(x, inplace=True) 60 | return x 61 | 62 | 63 | class FaceBoxes(nn.Module): 64 | 65 | def __init__(self, phase, size, num_classes): 66 | super(FaceBoxes, self).__init__() 67 | self.phase = phase 68 | self.num_classes = num_classes 69 | self.size = size 70 | 71 | self.conv1 = CRelu(3, 24, kernel_size=7, stride=4, padding=3) 72 | self.conv2 = CRelu(48, 64, kernel_size=5, stride=2, padding=2) 73 | 74 | self.inception1 = Inception() 75 | self.inception2 = Inception() 76 | self.inception3 = Inception() 77 | 78 | self.conv3_1 = BasicConv2d(128, 128, kernel_size=1, stride=1, padding=0) 79 | self.conv3_2 = BasicConv2d(128, 256, kernel_size=3, stride=2, padding=1) 80 | 81 | self.conv4_1 = BasicConv2d(256, 128, kernel_size=1, stride=1, padding=0) 82 | self.conv4_2 = BasicConv2d(128, 256, kernel_size=3, stride=2, padding=1) 83 | 84 | self.loc, self.conf = self.multibox(self.num_classes) 85 | 86 | if self.phase == 'test': 87 | self.softmax = nn.Softmax(dim=-1) 88 | 89 | if self.phase == 'train': 90 | for m in self.modules(): 91 | if isinstance(m, nn.Conv2d): 92 | if m.bias is not None: 93 | nn.init.xavier_normal_(m.weight.data) 94 | m.bias.data.fill_(0.02) 95 | else: 96 | m.weight.data.normal_(0, 0.01) 97 | elif isinstance(m, nn.BatchNorm2d): 98 | m.weight.data.fill_(1) 99 | m.bias.data.zero_() 100 | 101 | def multibox(self, num_classes): 102 | loc_layers = [] 103 | conf_layers = [] 104 | loc_layers += [nn.Conv2d(128, 21 * 4, kernel_size=3, padding=1)] 105 | conf_layers += [nn.Conv2d(128, 21 * num_classes, kernel_size=3, padding=1)] 106 | loc_layers += [nn.Conv2d(256, 1 * 4, kernel_size=3, padding=1)] 107 | conf_layers += [nn.Conv2d(256, 1 * num_classes, kernel_size=3, padding=1)] 108 | loc_layers += [nn.Conv2d(256, 1 * 4, kernel_size=3, padding=1)] 109 | conf_layers += [nn.Conv2d(256, 1 * num_classes, kernel_size=3, padding=1)] 110 | return nn.Sequential(*loc_layers), nn.Sequential(*conf_layers) 111 | 112 | def forward(self, x): 113 | 114 | detection_sources = list() 115 | loc = list() 116 | conf = list() 117 | 118 | x = self.conv1(x) 119 | x = F.max_pool2d(x, kernel_size=3, stride=2, padding=1) 120 | x = self.conv2(x) 121 | x = F.max_pool2d(x, kernel_size=3, stride=2, padding=1) 122 | x = self.inception1(x) 123 | x = self.inception2(x) 124 | x = self.inception3(x) 125 | detection_sources.append(x) 126 | 127 | x = self.conv3_1(x) 128 | x = self.conv3_2(x) 129 | detection_sources.append(x) 130 | 131 | x = self.conv4_1(x) 132 | x = self.conv4_2(x) 133 | detection_sources.append(x) 134 | 135 | for (x, l, c) in zip(detection_sources, self.loc, self.conf): 136 | loc.append(l(x).permute(0, 2, 3, 1).contiguous()) 137 | conf.append(c(x).permute(0, 2, 3, 1).contiguous()) 138 | 139 | loc = torch.cat([o.view(o.size(0), -1) for o in loc], 1) 140 | conf = torch.cat([o.view(o.size(0), -1) for o in conf], 1) 141 | 142 | if self.phase == "test": 143 | output = (loc.view(loc.size(0), -1, 4), 144 | self.softmax(conf.view(-1, self.num_classes))) 145 | else: 146 | output = (loc.view(loc.size(0), -1, 4), 147 | conf.view(conf.size(0), -1, self.num_classes)) 148 | 149 | return output 150 | -------------------------------------------------------------------------------- /out.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WynMew/AnimeFaceBoxes/025b5e0a265e971d03cf850d67a52dad2ab392c6/out.png -------------------------------------------------------------------------------- /utils/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WynMew/AnimeFaceBoxes/025b5e0a265e971d03cf850d67a52dad2ab392c6/utils/__init__.py -------------------------------------------------------------------------------- /utils/__pycache__/__init__.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WynMew/AnimeFaceBoxes/025b5e0a265e971d03cf850d67a52dad2ab392c6/utils/__pycache__/__init__.cpython-36.pyc -------------------------------------------------------------------------------- /utils/__pycache__/box_utils.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WynMew/AnimeFaceBoxes/025b5e0a265e971d03cf850d67a52dad2ab392c6/utils/__pycache__/box_utils.cpython-36.pyc -------------------------------------------------------------------------------- /utils/__pycache__/nms_wrapper.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WynMew/AnimeFaceBoxes/025b5e0a265e971d03cf850d67a52dad2ab392c6/utils/__pycache__/nms_wrapper.cpython-36.pyc -------------------------------------------------------------------------------- /utils/__pycache__/timer.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WynMew/AnimeFaceBoxes/025b5e0a265e971d03cf850d67a52dad2ab392c6/utils/__pycache__/timer.cpython-36.pyc -------------------------------------------------------------------------------- /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, loc_t, conf_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, num_priors]. 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 | loc_t: (tensor) Tensor to be filled w/ endcoded location targets. 108 | conf_t: (tensor) Tensor to be filled w/ matched indices for conf preds. 109 | idx: (int) current batch index 110 | Return: 111 | The matched indices corresponding to 1)location and 2)confidence preds. 112 | """ 113 | # jaccard index 114 | overlaps = jaccard( 115 | truths, 116 | point_form(priors) 117 | ) 118 | # (Bipartite Matching) 119 | # [1,num_objects] best prior for each ground truth 120 | best_prior_overlap, best_prior_idx = overlaps.max(1, keepdim=True) 121 | 122 | # ignore hard gt 123 | valid_gt_idx = best_prior_overlap[:, 0] >= 0.2 124 | best_prior_idx_filter = best_prior_idx[valid_gt_idx, :] 125 | if best_prior_idx_filter.shape[0] <= 0: 126 | loc_t[idx] = 0 127 | conf_t[idx] = 0 128 | return 129 | 130 | # [1,num_priors] best ground truth for each prior 131 | best_truth_overlap, best_truth_idx = overlaps.max(0, keepdim=True) 132 | best_truth_idx.squeeze_(0) 133 | best_truth_overlap.squeeze_(0) 134 | best_prior_idx.squeeze_(1) 135 | best_prior_idx_filter.squeeze_(1) 136 | best_prior_overlap.squeeze_(1) 137 | best_truth_overlap.index_fill_(0, best_prior_idx_filter, 2) # ensure best prior 138 | # TODO refactor: index best_prior_idx with long tensor 139 | # ensure every gt matches with its prior of max overlap 140 | for j in range(best_prior_idx.size(0)): 141 | best_truth_idx[best_prior_idx[j]] = j 142 | matches = truths[best_truth_idx] # Shape: [num_priors,4] 143 | conf = labels[best_truth_idx] # Shape: [num_priors] 144 | conf[best_truth_overlap < threshold] = 0 # label as background 145 | loc = encode(matches, priors, variances) 146 | loc_t[idx] = loc # [num_priors,4] encoded offsets to learn 147 | conf_t[idx] = conf # [num_priors] top class label for each prior 148 | 149 | 150 | def encode(matched, priors, variances): 151 | """Encode the variances from the priorbox layers into the ground truth boxes 152 | we have matched (based on jaccard overlap) with the prior boxes. 153 | Args: 154 | matched: (tensor) Coords of ground truth for each prior in point-form 155 | Shape: [num_priors, 4]. 156 | priors: (tensor) Prior boxes in center-offset form 157 | Shape: [num_priors,4]. 158 | variances: (list[float]) Variances of priorboxes 159 | Return: 160 | encoded boxes (tensor), Shape: [num_priors, 4] 161 | """ 162 | 163 | # dist b/t match center and prior's center 164 | g_cxcy = (matched[:, :2] + matched[:, 2:])/2 - priors[:, :2] 165 | # encode variance 166 | g_cxcy /= (variances[0] * priors[:, 2:]) 167 | # match wh / prior wh 168 | g_wh = (matched[:, 2:] - matched[:, :2]) / priors[:, 2:] 169 | g_wh = torch.log(g_wh) / variances[1] 170 | # return target for smooth_l1_loss 171 | return torch.cat([g_cxcy, g_wh], 1) # [num_priors,4] 172 | 173 | 174 | # Adapted from https://github.com/Hakuyume/chainer-ssd 175 | def decode(loc, priors, variances): 176 | """Decode locations from predictions using priors to undo 177 | the encoding we did for offset regression at train time. 178 | Args: 179 | loc (tensor): location predictions for loc layers, 180 | Shape: [num_priors,4] 181 | priors (tensor): Prior boxes in center-offset form. 182 | Shape: [num_priors,4]. 183 | variances: (list[float]) Variances of priorboxes 184 | Return: 185 | decoded bounding box predictions 186 | """ 187 | 188 | boxes = torch.cat(( 189 | priors[:, :2] + loc[:, :2] * variances[0] * priors[:, 2:], 190 | priors[:, 2:] * torch.exp(loc[:, 2:] * variances[1])), 1) 191 | boxes[:, :2] -= boxes[:, 2:] / 2 192 | boxes[:, 2:] += boxes[:, :2] 193 | return boxes 194 | 195 | 196 | def log_sum_exp(x): 197 | """Utility function for computing log_sum_exp while determining 198 | This will be used to determine unaveraged confidence loss across 199 | all examples in a batch. 200 | Args: 201 | x (Variable(tensor)): conf_preds from conf layers 202 | """ 203 | x_max = x.data.max() 204 | return torch.log(torch.sum(torch.exp(x-x_max), 1, keepdim=True)) + x_max 205 | 206 | 207 | # Original author: Francisco Massa: 208 | # https://github.com/fmassa/object-detection.torch 209 | # Ported to PyTorch by Max deGroot (02/01/2017) 210 | def nms(boxes, scores, overlap=0.5, top_k=200): 211 | """Apply non-maximum suppression at test time to avoid detecting too many 212 | overlapping bounding boxes for a given object. 213 | Args: 214 | boxes: (tensor) The location preds for the img, Shape: [num_priors,4]. 215 | scores: (tensor) The class predscores for the img, Shape:[num_priors]. 216 | overlap: (float) The overlap thresh for suppressing unnecessary boxes. 217 | top_k: (int) The Maximum number of box preds to consider. 218 | Return: 219 | The indices of the kept boxes with respect to num_priors. 220 | """ 221 | 222 | keep = torch.Tensor(scores.size(0)).fill_(0).long() 223 | if boxes.numel() == 0: 224 | return keep 225 | x1 = boxes[:, 0] 226 | y1 = boxes[:, 1] 227 | x2 = boxes[:, 2] 228 | y2 = boxes[:, 3] 229 | area = torch.mul(x2 - x1, y2 - y1) 230 | v, idx = scores.sort(0) # sort in ascending order 231 | # I = I[v >= 0.01] 232 | idx = idx[-top_k:] # indices of the top-k largest vals 233 | xx1 = boxes.new() 234 | yy1 = boxes.new() 235 | xx2 = boxes.new() 236 | yy2 = boxes.new() 237 | w = boxes.new() 238 | h = boxes.new() 239 | 240 | # keep = torch.Tensor() 241 | count = 0 242 | while idx.numel() > 0: 243 | i = idx[-1] # index of current largest val 244 | # keep.append(i) 245 | keep[count] = i 246 | count += 1 247 | if idx.size(0) == 1: 248 | break 249 | idx = idx[:-1] # remove kept element from view 250 | # load bboxes of next highest vals 251 | torch.index_select(x1, 0, idx, out=xx1) 252 | torch.index_select(y1, 0, idx, out=yy1) 253 | torch.index_select(x2, 0, idx, out=xx2) 254 | torch.index_select(y2, 0, idx, out=yy2) 255 | # store element-wise max with next highest score 256 | xx1 = torch.clamp(xx1, min=x1[i]) 257 | yy1 = torch.clamp(yy1, min=y1[i]) 258 | xx2 = torch.clamp(xx2, max=x2[i]) 259 | yy2 = torch.clamp(yy2, max=y2[i]) 260 | w.resize_as_(xx2) 261 | h.resize_as_(yy2) 262 | w = xx2 - xx1 263 | h = yy2 - yy1 264 | # check sizes of xx1 and xx2.. after each iteration 265 | w = torch.clamp(w, min=0.0) 266 | h = torch.clamp(h, min=0.0) 267 | inter = w*h 268 | # IoU = i / (area(a) + area(b) - i) 269 | rem_areas = torch.index_select(area, 0, idx) # load remaining areas) 270 | union = (rem_areas - inter) + area[i] 271 | IoU = inter/union # store result in iou 272 | # keep only elements with an IoU <= overlap 273 | idx = idx[IoU.le(overlap)] 274 | return keep, count 275 | 276 | 277 | -------------------------------------------------------------------------------- /utils/build.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 os 9 | from os.path import join as pjoin 10 | import numpy as np 11 | from distutils.core import setup 12 | from distutils.extension import Extension 13 | from Cython.Distutils import build_ext 14 | 15 | 16 | def find_in_path(name, path): 17 | "Find a file in a search path" 18 | # adapted fom http://code.activestate.com/recipes/52224-find-a-file-given-a-search-path/ 19 | for dir in path.split(os.pathsep): 20 | binpath = pjoin(dir, name) 21 | if os.path.exists(binpath): 22 | return os.path.abspath(binpath) 23 | return None 24 | 25 | 26 | def locate_cuda(): 27 | """Locate the CUDA environment on the system 28 | 29 | Returns a dict with keys 'home', 'nvcc', 'include', and 'lib64' 30 | and values giving the absolute path to each directory. 31 | 32 | Starts by looking for the CUDAHOME env variable. If not found, everything 33 | is based on finding 'nvcc' in the PATH. 34 | """ 35 | 36 | # first check if the CUDAHOME env variable is in use 37 | if 'CUDAHOME' in os.environ: 38 | home = os.environ['CUDAHOME'] 39 | nvcc = pjoin(home, 'bin', 'nvcc') 40 | else: 41 | # otherwise, search the PATH for NVCC 42 | default_path = pjoin(os.sep, 'usr', 'local', 'cuda', 'bin') 43 | nvcc = find_in_path('nvcc', os.environ['PATH'] + os.pathsep + default_path) 44 | if nvcc is None: 45 | raise EnvironmentError('The nvcc binary could not be ' 46 | 'located in your $PATH. Either add it to your path, or set $CUDAHOME') 47 | home = os.path.dirname(os.path.dirname(nvcc)) 48 | 49 | cudaconfig = {'home': home, 'nvcc': nvcc, 50 | 'include': pjoin(home, 'include'), 51 | 'lib64': pjoin(home, 'lib64')} 52 | for k, v in cudaconfig.items(): 53 | if not os.path.exists(v): 54 | raise EnvironmentError('The CUDA %s path could not be located in %s' % (k, v)) 55 | 56 | return cudaconfig 57 | 58 | 59 | CUDA = locate_cuda() 60 | 61 | # Obtain the numpy include directory. This logic works across numpy versions. 62 | try: 63 | numpy_include = np.get_include() 64 | except AttributeError: 65 | numpy_include = np.get_numpy_include() 66 | 67 | 68 | def customize_compiler_for_nvcc(self): 69 | """inject deep into distutils to customize how the dispatch 70 | to gcc/nvcc works. 71 | 72 | If you subclass UnixCCompiler, it's not trivial to get your subclass 73 | injected in, and still have the right customizations (i.e. 74 | distutils.sysconfig.customize_compiler) run on it. So instead of going 75 | the OO route, I have this. Note, it's kindof like a wierd functional 76 | subclassing going on.""" 77 | 78 | # tell the compiler it can processes .cu 79 | self.src_extensions.append('.cu') 80 | 81 | # save references to the default compiler_so and _comple methods 82 | default_compiler_so = self.compiler_so 83 | super = self._compile 84 | 85 | # now redefine the _compile method. This gets executed for each 86 | # object but distutils doesn't have the ability to change compilers 87 | # based on source extension: we add it. 88 | def _compile(obj, src, ext, cc_args, extra_postargs, pp_opts): 89 | print(extra_postargs) 90 | if os.path.splitext(src)[1] == '.cu': 91 | # use the cuda for .cu files 92 | self.set_executable('compiler_so', CUDA['nvcc']) 93 | # use only a subset of the extra_postargs, which are 1-1 translated 94 | # from the extra_compile_args in the Extension class 95 | postargs = extra_postargs['nvcc'] 96 | else: 97 | postargs = extra_postargs['gcc'] 98 | 99 | super(obj, src, ext, cc_args, postargs, pp_opts) 100 | # reset the default compiler_so, which we might have changed for cuda 101 | self.compiler_so = default_compiler_so 102 | 103 | # inject our redefined _compile method into the class 104 | self._compile = _compile 105 | 106 | 107 | # run the customize_compiler 108 | class custom_build_ext(build_ext): 109 | def build_extensions(self): 110 | customize_compiler_for_nvcc(self.compiler) 111 | build_ext.build_extensions(self) 112 | 113 | 114 | ext_modules = [ 115 | Extension( 116 | "nms.cpu_nms", 117 | ["nms/cpu_nms.pyx"], 118 | extra_compile_args={'gcc': ["-Wno-cpp", "-Wno-unused-function"]}, 119 | include_dirs=[numpy_include] 120 | ), 121 | Extension('nms.gpu_nms', 122 | ['nms/nms_kernel.cu', 'nms/gpu_nms.pyx'], 123 | library_dirs=[CUDA['lib64']], 124 | libraries=['cudart'], 125 | language='c++', 126 | runtime_library_dirs=[CUDA['lib64']], 127 | # this syntax is specific to this build system 128 | # we're only going to use certain compiler args with nvcc and not with gcc 129 | # the implementation of this trick is in customize_compiler() below 130 | extra_compile_args={'gcc': ["-Wno-unused-function"], 131 | 'nvcc': ['-arch=sm_52', 132 | '--ptxas-options=-v', 133 | '-c', 134 | '--compiler-options', 135 | "'-fPIC'"]}, 136 | include_dirs=[numpy_include, CUDA['include']] 137 | ), 138 | ] 139 | 140 | setup( 141 | name='mot_utils', 142 | ext_modules=ext_modules, 143 | # inject our custom trigger 144 | cmdclass={'build_ext': custom_build_ext}, 145 | ) 146 | -------------------------------------------------------------------------------- /utils/build/temp.linux-x86_64-3.6/nms/cpu_nms.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WynMew/AnimeFaceBoxes/025b5e0a265e971d03cf850d67a52dad2ab392c6/utils/build/temp.linux-x86_64-3.6/nms/cpu_nms.o -------------------------------------------------------------------------------- /utils/build/temp.linux-x86_64-3.6/nms/gpu_nms.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WynMew/AnimeFaceBoxes/025b5e0a265e971d03cf850d67a52dad2ab392c6/utils/build/temp.linux-x86_64-3.6/nms/gpu_nms.o -------------------------------------------------------------------------------- /utils/build/temp.linux-x86_64-3.6/nms/nms_kernel.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WynMew/AnimeFaceBoxes/025b5e0a265e971d03cf850d67a52dad2ab392c6/utils/build/temp.linux-x86_64-3.6/nms/nms_kernel.o -------------------------------------------------------------------------------- /utils/nms/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WynMew/AnimeFaceBoxes/025b5e0a265e971d03cf850d67a52dad2ab392c6/utils/nms/__init__.py -------------------------------------------------------------------------------- /utils/nms/__pycache__/__init__.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WynMew/AnimeFaceBoxes/025b5e0a265e971d03cf850d67a52dad2ab392c6/utils/nms/__pycache__/__init__.cpython-36.pyc -------------------------------------------------------------------------------- /utils/nms/cpu_nms.cpython-36m-x86_64-linux-gnu.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WynMew/AnimeFaceBoxes/025b5e0a265e971d03cf850d67a52dad2ab392c6/utils/nms/cpu_nms.cpython-36m-x86_64-linux-gnu.so -------------------------------------------------------------------------------- /utils/nms/cpu_nms.pyx: -------------------------------------------------------------------------------- 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 | cimport numpy as np 10 | 11 | cdef inline np.float32_t max(np.float32_t a, np.float32_t b): 12 | return a if a >= b else b 13 | 14 | cdef inline np.float32_t min(np.float32_t a, np.float32_t b): 15 | return a if a <= b else b 16 | 17 | def cpu_nms(np.ndarray[np.float32_t, ndim=2] dets, np.float thresh): 18 | cdef np.ndarray[np.float32_t, ndim=1] x1 = dets[:, 0] 19 | cdef np.ndarray[np.float32_t, ndim=1] y1 = dets[:, 1] 20 | cdef np.ndarray[np.float32_t, ndim=1] x2 = dets[:, 2] 21 | cdef np.ndarray[np.float32_t, ndim=1] y2 = dets[:, 3] 22 | cdef np.ndarray[np.float32_t, ndim=1] scores = dets[:, 4] 23 | 24 | cdef np.ndarray[np.float32_t, ndim=1] areas = (x2 - x1 + 1) * (y2 - y1 + 1) 25 | cdef np.ndarray[np.int_t, ndim=1] order = scores.argsort()[::-1] 26 | 27 | cdef int ndets = dets.shape[0] 28 | cdef np.ndarray[np.int_t, ndim=1] suppressed = \ 29 | np.zeros((ndets), dtype=np.int) 30 | 31 | # nominal indices 32 | cdef int _i, _j 33 | # sorted indices 34 | cdef int i, j 35 | # temp variables for box i's (the box currently under consideration) 36 | cdef np.float32_t ix1, iy1, ix2, iy2, iarea 37 | # variables for computing overlap with box j (lower scoring box) 38 | cdef np.float32_t xx1, yy1, xx2, yy2 39 | cdef np.float32_t w, h 40 | cdef np.float32_t inter, ovr 41 | 42 | keep = [] 43 | for _i in range(ndets): 44 | i = order[_i] 45 | if suppressed[i] == 1: 46 | continue 47 | keep.append(i) 48 | ix1 = x1[i] 49 | iy1 = y1[i] 50 | ix2 = x2[i] 51 | iy2 = y2[i] 52 | iarea = areas[i] 53 | for _j in range(_i + 1, ndets): 54 | j = order[_j] 55 | if suppressed[j] == 1: 56 | continue 57 | xx1 = max(ix1, x1[j]) 58 | yy1 = max(iy1, y1[j]) 59 | xx2 = min(ix2, x2[j]) 60 | yy2 = min(iy2, y2[j]) 61 | w = max(0.0, xx2 - xx1 + 1) 62 | h = max(0.0, yy2 - yy1 + 1) 63 | inter = w * h 64 | ovr = inter / (iarea + areas[j] - inter) 65 | if ovr >= thresh: 66 | suppressed[j] = 1 67 | 68 | return keep 69 | 70 | def cpu_soft_nms(np.ndarray[float, ndim=2] boxes, float sigma=0.5, float Nt=0.3, float threshold=0.001, unsigned int method=0): 71 | cdef unsigned int N = boxes.shape[0] 72 | cdef float iw, ih, box_area 73 | cdef float ua 74 | cdef int pos = 0 75 | cdef float maxscore = 0 76 | cdef int maxpos = 0 77 | cdef float x1,x2,y1,y2,tx1,tx2,ty1,ty2,ts,area,weight,ov 78 | 79 | for i in range(N): 80 | maxscore = boxes[i, 4] 81 | maxpos = i 82 | 83 | tx1 = boxes[i,0] 84 | ty1 = boxes[i,1] 85 | tx2 = boxes[i,2] 86 | ty2 = boxes[i,3] 87 | ts = boxes[i,4] 88 | 89 | pos = i + 1 90 | # get max box 91 | while pos < N: 92 | if maxscore < boxes[pos, 4]: 93 | maxscore = boxes[pos, 4] 94 | maxpos = pos 95 | pos = pos + 1 96 | 97 | # add max box as a detection 98 | boxes[i,0] = boxes[maxpos,0] 99 | boxes[i,1] = boxes[maxpos,1] 100 | boxes[i,2] = boxes[maxpos,2] 101 | boxes[i,3] = boxes[maxpos,3] 102 | boxes[i,4] = boxes[maxpos,4] 103 | 104 | # swap ith box with position of max box 105 | boxes[maxpos,0] = tx1 106 | boxes[maxpos,1] = ty1 107 | boxes[maxpos,2] = tx2 108 | boxes[maxpos,3] = ty2 109 | boxes[maxpos,4] = ts 110 | 111 | tx1 = boxes[i,0] 112 | ty1 = boxes[i,1] 113 | tx2 = boxes[i,2] 114 | ty2 = boxes[i,3] 115 | ts = boxes[i,4] 116 | 117 | pos = i + 1 118 | # NMS iterations, note that N changes if detection boxes fall below threshold 119 | while pos < N: 120 | x1 = boxes[pos, 0] 121 | y1 = boxes[pos, 1] 122 | x2 = boxes[pos, 2] 123 | y2 = boxes[pos, 3] 124 | s = boxes[pos, 4] 125 | 126 | area = (x2 - x1 + 1) * (y2 - y1 + 1) 127 | iw = (min(tx2, x2) - max(tx1, x1) + 1) 128 | if iw > 0: 129 | ih = (min(ty2, y2) - max(ty1, y1) + 1) 130 | if ih > 0: 131 | ua = float((tx2 - tx1 + 1) * (ty2 - ty1 + 1) + area - iw * ih) 132 | ov = iw * ih / ua #iou between max box and detection box 133 | 134 | if method == 1: # linear 135 | if ov > Nt: 136 | weight = 1 - ov 137 | else: 138 | weight = 1 139 | elif method == 2: # gaussian 140 | weight = np.exp(-(ov * ov)/sigma) 141 | else: # original NMS 142 | if ov > Nt: 143 | weight = 0 144 | else: 145 | weight = 1 146 | 147 | boxes[pos, 4] = weight*boxes[pos, 4] 148 | 149 | # if box score falls below threshold, discard the box by swapping with last box 150 | # update N 151 | if boxes[pos, 4] < threshold: 152 | boxes[pos,0] = boxes[N-1, 0] 153 | boxes[pos,1] = boxes[N-1, 1] 154 | boxes[pos,2] = boxes[N-1, 2] 155 | boxes[pos,3] = boxes[N-1, 3] 156 | boxes[pos,4] = boxes[N-1, 4] 157 | N = N - 1 158 | pos = pos - 1 159 | 160 | pos = pos + 1 161 | 162 | keep = [i for i in range(N)] 163 | return keep 164 | -------------------------------------------------------------------------------- /utils/nms/gpu_nms.cpython-36m-x86_64-linux-gnu.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WynMew/AnimeFaceBoxes/025b5e0a265e971d03cf850d67a52dad2ab392c6/utils/nms/gpu_nms.cpython-36m-x86_64-linux-gnu.so -------------------------------------------------------------------------------- /utils/nms/gpu_nms.hpp: -------------------------------------------------------------------------------- 1 | void _nms(int* keep_out, int* num_out, const float* boxes_host, int boxes_num, 2 | int boxes_dim, float nms_overlap_thresh, int device_id); 3 | -------------------------------------------------------------------------------- /utils/nms/gpu_nms.pyx: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------- 2 | # Faster 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 | cimport numpy as np 10 | 11 | assert sizeof(int) == sizeof(np.int32_t) 12 | 13 | cdef extern from "gpu_nms.hpp": 14 | void _nms(np.int32_t*, int*, np.float32_t*, int, int, float, int) 15 | 16 | def gpu_nms(np.ndarray[np.float32_t, ndim=2] dets, np.float thresh, 17 | np.int32_t device_id=0): 18 | cdef int boxes_num = dets.shape[0] 19 | cdef int boxes_dim = dets.shape[1] 20 | cdef int num_out 21 | cdef np.ndarray[np.int32_t, ndim=1] \ 22 | keep = np.zeros(boxes_num, dtype=np.int32) 23 | cdef np.ndarray[np.float32_t, ndim=1] \ 24 | scores = dets[:, 4] 25 | cdef np.ndarray[np.int_t, ndim=1] \ 26 | order = scores.argsort()[::-1] 27 | cdef np.ndarray[np.float32_t, ndim=2] \ 28 | sorted_dets = dets[order, :] 29 | _nms(&keep[0], &num_out, &sorted_dets[0, 0], boxes_num, boxes_dim, thresh, device_id) 30 | keep = keep[:num_out] 31 | return list(order[keep]) 32 | -------------------------------------------------------------------------------- /utils/nms/nms_kernel.cu: -------------------------------------------------------------------------------- 1 | // ------------------------------------------------------------------ 2 | // Faster R-CNN 3 | // Copyright (c) 2015 Microsoft 4 | // Licensed under The MIT License [see fast-rcnn/LICENSE for details] 5 | // Written by Shaoqing Ren 6 | // ------------------------------------------------------------------ 7 | 8 | #include "gpu_nms.hpp" 9 | #include 10 | #include 11 | 12 | #define CUDA_CHECK(condition) \ 13 | /* Code block avoids redefinition of cudaError_t error */ \ 14 | do { \ 15 | cudaError_t error = condition; \ 16 | if (error != cudaSuccess) { \ 17 | std::cout << cudaGetErrorString(error) << std::endl; \ 18 | } \ 19 | } while (0) 20 | 21 | #define DIVUP(m,n) ((m) / (n) + ((m) % (n) > 0)) 22 | int const threadsPerBlock = sizeof(unsigned long long) * 8; 23 | 24 | __device__ inline float devIoU(float const * const a, float const * const b) { 25 | float left = max(a[0], b[0]), right = min(a[2], b[2]); 26 | float top = max(a[1], b[1]), bottom = min(a[3], b[3]); 27 | float width = max(right - left + 1, 0.f), height = max(bottom - top + 1, 0.f); 28 | float interS = width * height; 29 | float Sa = (a[2] - a[0] + 1) * (a[3] - a[1] + 1); 30 | float Sb = (b[2] - b[0] + 1) * (b[3] - b[1] + 1); 31 | return interS / (Sa + Sb - interS); 32 | } 33 | 34 | __global__ void nms_kernel(const int n_boxes, const float nms_overlap_thresh, 35 | const float *dev_boxes, unsigned long long *dev_mask) { 36 | const int row_start = blockIdx.y; 37 | const int col_start = blockIdx.x; 38 | 39 | // if (row_start > col_start) return; 40 | 41 | const int row_size = 42 | min(n_boxes - row_start * threadsPerBlock, threadsPerBlock); 43 | const int col_size = 44 | min(n_boxes - col_start * threadsPerBlock, threadsPerBlock); 45 | 46 | __shared__ float block_boxes[threadsPerBlock * 5]; 47 | if (threadIdx.x < col_size) { 48 | block_boxes[threadIdx.x * 5 + 0] = 49 | dev_boxes[(threadsPerBlock * col_start + threadIdx.x) * 5 + 0]; 50 | block_boxes[threadIdx.x * 5 + 1] = 51 | dev_boxes[(threadsPerBlock * col_start + threadIdx.x) * 5 + 1]; 52 | block_boxes[threadIdx.x * 5 + 2] = 53 | dev_boxes[(threadsPerBlock * col_start + threadIdx.x) * 5 + 2]; 54 | block_boxes[threadIdx.x * 5 + 3] = 55 | dev_boxes[(threadsPerBlock * col_start + threadIdx.x) * 5 + 3]; 56 | block_boxes[threadIdx.x * 5 + 4] = 57 | dev_boxes[(threadsPerBlock * col_start + threadIdx.x) * 5 + 4]; 58 | } 59 | __syncthreads(); 60 | 61 | if (threadIdx.x < row_size) { 62 | const int cur_box_idx = threadsPerBlock * row_start + threadIdx.x; 63 | const float *cur_box = dev_boxes + cur_box_idx * 5; 64 | int i = 0; 65 | unsigned long long t = 0; 66 | int start = 0; 67 | if (row_start == col_start) { 68 | start = threadIdx.x + 1; 69 | } 70 | for (i = start; i < col_size; i++) { 71 | if (devIoU(cur_box, block_boxes + i * 5) > nms_overlap_thresh) { 72 | t |= 1ULL << i; 73 | } 74 | } 75 | const int col_blocks = DIVUP(n_boxes, threadsPerBlock); 76 | dev_mask[cur_box_idx * col_blocks + col_start] = t; 77 | } 78 | } 79 | 80 | void _set_device(int device_id) { 81 | int current_device; 82 | CUDA_CHECK(cudaGetDevice(¤t_device)); 83 | if (current_device == device_id) { 84 | return; 85 | } 86 | // The call to cudaSetDevice must come before any calls to Get, which 87 | // may perform initialization using the GPU. 88 | CUDA_CHECK(cudaSetDevice(device_id)); 89 | } 90 | 91 | void _nms(int* keep_out, int* num_out, const float* boxes_host, int boxes_num, 92 | int boxes_dim, float nms_overlap_thresh, int device_id) { 93 | _set_device(device_id); 94 | 95 | float* boxes_dev = NULL; 96 | unsigned long long* mask_dev = NULL; 97 | 98 | const int col_blocks = DIVUP(boxes_num, threadsPerBlock); 99 | 100 | CUDA_CHECK(cudaMalloc(&boxes_dev, 101 | boxes_num * boxes_dim * sizeof(float))); 102 | CUDA_CHECK(cudaMemcpy(boxes_dev, 103 | boxes_host, 104 | boxes_num * boxes_dim * sizeof(float), 105 | cudaMemcpyHostToDevice)); 106 | 107 | CUDA_CHECK(cudaMalloc(&mask_dev, 108 | boxes_num * col_blocks * sizeof(unsigned long long))); 109 | 110 | dim3 blocks(DIVUP(boxes_num, threadsPerBlock), 111 | DIVUP(boxes_num, threadsPerBlock)); 112 | dim3 threads(threadsPerBlock); 113 | nms_kernel<<>>(boxes_num, 114 | nms_overlap_thresh, 115 | boxes_dev, 116 | mask_dev); 117 | 118 | std::vector mask_host(boxes_num * col_blocks); 119 | CUDA_CHECK(cudaMemcpy(&mask_host[0], 120 | mask_dev, 121 | sizeof(unsigned long long) * boxes_num * col_blocks, 122 | cudaMemcpyDeviceToHost)); 123 | 124 | std::vector remv(col_blocks); 125 | memset(&remv[0], 0, sizeof(unsigned long long) * col_blocks); 126 | 127 | int num_to_keep = 0; 128 | for (int i = 0; i < boxes_num; i++) { 129 | int nblock = i / threadsPerBlock; 130 | int inblock = i % threadsPerBlock; 131 | 132 | if (!(remv[nblock] & (1ULL << inblock))) { 133 | keep_out[num_to_keep++] = i; 134 | unsigned long long *p = &mask_host[0] + i * col_blocks; 135 | for (int j = nblock; j < col_blocks; j++) { 136 | remv[j] |= p[j]; 137 | } 138 | } 139 | } 140 | *num_out = num_to_keep; 141 | 142 | CUDA_CHECK(cudaFree(boxes_dev)); 143 | CUDA_CHECK(cudaFree(mask_dev)); 144 | } 145 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /utils/nms_wrapper.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 | from .nms.cpu_nms import cpu_nms, cpu_soft_nms 9 | from .nms.gpu_nms import gpu_nms 10 | 11 | 12 | # def nms(dets, thresh, force_cpu=False): 13 | # """Dispatch to either CPU or GPU NMS implementations.""" 14 | # 15 | # if dets.shape[0] == 0: 16 | # return [] 17 | # if cfg.USE_GPU_NMS and not force_cpu: 18 | # return gpu_nms(dets, thresh, device_id=cfg.GPU_ID) 19 | # else: 20 | # return cpu_nms(dets, thresh) 21 | 22 | 23 | def nms(dets, thresh, force_cpu=False): 24 | """Dispatch to either CPU or GPU NMS implementations.""" 25 | 26 | if dets.shape[0] == 0: 27 | return [] 28 | if force_cpu: 29 | #return cpu_soft_nms(dets, thresh, method = 0) 30 | return cpu_nms(dets, thresh) 31 | return gpu_nms(dets, thresh) 32 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /weightsBK/FaceBoxesProd.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WynMew/AnimeFaceBoxes/025b5e0a265e971d03cf850d67a52dad2ab392c6/weightsBK/FaceBoxesProd.pth --------------------------------------------------------------------------------