diff --git a/.gitattributes b/.gitattributes index a792e665b9528b1e3189c05e49a12215fc6aed9b..84020c69ee2cb312fa6db47791b1baf8f6047827 100644 --- a/.gitattributes +++ b/.gitattributes @@ -59,3 +59,13 @@ src/pixel3dmm/preprocessing/MICA/documents/LYHM.gif filter=lfs diff=lfs merge=lf src/pixel3dmm/preprocessing/MICA/documents/STIRLING.gif filter=lfs diff=lfs merge=lfs -text src/pixel3dmm/preprocessing/MICA/documents/teaser.jpg filter=lfs diff=lfs merge=lfs -text src/pixel3dmm/preprocessing/MICA/documents/voxceleb.gif filter=lfs diff=lfs merge=lfs -text +src/pixel3dmm/preprocessing/PIPNet/images/1_out_WFLW_model.jpg filter=lfs diff=lfs merge=lfs -text +src/pixel3dmm/preprocessing/PIPNet/images/1.jpg filter=lfs diff=lfs merge=lfs -text +src/pixel3dmm/preprocessing/PIPNet/images/2.jpg filter=lfs diff=lfs merge=lfs -text +src/pixel3dmm/preprocessing/PIPNet/images/3.jpg filter=lfs diff=lfs merge=lfs -text +src/pixel3dmm/preprocessing/PIPNet/images/speed.png filter=lfs diff=lfs merge=lfs -text +src/pixel3dmm/preprocessing/PIPNet/videos/002_out_WFLW_model.gif filter=lfs diff=lfs merge=lfs -text +src/pixel3dmm/preprocessing/PIPNet/videos/002.avi filter=lfs diff=lfs merge=lfs -text +src/pixel3dmm/preprocessing/PIPNet/videos/007_out_300W_CELEBA_model.gif filter=lfs diff=lfs merge=lfs -text +src/pixel3dmm/preprocessing/PIPNet/videos/007.avi filter=lfs diff=lfs merge=lfs -text +src/pixel3dmm/preprocessing/PIPNet/videos/shaolin_soccer.gif filter=lfs diff=lfs merge=lfs -text diff --git a/src/pixel3dmm/preprocessing/PIPNet/FaceBoxesV2/detector.py b/src/pixel3dmm/preprocessing/PIPNet/FaceBoxesV2/detector.py new file mode 100644 index 0000000000000000000000000000000000000000..bb9c8fe988e05bb5d72103d6699ca8eac6de678f --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/FaceBoxesV2/detector.py @@ -0,0 +1,39 @@ +import cv2 + +class Detector(object): + def __init__(self, model_arch, model_weights): + self.model_arch = model_arch + self.model_weights = model_weights + + def detect(self, image, thresh): + raise NotImplementedError + + def crop(self, image, detections): + crops = [] + for det in detections: + xmin = max(det[2], 0) + ymin = max(det[3], 0) + width = det[4] + height = det[5] + xmax = min(xmin+width, image.shape[1]) + ymax = min(ymin+height, image.shape[0]) + cut = image[ymin:ymax, xmin:xmax,:] + crops.append(cut) + + return crops + + def draw(self, image, detections, im_scale=None): + if im_scale is not None: + image = cv2.resize(image, None, None, fx=im_scale, fy=im_scale, interpolation=cv2.INTER_LINEAR) + detections = [[det[0],det[1],int(det[2]*im_scale),int(det[3]*im_scale),int(det[4]*im_scale),int(det[5]*im_scale)] for det in detections] + + for det in detections: + xmin = det[2] + ymin = det[3] + width = det[4] + height = det[5] + xmax = xmin + width + ymax = ymin + height + cv2.rectangle(image, (xmin, ymin), (xmax, ymax), (0, 0, 255), 2) + + return image diff --git a/src/pixel3dmm/preprocessing/PIPNet/FaceBoxesV2/faceboxes_detector.py b/src/pixel3dmm/preprocessing/PIPNet/FaceBoxesV2/faceboxes_detector.py new file mode 100644 index 0000000000000000000000000000000000000000..5d3f35f3a21e7a5279ac20bb4c534f7edcaa226c --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/FaceBoxesV2/faceboxes_detector.py @@ -0,0 +1,97 @@ +from detector import Detector +import cv2, os +import numpy as np +import torch +import torch.nn as nn +from utils.config import cfg +from utils.prior_box import PriorBox +from utils.nms_wrapper import nms +from utils.faceboxes import FaceBoxesV2 +from utils.box_utils import decode +import time + +class FaceBoxesDetector(Detector): + def __init__(self, model_arch, model_weights, use_gpu, device): + super().__init__(model_arch, model_weights) + self.name = 'FaceBoxesDetector' + self.net = FaceBoxesV2(phase='test', size=None, num_classes=2) # initialize detector + self.use_gpu = use_gpu + self.device = device + + state_dict = torch.load(self.model_weights, map_location=self.device) + # create new OrderedDict that does not contain `module.` + from collections import OrderedDict + new_state_dict = OrderedDict() + for k, v in state_dict.items(): + name = k[7:] # remove `module.` + new_state_dict[name] = v + # load params + self.net.load_state_dict(new_state_dict) + self.net = self.net.to(self.device) + self.net.eval() + + + def detect(self, image, thresh=0.6, im_scale=None): + # auto resize for large images + if im_scale is None: + height, width, _ = image.shape + if min(height, width) > 600: + im_scale = 600. / min(height, width) + else: + im_scale = 1 + image_scale = cv2.resize(image, None, None, fx=im_scale, fy=im_scale, interpolation=cv2.INTER_LINEAR) + + scale = torch.Tensor([image_scale.shape[1], image_scale.shape[0], image_scale.shape[1], image_scale.shape[0]]) + image_scale = torch.from_numpy(image_scale.transpose(2,0,1)).to(self.device).int() + mean_tmp = torch.IntTensor([104, 117, 123]).to(self.device) + mean_tmp = mean_tmp.unsqueeze(1).unsqueeze(2) + image_scale -= mean_tmp + image_scale = image_scale.float().unsqueeze(0) + scale = scale.to(self.device) + + with torch.no_grad(): + out = self.net(image_scale) + #priorbox = PriorBox(cfg, out[2], (image_scale.size()[2], image_scale.size()[3]), phase='test') + priorbox = PriorBox(cfg, image_size=(image_scale.size()[2], image_scale.size()[3])) + priors = priorbox.forward() + priors = priors.to(self.device) + loc, conf = out + prior_data = priors.data + boxes = decode(loc.data.squeeze(0), prior_data, cfg['variance']) + boxes = boxes * scale + boxes = boxes.cpu().numpy() + scores = conf.data.cpu().numpy()[:, 1] + + # ignore low scores + inds = np.where(scores > thresh)[0] + boxes = boxes[inds] + scores = scores[inds] + + # keep top-K before NMS + order = scores.argsort()[::-1][:5000] + boxes = boxes[order] + scores = scores[order] + + # do NMS + dets = np.hstack((boxes, scores[:, np.newaxis])).astype(np.float32, copy=False) + keep = nms(dets, 0.3) + dets = dets[keep, :] + + dets = dets[:750, :] + detections_scale = [] + for i in range(dets.shape[0]): + xmin = int(dets[i][0]) + ymin = int(dets[i][1]) + xmax = int(dets[i][2]) + ymax = int(dets[i][3]) + score = dets[i][4] + width = xmax - xmin + height = ymax - ymin + detections_scale.append(['face', score, xmin, ymin, width, height]) + + # adapt bboxes to the original image size + if len(detections_scale) > 0: + detections_scale = [[det[0],det[1],int(det[2]/im_scale),int(det[3]/im_scale),int(det[4]/im_scale),int(det[5]/im_scale)] for det in detections_scale] + + return detections_scale, im_scale + diff --git a/src/pixel3dmm/preprocessing/PIPNet/FaceBoxesV2/utils/__init__.py b/src/pixel3dmm/preprocessing/PIPNet/FaceBoxesV2/utils/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/src/pixel3dmm/preprocessing/PIPNet/FaceBoxesV2/utils/box_utils.py b/src/pixel3dmm/preprocessing/PIPNet/FaceBoxesV2/utils/box_utils.py new file mode 100644 index 0000000000000000000000000000000000000000..4797f1d7498cc35499c9b86a35c0754eb16e5a60 --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/FaceBoxesV2/utils/box_utils.py @@ -0,0 +1,276 @@ +import torch +import numpy as np + + +def point_form(boxes): + """ Convert prior_boxes to (xmin, ymin, xmax, ymax) + representation for comparison to point form ground truth data. + Args: + boxes: (tensor) center-size default boxes from priorbox layers. + Return: + boxes: (tensor) Converted xmin, ymin, xmax, ymax form of boxes. + """ + return torch.cat((boxes[:, :2] - boxes[:, 2:]/2, # xmin, ymin + boxes[:, :2] + boxes[:, 2:]/2), 1) # xmax, ymax + + +def center_size(boxes): + """ Convert prior_boxes to (cx, cy, w, h) + representation for comparison to center-size form ground truth data. + Args: + boxes: (tensor) point_form boxes + Return: + boxes: (tensor) Converted xmin, ymin, xmax, ymax form of boxes. + """ + return torch.cat((boxes[:, 2:] + boxes[:, :2])/2, # cx, cy + boxes[:, 2:] - boxes[:, :2], 1) # w, h + + +def intersect(box_a, box_b): + """ We resize both tensors to [A,B,2] without new malloc: + [A,2] -> [A,1,2] -> [A,B,2] + [B,2] -> [1,B,2] -> [A,B,2] + Then we compute the area of intersect between box_a and box_b. + Args: + box_a: (tensor) bounding boxes, Shape: [A,4]. + box_b: (tensor) bounding boxes, Shape: [B,4]. + Return: + (tensor) intersection area, Shape: [A,B]. + """ + A = box_a.size(0) + B = box_b.size(0) + max_xy = torch.min(box_a[:, 2:].unsqueeze(1).expand(A, B, 2), + box_b[:, 2:].unsqueeze(0).expand(A, B, 2)) + min_xy = torch.max(box_a[:, :2].unsqueeze(1).expand(A, B, 2), + box_b[:, :2].unsqueeze(0).expand(A, B, 2)) + inter = torch.clamp((max_xy - min_xy), min=0) + return inter[:, :, 0] * inter[:, :, 1] + + +def jaccard(box_a, box_b): + """Compute the jaccard overlap of two sets of boxes. The jaccard overlap + is simply the intersection over union of two boxes. Here we operate on + ground truth boxes and default boxes. + E.g.: + A ∩ B / A ∪ B = A ∩ B / (area(A) + area(B) - A ∩ B) + Args: + box_a: (tensor) Ground truth bounding boxes, Shape: [num_objects,4] + box_b: (tensor) Prior boxes from priorbox layers, Shape: [num_priors,4] + Return: + jaccard overlap: (tensor) Shape: [box_a.size(0), box_b.size(0)] + """ + inter = intersect(box_a, box_b) + area_a = ((box_a[:, 2]-box_a[:, 0]) * + (box_a[:, 3]-box_a[:, 1])).unsqueeze(1).expand_as(inter) # [A,B] + area_b = ((box_b[:, 2]-box_b[:, 0]) * + (box_b[:, 3]-box_b[:, 1])).unsqueeze(0).expand_as(inter) # [A,B] + union = area_a + area_b - inter + return inter / union # [A,B] + + +def matrix_iou(a, b): + """ + return iou of a and b, numpy version for data augenmentation + """ + lt = np.maximum(a[:, np.newaxis, :2], b[:, :2]) + rb = np.minimum(a[:, np.newaxis, 2:], b[:, 2:]) + + area_i = np.prod(rb - lt, axis=2) * (lt < rb).all(axis=2) + area_a = np.prod(a[:, 2:] - a[:, :2], axis=1) + area_b = np.prod(b[:, 2:] - b[:, :2], axis=1) + return area_i / (area_a[:, np.newaxis] + area_b - area_i) + + +def matrix_iof(a, b): + """ + return iof of a and b, numpy version for data augenmentation + """ + lt = np.maximum(a[:, np.newaxis, :2], b[:, :2]) + rb = np.minimum(a[:, np.newaxis, 2:], b[:, 2:]) + + area_i = np.prod(rb - lt, axis=2) * (lt < rb).all(axis=2) + area_a = np.prod(a[:, 2:] - a[:, :2], axis=1) + return area_i / np.maximum(area_a[:, np.newaxis], 1) + + +def match(threshold, truths, priors, variances, labels, loc_t, conf_t, idx): + """Match each prior box with the ground truth box of the highest jaccard + overlap, encode the bounding boxes, then return the matched indices + corresponding to both confidence and location preds. + Args: + threshold: (float) The overlap threshold used when mathing boxes. + truths: (tensor) Ground truth boxes, Shape: [num_obj, num_priors]. + priors: (tensor) Prior boxes from priorbox layers, Shape: [n_priors,4]. + variances: (tensor) Variances corresponding to each prior coord, + Shape: [num_priors, 4]. + labels: (tensor) All the class labels for the image, Shape: [num_obj]. + loc_t: (tensor) Tensor to be filled w/ endcoded location targets. + conf_t: (tensor) Tensor to be filled w/ matched indices for conf preds. + idx: (int) current batch index + Return: + The matched indices corresponding to 1)location and 2)confidence preds. + """ + # jaccard index + overlaps = jaccard( + truths, + point_form(priors) + ) + # (Bipartite Matching) + # [1,num_objects] best prior for each ground truth + best_prior_overlap, best_prior_idx = overlaps.max(1, keepdim=True) + + # ignore hard gt + valid_gt_idx = best_prior_overlap[:, 0] >= 0.2 + best_prior_idx_filter = best_prior_idx[valid_gt_idx, :] + if best_prior_idx_filter.shape[0] <= 0: + loc_t[idx] = 0 + conf_t[idx] = 0 + return + + # [1,num_priors] best ground truth for each prior + best_truth_overlap, best_truth_idx = overlaps.max(0, keepdim=True) + best_truth_idx.squeeze_(0) + best_truth_overlap.squeeze_(0) + best_prior_idx.squeeze_(1) + best_prior_idx_filter.squeeze_(1) + best_prior_overlap.squeeze_(1) + best_truth_overlap.index_fill_(0, best_prior_idx_filter, 2) # ensure best prior + # TODO refactor: index best_prior_idx with long tensor + # ensure every gt matches with its prior of max overlap + for j in range(best_prior_idx.size(0)): + best_truth_idx[best_prior_idx[j]] = j + matches = truths[best_truth_idx] # Shape: [num_priors,4] + conf = labels[best_truth_idx] # Shape: [num_priors] + conf[best_truth_overlap < threshold] = 0 # label as background + loc = encode(matches, priors, variances) + loc_t[idx] = loc # [num_priors,4] encoded offsets to learn + conf_t[idx] = conf # [num_priors] top class label for each prior + + +def encode(matched, priors, variances): + """Encode the variances from the priorbox layers into the ground truth boxes + we have matched (based on jaccard overlap) with the prior boxes. + Args: + matched: (tensor) Coords of ground truth for each prior in point-form + Shape: [num_priors, 4]. + priors: (tensor) Prior boxes in center-offset form + Shape: [num_priors,4]. + variances: (list[float]) Variances of priorboxes + Return: + encoded boxes (tensor), Shape: [num_priors, 4] + """ + + # dist b/t match center and prior's center + g_cxcy = (matched[:, :2] + matched[:, 2:])/2 - priors[:, :2] + # encode variance + g_cxcy /= (variances[0] * priors[:, 2:]) + # match wh / prior wh + g_wh = (matched[:, 2:] - matched[:, :2]) / priors[:, 2:] + g_wh = torch.log(g_wh) / variances[1] + # return target for smooth_l1_loss + return torch.cat([g_cxcy, g_wh], 1) # [num_priors,4] + + +# Adapted from https://github.com/Hakuyume/chainer-ssd +def decode(loc, priors, variances): + """Decode locations from predictions using priors to undo + the encoding we did for offset regression at train time. + Args: + loc (tensor): location predictions for loc layers, + Shape: [num_priors,4] + priors (tensor): Prior boxes in center-offset form. + Shape: [num_priors,4]. + variances: (list[float]) Variances of priorboxes + Return: + decoded bounding box predictions + """ + + boxes = torch.cat(( + priors[:, :2] + loc[:, :2] * variances[0] * priors[:, 2:], + priors[:, 2:] * torch.exp(loc[:, 2:] * variances[1])), 1) + boxes[:, :2] -= boxes[:, 2:] / 2 + boxes[:, 2:] += boxes[:, :2] + return boxes + + +def log_sum_exp(x): + """Utility function for computing log_sum_exp while determining + This will be used to determine unaveraged confidence loss across + all examples in a batch. + Args: + x (Variable(tensor)): conf_preds from conf layers + """ + x_max = x.data.max() + return torch.log(torch.sum(torch.exp(x-x_max), 1, keepdim=True)) + x_max + + +# Original author: Francisco Massa: +# https://github.com/fmassa/object-detection.torch +# Ported to PyTorch by Max deGroot (02/01/2017) +def nms(boxes, scores, overlap=0.5, top_k=200): + """Apply non-maximum suppression at test time to avoid detecting too many + overlapping bounding boxes for a given object. + Args: + boxes: (tensor) The location preds for the img, Shape: [num_priors,4]. + scores: (tensor) The class predscores for the img, Shape:[num_priors]. + overlap: (float) The overlap thresh for suppressing unnecessary boxes. + top_k: (int) The Maximum number of box preds to consider. + Return: + The indices of the kept boxes with respect to num_priors. + """ + + keep = torch.Tensor(scores.size(0)).fill_(0).long() + if boxes.numel() == 0: + return keep + x1 = boxes[:, 0] + y1 = boxes[:, 1] + x2 = boxes[:, 2] + y2 = boxes[:, 3] + area = torch.mul(x2 - x1, y2 - y1) + v, idx = scores.sort(0) # sort in ascending order + # I = I[v >= 0.01] + idx = idx[-top_k:] # indices of the top-k largest vals + xx1 = boxes.new() + yy1 = boxes.new() + xx2 = boxes.new() + yy2 = boxes.new() + w = boxes.new() + h = boxes.new() + + # keep = torch.Tensor() + count = 0 + while idx.numel() > 0: + i = idx[-1] # index of current largest val + # keep.append(i) + keep[count] = i + count += 1 + if idx.size(0) == 1: + break + idx = idx[:-1] # remove kept element from view + # load bboxes of next highest vals + torch.index_select(x1, 0, idx, out=xx1) + torch.index_select(y1, 0, idx, out=yy1) + torch.index_select(x2, 0, idx, out=xx2) + torch.index_select(y2, 0, idx, out=yy2) + # store element-wise max with next highest score + xx1 = torch.clamp(xx1, min=x1[i]) + yy1 = torch.clamp(yy1, min=y1[i]) + xx2 = torch.clamp(xx2, max=x2[i]) + yy2 = torch.clamp(yy2, max=y2[i]) + w.resize_as_(xx2) + h.resize_as_(yy2) + w = xx2 - xx1 + h = yy2 - yy1 + # check sizes of xx1 and xx2.. after each iteration + w = torch.clamp(w, min=0.0) + h = torch.clamp(h, min=0.0) + inter = w*h + # IoU = i / (area(a) + area(b) - i) + rem_areas = torch.index_select(area, 0, idx) # load remaining areas) + union = (rem_areas - inter) + area[i] + IoU = inter/union # store result in iou + # keep only elements with an IoU <= overlap + idx = idx[IoU.le(overlap)] + return keep, count + + diff --git a/src/pixel3dmm/preprocessing/PIPNet/FaceBoxesV2/utils/build.py b/src/pixel3dmm/preprocessing/PIPNet/FaceBoxesV2/utils/build.py new file mode 100644 index 0000000000000000000000000000000000000000..b1d4fb495db46eb5eb0b311d9bfbd5e111d49c56 --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/FaceBoxesV2/utils/build.py @@ -0,0 +1,57 @@ +# coding: utf-8 + +# -------------------------------------------------------- +# Fast R-CNN +# Copyright (c) 2015 Microsoft +# Licensed under The MIT License [see LICENSE for details] +# Written by Ross Girshick +# -------------------------------------------------------- + +import os +from os.path import join as pjoin +import numpy as np +from distutils.core import setup +from distutils.extension import Extension +from Cython.Distutils import build_ext + + +def find_in_path(name, path): + "Find a file in a search path" + # adapted fom http://code.activestate.com/recipes/52224-find-a-file-given-a-search-path/ + for dir in path.split(os.pathsep): + binpath = pjoin(dir, name) + if os.path.exists(binpath): + return os.path.abspath(binpath) + return None + + +# Obtain the numpy include directory. This logic works across numpy versions. +try: + numpy_include = np.get_include() +except AttributeError: + numpy_include = np.get_numpy_include() + + +# run the customize_compiler +class custom_build_ext(build_ext): + def build_extensions(self): + # customize_compiler_for_nvcc(self.compiler) + build_ext.build_extensions(self) + + +ext_modules = [ + Extension( + "nms.cpu_nms", + ["nms/cpu_nms.pyx"], + # extra_compile_args={'gcc': ["-Wno-cpp", "-Wno-unused-function"]}, + extra_compile_args=["-Wno-cpp", "-Wno-unused-function"], + include_dirs=[numpy_include] + ) +] + +setup( + name='mot_utils', + ext_modules=ext_modules, + # inject our custom trigger + cmdclass={'build_ext': custom_build_ext}, +) diff --git a/src/pixel3dmm/preprocessing/PIPNet/FaceBoxesV2/utils/config.py b/src/pixel3dmm/preprocessing/PIPNet/FaceBoxesV2/utils/config.py new file mode 100644 index 0000000000000000000000000000000000000000..527c8b3754fbc6e1187e4539bf5075cd0cea4952 --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/FaceBoxesV2/utils/config.py @@ -0,0 +1,14 @@ +# config.py + +cfg = { + 'name': 'FaceBoxes', + #'min_dim': 1024, + #'feature_maps': [[32, 32], [16, 16], [8, 8]], + # 'aspect_ratios': [[1], [1], [1]], + 'min_sizes': [[32, 64, 128], [256], [512]], + 'steps': [32, 64, 128], + 'variance': [0.1, 0.2], + 'clip': False, + 'loc_weight': 2.0, + 'gpu_train': True +} diff --git a/src/pixel3dmm/preprocessing/PIPNet/FaceBoxesV2/utils/faceboxes.py b/src/pixel3dmm/preprocessing/PIPNet/FaceBoxesV2/utils/faceboxes.py new file mode 100644 index 0000000000000000000000000000000000000000..4ae4d31a7dfde983da5459c169a30e5a11ccdd7a --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/FaceBoxesV2/utils/faceboxes.py @@ -0,0 +1,239 @@ +import torch +import torch.nn as nn +import torch.nn.functional as F + + +class BasicConv2d(nn.Module): + + def __init__(self, in_channels, out_channels, **kwargs): + super(BasicConv2d, self).__init__() + self.conv = nn.Conv2d(in_channels, out_channels, bias=False, **kwargs) + self.bn = nn.BatchNorm2d(out_channels, eps=1e-5) + + def forward(self, x): + x = self.conv(x) + x = self.bn(x) + return F.relu(x, inplace=True) + + +class Inception(nn.Module): + + def __init__(self): + super(Inception, self).__init__() + self.branch1x1 = BasicConv2d(128, 32, kernel_size=1, padding=0) + self.branch1x1_2 = BasicConv2d(128, 32, kernel_size=1, padding=0) + self.branch3x3_reduce = BasicConv2d(128, 24, kernel_size=1, padding=0) + self.branch3x3 = BasicConv2d(24, 32, kernel_size=3, padding=1) + self.branch3x3_reduce_2 = BasicConv2d(128, 24, kernel_size=1, padding=0) + self.branch3x3_2 = BasicConv2d(24, 32, kernel_size=3, padding=1) + self.branch3x3_3 = BasicConv2d(32, 32, kernel_size=3, padding=1) + + def forward(self, x): + branch1x1 = self.branch1x1(x) + + branch1x1_pool = F.avg_pool2d(x, kernel_size=3, stride=1, padding=1) + branch1x1_2 = self.branch1x1_2(branch1x1_pool) + + branch3x3_reduce = self.branch3x3_reduce(x) + branch3x3 = self.branch3x3(branch3x3_reduce) + + branch3x3_reduce_2 = self.branch3x3_reduce_2(x) + branch3x3_2 = self.branch3x3_2(branch3x3_reduce_2) + branch3x3_3 = self.branch3x3_3(branch3x3_2) + + outputs = [branch1x1, branch1x1_2, branch3x3, branch3x3_3] + return torch.cat(outputs, 1) + + +class CRelu(nn.Module): + + def __init__(self, in_channels, out_channels, **kwargs): + super(CRelu, self).__init__() + self.conv = nn.Conv2d(in_channels, out_channels, bias=False, **kwargs) + self.bn = nn.BatchNorm2d(out_channels, eps=1e-5) + + def forward(self, x): + x = self.conv(x) + x = self.bn(x) + x = torch.cat([x, -x], 1) + x = F.relu(x, inplace=True) + return x + + +class FaceBoxes(nn.Module): + + def __init__(self, phase, size, num_classes): + super(FaceBoxes, self).__init__() + self.phase = phase + self.num_classes = num_classes + self.size = size + + self.conv1 = CRelu(3, 24, kernel_size=7, stride=4, padding=3) + self.conv2 = CRelu(48, 64, kernel_size=5, stride=2, padding=2) + + self.inception1 = Inception() + self.inception2 = Inception() + self.inception3 = Inception() + + self.conv3_1 = BasicConv2d(128, 128, kernel_size=1, stride=1, padding=0) + self.conv3_2 = BasicConv2d(128, 256, kernel_size=3, stride=2, padding=1) + + self.conv4_1 = BasicConv2d(256, 128, kernel_size=1, stride=1, padding=0) + self.conv4_2 = BasicConv2d(128, 256, kernel_size=3, stride=2, padding=1) + + self.loc, self.conf = self.multibox(self.num_classes) + + if self.phase == 'test': + self.softmax = nn.Softmax(dim=-1) + + if self.phase == 'train': + for m in self.modules(): + if isinstance(m, nn.Conv2d): + if m.bias is not None: + nn.init.xavier_normal_(m.weight.data) + m.bias.data.fill_(0.02) + else: + m.weight.data.normal_(0, 0.01) + elif isinstance(m, nn.BatchNorm2d): + m.weight.data.fill_(1) + m.bias.data.zero_() + + def multibox(self, num_classes): + loc_layers = [] + conf_layers = [] + loc_layers += [nn.Conv2d(128, 21 * 4, kernel_size=3, padding=1)] + conf_layers += [nn.Conv2d(128, 21 * num_classes, kernel_size=3, padding=1)] + loc_layers += [nn.Conv2d(256, 1 * 4, kernel_size=3, padding=1)] + conf_layers += [nn.Conv2d(256, 1 * num_classes, kernel_size=3, padding=1)] + loc_layers += [nn.Conv2d(256, 1 * 4, kernel_size=3, padding=1)] + conf_layers += [nn.Conv2d(256, 1 * num_classes, kernel_size=3, padding=1)] + return nn.Sequential(*loc_layers), nn.Sequential(*conf_layers) + + def forward(self, x): + + detection_sources = list() + loc = list() + conf = list() + + x = self.conv1(x) + x = F.max_pool2d(x, kernel_size=3, stride=2, padding=1) + x = self.conv2(x) + x = F.max_pool2d(x, kernel_size=3, stride=2, padding=1) + x = self.inception1(x) + x = self.inception2(x) + x = self.inception3(x) + detection_sources.append(x) + + x = self.conv3_1(x) + x = self.conv3_2(x) + detection_sources.append(x) + + x = self.conv4_1(x) + x = self.conv4_2(x) + detection_sources.append(x) + + for (x, l, c) in zip(detection_sources, self.loc, self.conf): + loc.append(l(x).permute(0, 2, 3, 1).contiguous()) + conf.append(c(x).permute(0, 2, 3, 1).contiguous()) + + loc = torch.cat([o.view(o.size(0), -1) for o in loc], 1) + conf = torch.cat([o.view(o.size(0), -1) for o in conf], 1) + + if self.phase == "test": + output = (loc.view(loc.size(0), -1, 4), + self.softmax(conf.view(conf.size(0), -1, self.num_classes))) + else: + output = (loc.view(loc.size(0), -1, 4), + conf.view(conf.size(0), -1, self.num_classes)) + + return output + +class FaceBoxesV2(nn.Module): + + def __init__(self, phase, size, num_classes): + super(FaceBoxesV2, self).__init__() + self.phase = phase + self.num_classes = num_classes + self.size = size + + self.conv1 = BasicConv2d(3, 8, kernel_size=3, stride=2, padding=1) + self.conv2 = BasicConv2d(8, 16, kernel_size=3, stride=2, padding=1) + self.conv3 = BasicConv2d(16, 32, kernel_size=3, stride=2, padding=1) + self.conv4 = BasicConv2d(32, 64, kernel_size=3, stride=2, padding=1) + self.conv5 = BasicConv2d(64, 128, kernel_size=3, stride=2, padding=1) + + self.inception1 = Inception() + self.inception2 = Inception() + self.inception3 = Inception() + + self.conv6_1 = BasicConv2d(128, 128, kernel_size=1, stride=1, padding=0) + self.conv6_2 = BasicConv2d(128, 256, kernel_size=3, stride=2, padding=1) + + self.conv7_1 = BasicConv2d(256, 128, kernel_size=1, stride=1, padding=0) + self.conv7_2 = BasicConv2d(128, 256, kernel_size=3, stride=2, padding=1) + + self.loc, self.conf = self.multibox(self.num_classes) + + if self.phase == 'test': + self.softmax = nn.Softmax(dim=-1) + + if self.phase == 'train': + for m in self.modules(): + if isinstance(m, nn.Conv2d): + if m.bias is not None: + nn.init.xavier_normal_(m.weight.data) + m.bias.data.fill_(0.02) + else: + m.weight.data.normal_(0, 0.01) + elif isinstance(m, nn.BatchNorm2d): + m.weight.data.fill_(1) + m.bias.data.zero_() + + def multibox(self, num_classes): + loc_layers = [] + conf_layers = [] + loc_layers += [nn.Conv2d(128, 21 * 4, kernel_size=3, padding=1)] + conf_layers += [nn.Conv2d(128, 21 * num_classes, kernel_size=3, padding=1)] + loc_layers += [nn.Conv2d(256, 1 * 4, kernel_size=3, padding=1)] + conf_layers += [nn.Conv2d(256, 1 * num_classes, kernel_size=3, padding=1)] + loc_layers += [nn.Conv2d(256, 1 * 4, kernel_size=3, padding=1)] + conf_layers += [nn.Conv2d(256, 1 * num_classes, kernel_size=3, padding=1)] + return nn.Sequential(*loc_layers), nn.Sequential(*conf_layers) + + def forward(self, x): + + sources = list() + loc = list() + conf = list() + + x = self.conv1(x) + x = self.conv2(x) + x = self.conv3(x) + x = self.conv4(x) + x = self.conv5(x) + x = self.inception1(x) + x = self.inception2(x) + x = self.inception3(x) + sources.append(x) + x = self.conv6_1(x) + x = self.conv6_2(x) + sources.append(x) + x = self.conv7_1(x) + x = self.conv7_2(x) + sources.append(x) + + for (x, l, c) in zip(sources, self.loc, self.conf): + loc.append(l(x).permute(0, 2, 3, 1).contiguous()) + conf.append(c(x).permute(0, 2, 3, 1).contiguous()) + + loc = torch.cat([o.view(o.size(0), -1) for o in loc], 1) + conf = torch.cat([o.view(o.size(0), -1) for o in conf], 1) + + if self.phase == "test": + output = (loc.view(loc.size(0), -1, 4), + self.softmax(conf.view(-1, self.num_classes))) + else: + output = (loc.view(loc.size(0), -1, 4), + conf.view(conf.size(0), -1, self.num_classes)) + + return output diff --git a/src/pixel3dmm/preprocessing/PIPNet/FaceBoxesV2/utils/make.sh b/src/pixel3dmm/preprocessing/PIPNet/FaceBoxesV2/utils/make.sh new file mode 100644 index 0000000000000000000000000000000000000000..9693ed462e516432e100cc743ae3a1417aa12c41 --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/FaceBoxesV2/utils/make.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash +python3 build.py build_ext --inplace + diff --git a/src/pixel3dmm/preprocessing/PIPNet/FaceBoxesV2/utils/nms/__init__.py b/src/pixel3dmm/preprocessing/PIPNet/FaceBoxesV2/utils/nms/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/src/pixel3dmm/preprocessing/PIPNet/FaceBoxesV2/utils/nms/__pycache__/__init__.cpython-36.pyc b/src/pixel3dmm/preprocessing/PIPNet/FaceBoxesV2/utils/nms/__pycache__/__init__.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0227b79ca5dbba07348701d06cc6ea8b0113277b Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/FaceBoxesV2/utils/nms/__pycache__/__init__.cpython-36.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/FaceBoxesV2/utils/nms/__pycache__/__init__.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/FaceBoxesV2/utils/nms/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..91563bdbeaa2faec95f545b4a52ac4f2b9816a91 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/FaceBoxesV2/utils/nms/__pycache__/__init__.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/FaceBoxesV2/utils/nms/__pycache__/__init__.cpython-38.pyc b/src/pixel3dmm/preprocessing/PIPNet/FaceBoxesV2/utils/nms/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6ddb8d139e111b2aa2b79cc6c5567348b471ff68 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/FaceBoxesV2/utils/nms/__pycache__/__init__.cpython-38.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/FaceBoxesV2/utils/nms/cpu_nms.pyx b/src/pixel3dmm/preprocessing/PIPNet/FaceBoxesV2/utils/nms/cpu_nms.pyx new file mode 100644 index 0000000000000000000000000000000000000000..5f921bb2e0ad8be2f9f35b59a452327b191fae78 --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/FaceBoxesV2/utils/nms/cpu_nms.pyx @@ -0,0 +1,163 @@ +# -------------------------------------------------------- +# Fast R-CNN +# Copyright (c) 2015 Microsoft +# Licensed under The MIT License [see LICENSE for details] +# Written by Ross Girshick +# -------------------------------------------------------- + +import numpy as np +cimport numpy as np + +cdef inline np.float32_t max(np.float32_t a, np.float32_t b): + return a if a >= b else b + +cdef inline np.float32_t min(np.float32_t a, np.float32_t b): + return a if a <= b else b + +def cpu_nms(np.ndarray[np.float32_t, ndim=2] dets, np.float thresh): + cdef np.ndarray[np.float32_t, ndim=1] x1 = dets[:, 0] + cdef np.ndarray[np.float32_t, ndim=1] y1 = dets[:, 1] + cdef np.ndarray[np.float32_t, ndim=1] x2 = dets[:, 2] + cdef np.ndarray[np.float32_t, ndim=1] y2 = dets[:, 3] + cdef np.ndarray[np.float32_t, ndim=1] scores = dets[:, 4] + + cdef np.ndarray[np.float32_t, ndim=1] areas = (x2 - x1 + 1) * (y2 - y1 + 1) + cdef np.ndarray[np.int_t, ndim=1] order = scores.argsort()[::-1] + + cdef int ndets = dets.shape[0] + cdef np.ndarray[np.int_t, ndim=1] suppressed = \ + np.zeros((ndets), dtype=np.int) + + # nominal indices + cdef int _i, _j + # sorted indices + cdef int i, j + # temp variables for box i's (the box currently under consideration) + cdef np.float32_t ix1, iy1, ix2, iy2, iarea + # variables for computing overlap with box j (lower scoring box) + cdef np.float32_t xx1, yy1, xx2, yy2 + cdef np.float32_t w, h + cdef np.float32_t inter, ovr + + keep = [] + for _i in range(ndets): + i = order[_i] + if suppressed[i] == 1: + continue + keep.append(i) + ix1 = x1[i] + iy1 = y1[i] + ix2 = x2[i] + iy2 = y2[i] + iarea = areas[i] + for _j in range(_i + 1, ndets): + j = order[_j] + if suppressed[j] == 1: + continue + xx1 = max(ix1, x1[j]) + yy1 = max(iy1, y1[j]) + xx2 = min(ix2, x2[j]) + yy2 = min(iy2, y2[j]) + w = max(0.0, xx2 - xx1 + 1) + h = max(0.0, yy2 - yy1 + 1) + inter = w * h + ovr = inter / (iarea + areas[j] - inter) + if ovr >= thresh: + suppressed[j] = 1 + + return keep + +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): + cdef unsigned int N = boxes.shape[0] + cdef float iw, ih, box_area + cdef float ua + cdef int pos = 0 + cdef float maxscore = 0 + cdef int maxpos = 0 + cdef float x1,x2,y1,y2,tx1,tx2,ty1,ty2,ts,area,weight,ov + + for i in range(N): + maxscore = boxes[i, 4] + maxpos = i + + tx1 = boxes[i,0] + ty1 = boxes[i,1] + tx2 = boxes[i,2] + ty2 = boxes[i,3] + ts = boxes[i,4] + + pos = i + 1 + # get max box + while pos < N: + if maxscore < boxes[pos, 4]: + maxscore = boxes[pos, 4] + maxpos = pos + pos = pos + 1 + + # add max box as a detection + boxes[i,0] = boxes[maxpos,0] + boxes[i,1] = boxes[maxpos,1] + boxes[i,2] = boxes[maxpos,2] + boxes[i,3] = boxes[maxpos,3] + boxes[i,4] = boxes[maxpos,4] + + # swap ith box with position of max box + boxes[maxpos,0] = tx1 + boxes[maxpos,1] = ty1 + boxes[maxpos,2] = tx2 + boxes[maxpos,3] = ty2 + boxes[maxpos,4] = ts + + tx1 = boxes[i,0] + ty1 = boxes[i,1] + tx2 = boxes[i,2] + ty2 = boxes[i,3] + ts = boxes[i,4] + + pos = i + 1 + # NMS iterations, note that N changes if detection boxes fall below threshold + while pos < N: + x1 = boxes[pos, 0] + y1 = boxes[pos, 1] + x2 = boxes[pos, 2] + y2 = boxes[pos, 3] + s = boxes[pos, 4] + + area = (x2 - x1 + 1) * (y2 - y1 + 1) + iw = (min(tx2, x2) - max(tx1, x1) + 1) + if iw > 0: + ih = (min(ty2, y2) - max(ty1, y1) + 1) + if ih > 0: + ua = float((tx2 - tx1 + 1) * (ty2 - ty1 + 1) + area - iw * ih) + ov = iw * ih / ua #iou between max box and detection box + + if method == 1: # linear + if ov > Nt: + weight = 1 - ov + else: + weight = 1 + elif method == 2: # gaussian + weight = np.exp(-(ov * ov)/sigma) + else: # original NMS + if ov > Nt: + weight = 0 + else: + weight = 1 + + boxes[pos, 4] = weight*boxes[pos, 4] + + # if box score falls below threshold, discard the box by swapping with last box + # update N + if boxes[pos, 4] < threshold: + boxes[pos,0] = boxes[N-1, 0] + boxes[pos,1] = boxes[N-1, 1] + boxes[pos,2] = boxes[N-1, 2] + boxes[pos,3] = boxes[N-1, 3] + boxes[pos,4] = boxes[N-1, 4] + N = N - 1 + pos = pos - 1 + + pos = pos + 1 + + keep = [i for i in range(N)] + return keep diff --git a/src/pixel3dmm/preprocessing/PIPNet/FaceBoxesV2/utils/nms/gpu_nms.hpp b/src/pixel3dmm/preprocessing/PIPNet/FaceBoxesV2/utils/nms/gpu_nms.hpp new file mode 100644 index 0000000000000000000000000000000000000000..68b6d42cd88b59496b22a9e77919abe529b09014 --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/FaceBoxesV2/utils/nms/gpu_nms.hpp @@ -0,0 +1,2 @@ +void _nms(int* keep_out, int* num_out, const float* boxes_host, int boxes_num, + int boxes_dim, float nms_overlap_thresh, int device_id); diff --git a/src/pixel3dmm/preprocessing/PIPNet/FaceBoxesV2/utils/nms/gpu_nms.pyx b/src/pixel3dmm/preprocessing/PIPNet/FaceBoxesV2/utils/nms/gpu_nms.pyx new file mode 100644 index 0000000000000000000000000000000000000000..59d84afe94e42de3c456b73580ed83358a2b30d8 --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/FaceBoxesV2/utils/nms/gpu_nms.pyx @@ -0,0 +1,31 @@ +# -------------------------------------------------------- +# Faster R-CNN +# Copyright (c) 2015 Microsoft +# Licensed under The MIT License [see LICENSE for details] +# Written by Ross Girshick +# -------------------------------------------------------- + +import numpy as np +cimport numpy as np + +assert sizeof(int) == sizeof(np.int32_t) + +cdef extern from "gpu_nms.hpp": + void _nms(np.int32_t*, int*, np.float32_t*, int, int, float, int) + +def gpu_nms(np.ndarray[np.float32_t, ndim=2] dets, np.float thresh, + np.int32_t device_id=0): + cdef int boxes_num = dets.shape[0] + cdef int boxes_dim = dets.shape[1] + cdef int num_out + cdef np.ndarray[np.int32_t, ndim=1] \ + keep = np.zeros(boxes_num, dtype=np.int32) + cdef np.ndarray[np.float32_t, ndim=1] \ + scores = dets[:, 4] + cdef np.ndarray[np.int_t, ndim=1] \ + order = scores.argsort()[::-1] + cdef np.ndarray[np.float32_t, ndim=2] \ + sorted_dets = dets[order, :] + _nms(&keep[0], &num_out, &sorted_dets[0, 0], boxes_num, boxes_dim, thresh, device_id) + keep = keep[:num_out] + return list(order[keep]) diff --git a/src/pixel3dmm/preprocessing/PIPNet/FaceBoxesV2/utils/nms/nms_kernel.cu b/src/pixel3dmm/preprocessing/PIPNet/FaceBoxesV2/utils/nms/nms_kernel.cu new file mode 100644 index 0000000000000000000000000000000000000000..038a59012f60ebdf1182ecb778eb3b01a69bc5ed --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/FaceBoxesV2/utils/nms/nms_kernel.cu @@ -0,0 +1,144 @@ +// ------------------------------------------------------------------ +// Faster R-CNN +// Copyright (c) 2015 Microsoft +// Licensed under The MIT License [see fast-rcnn/LICENSE for details] +// Written by Shaoqing Ren +// ------------------------------------------------------------------ + +#include "gpu_nms.hpp" +#include +#include + +#define CUDA_CHECK(condition) \ + /* Code block avoids redefinition of cudaError_t error */ \ + do { \ + cudaError_t error = condition; \ + if (error != cudaSuccess) { \ + std::cout << cudaGetErrorString(error) << std::endl; \ + } \ + } while (0) + +#define DIVUP(m,n) ((m) / (n) + ((m) % (n) > 0)) +int const threadsPerBlock = sizeof(unsigned long long) * 8; + +__device__ inline float devIoU(float const * const a, float const * const b) { + float left = max(a[0], b[0]), right = min(a[2], b[2]); + float top = max(a[1], b[1]), bottom = min(a[3], b[3]); + float width = max(right - left + 1, 0.f), height = max(bottom - top + 1, 0.f); + float interS = width * height; + float Sa = (a[2] - a[0] + 1) * (a[3] - a[1] + 1); + float Sb = (b[2] - b[0] + 1) * (b[3] - b[1] + 1); + return interS / (Sa + Sb - interS); +} + +__global__ void nms_kernel(const int n_boxes, const float nms_overlap_thresh, + const float *dev_boxes, unsigned long long *dev_mask) { + const int row_start = blockIdx.y; + const int col_start = blockIdx.x; + + // if (row_start > col_start) return; + + const int row_size = + min(n_boxes - row_start * threadsPerBlock, threadsPerBlock); + const int col_size = + min(n_boxes - col_start * threadsPerBlock, threadsPerBlock); + + __shared__ float block_boxes[threadsPerBlock * 5]; + if (threadIdx.x < col_size) { + block_boxes[threadIdx.x * 5 + 0] = + dev_boxes[(threadsPerBlock * col_start + threadIdx.x) * 5 + 0]; + block_boxes[threadIdx.x * 5 + 1] = + dev_boxes[(threadsPerBlock * col_start + threadIdx.x) * 5 + 1]; + block_boxes[threadIdx.x * 5 + 2] = + dev_boxes[(threadsPerBlock * col_start + threadIdx.x) * 5 + 2]; + block_boxes[threadIdx.x * 5 + 3] = + dev_boxes[(threadsPerBlock * col_start + threadIdx.x) * 5 + 3]; + block_boxes[threadIdx.x * 5 + 4] = + dev_boxes[(threadsPerBlock * col_start + threadIdx.x) * 5 + 4]; + } + __syncthreads(); + + if (threadIdx.x < row_size) { + const int cur_box_idx = threadsPerBlock * row_start + threadIdx.x; + const float *cur_box = dev_boxes + cur_box_idx * 5; + int i = 0; + unsigned long long t = 0; + int start = 0; + if (row_start == col_start) { + start = threadIdx.x + 1; + } + for (i = start; i < col_size; i++) { + if (devIoU(cur_box, block_boxes + i * 5) > nms_overlap_thresh) { + t |= 1ULL << i; + } + } + const int col_blocks = DIVUP(n_boxes, threadsPerBlock); + dev_mask[cur_box_idx * col_blocks + col_start] = t; + } +} + +void _set_device(int device_id) { + int current_device; + CUDA_CHECK(cudaGetDevice(¤t_device)); + if (current_device == device_id) { + return; + } + // The call to cudaSetDevice must come before any calls to Get, which + // may perform initialization using the GPU. + CUDA_CHECK(cudaSetDevice(device_id)); +} + +void _nms(int* keep_out, int* num_out, const float* boxes_host, int boxes_num, + int boxes_dim, float nms_overlap_thresh, int device_id) { + _set_device(device_id); + + float* boxes_dev = NULL; + unsigned long long* mask_dev = NULL; + + const int col_blocks = DIVUP(boxes_num, threadsPerBlock); + + CUDA_CHECK(cudaMalloc(&boxes_dev, + boxes_num * boxes_dim * sizeof(float))); + CUDA_CHECK(cudaMemcpy(boxes_dev, + boxes_host, + boxes_num * boxes_dim * sizeof(float), + cudaMemcpyHostToDevice)); + + CUDA_CHECK(cudaMalloc(&mask_dev, + boxes_num * col_blocks * sizeof(unsigned long long))); + + dim3 blocks(DIVUP(boxes_num, threadsPerBlock), + DIVUP(boxes_num, threadsPerBlock)); + dim3 threads(threadsPerBlock); + nms_kernel<<>>(boxes_num, + nms_overlap_thresh, + boxes_dev, + mask_dev); + + std::vector mask_host(boxes_num * col_blocks); + CUDA_CHECK(cudaMemcpy(&mask_host[0], + mask_dev, + sizeof(unsigned long long) * boxes_num * col_blocks, + cudaMemcpyDeviceToHost)); + + std::vector remv(col_blocks); + memset(&remv[0], 0, sizeof(unsigned long long) * col_blocks); + + int num_to_keep = 0; + for (int i = 0; i < boxes_num; i++) { + int nblock = i / threadsPerBlock; + int inblock = i % threadsPerBlock; + + if (!(remv[nblock] & (1ULL << inblock))) { + keep_out[num_to_keep++] = i; + unsigned long long *p = &mask_host[0] + i * col_blocks; + for (int j = nblock; j < col_blocks; j++) { + remv[j] |= p[j]; + } + } + } + *num_out = num_to_keep; + + CUDA_CHECK(cudaFree(boxes_dev)); + CUDA_CHECK(cudaFree(mask_dev)); +} diff --git a/src/pixel3dmm/preprocessing/PIPNet/FaceBoxesV2/utils/nms/py_cpu_nms.py b/src/pixel3dmm/preprocessing/PIPNet/FaceBoxesV2/utils/nms/py_cpu_nms.py new file mode 100644 index 0000000000000000000000000000000000000000..54e7b25fef72b518df6dcf8d6fb78b986796c6e3 --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/FaceBoxesV2/utils/nms/py_cpu_nms.py @@ -0,0 +1,38 @@ +# -------------------------------------------------------- +# Fast R-CNN +# Copyright (c) 2015 Microsoft +# Licensed under The MIT License [see LICENSE for details] +# Written by Ross Girshick +# -------------------------------------------------------- + +import numpy as np + +def py_cpu_nms(dets, thresh): + """Pure Python NMS baseline.""" + x1 = dets[:, 0] + y1 = dets[:, 1] + x2 = dets[:, 2] + y2 = dets[:, 3] + scores = dets[:, 4] + + areas = (x2 - x1 + 1) * (y2 - y1 + 1) + order = scores.argsort()[::-1] + + keep = [] + while order.size > 0: + i = order[0] + keep.append(i) + xx1 = np.maximum(x1[i], x1[order[1:]]) + yy1 = np.maximum(y1[i], y1[order[1:]]) + xx2 = np.minimum(x2[i], x2[order[1:]]) + yy2 = np.minimum(y2[i], y2[order[1:]]) + + w = np.maximum(0.0, xx2 - xx1 + 1) + h = np.maximum(0.0, yy2 - yy1 + 1) + inter = w * h + ovr = inter / (areas[i] + areas[order[1:]] - inter) + + inds = np.where(ovr <= thresh)[0] + order = order[inds + 1] + + return keep diff --git a/src/pixel3dmm/preprocessing/PIPNet/FaceBoxesV2/utils/nms_wrapper.py b/src/pixel3dmm/preprocessing/PIPNet/FaceBoxesV2/utils/nms_wrapper.py new file mode 100644 index 0000000000000000000000000000000000000000..d529875fac67e070ea865a1ba0cc3d248847827f --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/FaceBoxesV2/utils/nms_wrapper.py @@ -0,0 +1,15 @@ +# -------------------------------------------------------- +# Fast R-CNN +# Copyright (c) 2015 Microsoft +# Licensed under The MIT License [see LICENSE for details] +# Written by Ross Girshick +# -------------------------------------------------------- + +from .nms.cpu_nms import cpu_nms, cpu_soft_nms + +def nms(dets, thresh): + """Dispatch to either CPU or GPU NMS implementations.""" + + if dets.shape[0] == 0: + return [] + return cpu_nms(dets, thresh) diff --git a/src/pixel3dmm/preprocessing/PIPNet/FaceBoxesV2/utils/prior_box.py b/src/pixel3dmm/preprocessing/PIPNet/FaceBoxesV2/utils/prior_box.py new file mode 100644 index 0000000000000000000000000000000000000000..e5536670afe139de420bc16bd88238fd2a90735b --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/FaceBoxesV2/utils/prior_box.py @@ -0,0 +1,43 @@ +import torch +from itertools import product as product +import numpy as np +from math import ceil + + +class PriorBox(object): + def __init__(self, cfg, image_size=None, phase='train'): + super(PriorBox, self).__init__() + #self.aspect_ratios = cfg['aspect_ratios'] + self.min_sizes = cfg['min_sizes'] + self.steps = cfg['steps'] + self.clip = cfg['clip'] + self.image_size = image_size + self.feature_maps = [[ceil(self.image_size[0]/step), ceil(self.image_size[1]/step)] for step in self.steps] + + def forward(self): + anchors = [] + for k, f in enumerate(self.feature_maps): + min_sizes = self.min_sizes[k] + for i, j in product(range(f[0]), range(f[1])): + for min_size in min_sizes: + s_kx = min_size / self.image_size[1] + s_ky = min_size / self.image_size[0] + if min_size == 32: + dense_cx = [x*self.steps[k]/self.image_size[1] for x in [j+0, j+0.25, j+0.5, j+0.75]] + dense_cy = [y*self.steps[k]/self.image_size[0] for y in [i+0, i+0.25, i+0.5, i+0.75]] + for cy, cx in product(dense_cy, dense_cx): + anchors += [cx, cy, s_kx, s_ky] + elif min_size == 64: + dense_cx = [x*self.steps[k]/self.image_size[1] for x in [j+0, j+0.5]] + dense_cy = [y*self.steps[k]/self.image_size[0] for y in [i+0, i+0.5]] + for cy, cx in product(dense_cy, dense_cx): + anchors += [cx, cy, s_kx, s_ky] + else: + cx = (j + 0.5) * self.steps[k] / self.image_size[1] + cy = (i + 0.5) * self.steps[k] / self.image_size[0] + anchors += [cx, cy, s_kx, s_ky] + # back to torch land + output = torch.Tensor(anchors).view(-1, 4) + if self.clip: + output.clamp_(max=1, min=0) + return output diff --git a/src/pixel3dmm/preprocessing/PIPNet/FaceBoxesV2/utils/timer.py b/src/pixel3dmm/preprocessing/PIPNet/FaceBoxesV2/utils/timer.py new file mode 100644 index 0000000000000000000000000000000000000000..e4b3b8098a5ad41f8d18d42b6b2fedb694aa5508 --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/FaceBoxesV2/utils/timer.py @@ -0,0 +1,40 @@ +# -------------------------------------------------------- +# Fast R-CNN +# Copyright (c) 2015 Microsoft +# Licensed under The MIT License [see LICENSE for details] +# Written by Ross Girshick +# -------------------------------------------------------- + +import time + + +class Timer(object): + """A simple timer.""" + def __init__(self): + self.total_time = 0. + self.calls = 0 + self.start_time = 0. + self.diff = 0. + self.average_time = 0. + + def tic(self): + # using time.time instead of time.clock because time time.clock + # does not normalize for multithreading + self.start_time = time.time() + + def toc(self, average=True): + self.diff = time.time() - self.start_time + self.total_time += self.diff + self.calls += 1 + self.average_time = self.total_time / self.calls + if average: + return self.average_time + else: + return self.diff + + def clear(self): + self.total_time = 0. + self.calls = 0 + self.start_time = 0. + self.diff = 0. + self.average_time = 0. diff --git a/src/pixel3dmm/preprocessing/PIPNet/FaceBoxesV2/weights/FaceBoxesV2.pth b/src/pixel3dmm/preprocessing/PIPNet/FaceBoxesV2/weights/FaceBoxesV2.pth new file mode 100644 index 0000000000000000000000000000000000000000..47a5cadd52bf7a6a32a4071ea2cd24270c5f33e9 --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/FaceBoxesV2/weights/FaceBoxesV2.pth @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:aae07fec4b62ac655508c06336662538803407852312ca5009fd93fb487d8cd7 +size 4153573 diff --git a/src/pixel3dmm/preprocessing/PIPNet/LICENSE b/src/pixel3dmm/preprocessing/PIPNet/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..643b2d0cf63445ede21be6a0f9dfd37e23c75388 --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 Haibo Jin + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/src/pixel3dmm/preprocessing/PIPNet/README.md b/src/pixel3dmm/preprocessing/PIPNet/README.md new file mode 100644 index 0000000000000000000000000000000000000000..0c33f74742f3611958e7a8cad684e6832dad26b6 --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/README.md @@ -0,0 +1,161 @@ +# Pixel-in-Pixel Net: Towards Efficient Facial Landmark Detection in the Wild +## Introduction +This is the code of paper [Pixel-in-Pixel Net: Towards Efficient Facial Landmark Detection in the Wild](https://arxiv.org/abs/2003.03771). We propose a novel facial landmark detector, PIPNet, that is **fast**, **accurate**, and **robust**. PIPNet can be trained under two settings: (1) supervised learning; (2) generalizable semi-supervised learning (GSSL). With GSSL, PIPNet has better cross-domain generalization performance by utilizing massive amounts of unlabeled data across domains. + +speed +Figure 1. Comparison to existing methods on speed-accuracy tradeoff, tested on WFLW full test set (closer to bottom-right corner is better).

+ +det_heads +Figure 2. Comparison of different detection heads.
+ +## Installation +1. Install Python3 and PyTorch >= v1.1 +2. Clone this repository. +```Shell +git clone https://github.com/jhb86253817/PIPNet.git +``` +3. Install the dependencies in requirements.txt. +```Shell +pip install -r requirements.txt +``` + +## Demo +1. We use a [modified version](https://github.com/jhb86253817/FaceBoxesV2) of [FaceBoxes](https://github.com/zisianw/FaceBoxes.PyTorch) as the face detector, so go to folder `FaceBoxesV2/utils`, run `sh make.sh` to build for NMS. +2. Back to folder `PIPNet`, create two empty folders `logs` and `snapshots`. For PIPNets, you can download our trained models from [here](https://drive.google.com/drive/folders/17OwDgJUfuc5_ymQ3QruD8pUnh5zHreP2?usp=sharing), and put them under folder `snapshots/DATA_NAME/EXPERIMENT_NAME/`. +3. Edit `run_demo.sh` to choose the config file and input source you want, then run `sh run_demo.sh`. We support image, video, and camera as the input. Some sample predictions can be seen as follows. +* PIPNet-ResNet18 trained on WFLW, with image `images/1.jpg` as the input: +1_out_WFLW_model + +* PIPNet-ResNet18 trained on WFLW, with a snippet from *Shaolin Soccer* as the input: +shaolin_soccer + +* PIPNet-ResNet18 trained on WFLW, with video `videos/002.avi` as the input: +002_out_WFLW_model + +* PIPNet-ResNet18 trained on 300W+CelebA (GSSL), with video `videos/007.avi` as the input: +007_out_300W_CELEBA_model + +## Training + +### Supervised Learning +Datasets: [300W](https://ibug.doc.ic.ac.uk/resources/facial-point-annotations/), [COFW](http://www.vision.caltech.edu/xpburgos/ICCV13/), [WFLW](https://wywu.github.io/projects/LAB/WFLW.html), [AFLW](https://www.tugraz.at/institute/icg/research/team-bischof/lrs/downloads/aflw/), [LaPa](https://github.com/JDAI-CV/lapa-dataset) + +1. Download the datasets from official sources, then put them under folder `data`. The folder structure should look like this: +```` +PIPNet +-- FaceBoxesV2 +-- lib +-- experiments +-- logs +-- snapshots +-- data + |-- data_300W + |-- afw + |-- helen + |-- ibug + |-- lfpw + |-- COFW + |-- COFW_train_color.mat + |-- COFW_test_color.mat + |-- WFLW + |-- WFLW_images + |-- WFLW_annotations + |-- AFLW + |-- flickr + |-- AFLWinfo_release.mat + |-- LaPa + |-- train + |-- val + |-- test +```` +2. Go to folder `lib`, preprocess a dataset by running ```python preprocess.py DATA_NAME```. For example, to process 300W: +``` +python preprocess.py data_300W +``` +3. Back to folder `PIPNet`, edit `run_train.sh` to choose the config file you want. Then, train the model by running: +``` +sh run_train.sh +``` + +### Generalizable Semi-supervised Learning +Datasets: +* data_300W_COFW_WFLW: 300W + COFW-68 (unlabeled) + WFLW-68 (unlabeled) +* data_300W_CELEBA: 300W + CelebA (unlabeled) + +1. Download 300W, COFW, and WFLW as in the supervised learning setting. Download annotations of COFW-68 test from [here](https://github.com/golnazghiasi/cofw68-benchmark). For 300W+CelebA, you also need to download the in-the-wild CelebA images from [here](http://mmlab.ie.cuhk.edu.hk/projects/CelebA.html), and the [face bounding boxes](https://drive.google.com/drive/folders/17OwDgJUfuc5_ymQ3QruD8pUnh5zHreP2?usp=sharing) detected by us. The folder structure should look like this: +```` +PIPNet +-- FaceBoxesV2 +-- lib +-- experiments +-- logs +-- snapshots +-- data + |-- data_300W + |-- afw + |-- helen + |-- ibug + |-- lfpw + |-- COFW + |-- COFW_train_color.mat + |-- COFW_test_color.mat + |-- WFLW + |-- WFLW_images + |-- WFLW_annotations + |-- data_300W_COFW_WFLW + |-- cofw68_test_annotations + |-- cofw68_test_bboxes.mat + |-- CELEBA + |-- img_celeba + |-- celeba_bboxes.txt + |-- data_300W_CELEBA + |-- cofw68_test_annotations + |-- cofw68_test_bboxes.mat +```` +2. Go to folder `lib`, preprocess a dataset by running ```python preprocess_gssl.py DATA_NAME```. + To process data_300W_COFW_WFLW, run + ``` + python preprocess_gssl.py data_300W_COFW_WFLW + ``` + To process data_300W_CELEBA, run + ``` + python preprocess_gssl.py CELEBA + ``` + and + ``` + python preprocess_gssl.py data_300W_CELEBA + ``` +3. Back to folder `PIPNet`, edit `run_train.sh` to choose the config file you want. Then, train the model by running: +``` +sh run_train.sh +``` + +## Evaluation +1. Edit `run_test.sh` to choose the config file you want. Then, test the model by running: +``` +sh run_test.sh +``` + +## Community +* [lite.ai.toolkit](https://github.com/DefTruth/lite.ai.toolkit): Provide [MNN C++](https://github.com/DefTruth/lite.ai.toolkit/blob/main/lite/mnn/cv/mnn_pipnet98.cpp), [NCNN C++](https://github.com/DefTruth/lite.ai.toolkit/blob/main/lite/ncnn/cv/ncnn_pipnet98.cpp), [TNN C++](https://github.com/DefTruth/lite.ai.toolkit/blob/main/lite/tnn/cv/tnn_pipnet98.cpp) and [ONNXRuntime C++](https://github.com/DefTruth/lite.ai.toolkit/blob/main/lite/ort/cv/pipnet98.cpp) version of PIPNet. +* [torchlm](https://github.com/DefTruth/torchlm): Provide a PyTorch re-implement of PIPNet with ONNX Export, can install with pip. + +## Citation +```` +@article{JLS21, + title={Pixel-in-Pixel Net: Towards Efficient Facial Landmark Detection in the Wild}, + author={Haibo Jin and Shengcai Liao and Ling Shao}, + journal={International Journal of Computer Vision}, + publisher={Springer Science and Business Media LLC}, + ISSN={1573-1405}, + url={http://dx.doi.org/10.1007/s11263-021-01521-4}, + DOI={10.1007/s11263-021-01521-4}, + year={2021}, + month={Sep} +} +```` + +## Acknowledgement +We thank the following great works: +* [human-pose-estimation.pytorch](https://github.com/microsoft/human-pose-estimation.pytorch) +* [HRNet-Facial-Landmark-Detection](https://github.com/HRNet/HRNet-Facial-Landmark-Detection) diff --git a/src/pixel3dmm/preprocessing/PIPNet/data/AFLW/meanface.txt b/src/pixel3dmm/preprocessing/PIPNet/data/AFLW/meanface.txt new file mode 100644 index 0000000000000000000000000000000000000000..bef675f675f3e3fa29b162ccfef719dde3b033d5 --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/data/AFLW/meanface.txt @@ -0,0 +1 @@ +0.2520387312821065 0.22865125462128985 0.3408803567692688 0.20925181543701546 0.4309508960717316 0.2283849860162939 0.5633760922371124 0.22521654882766065 0.6577613879095671 0.20069412873970166 0.7494128254628353 0.21751422299660703 0.29339732989966233 0.3158076280737991 0.35848465881558284 0.31153167254355496 0.4198949142395704 0.3191909005986353 0.5819813735705355 0.3162318018434714 0.6454416413255778 0.3059331736033804 0.7111115695408189 0.3078931922969426 0.403567585150483 0.5334870420541395 0.4963015936690089 0.5077035362328098 0.5978205777158326 0.5306395249630969 0.3843748447832597 0.692393547770251 0.5031717401440071 0.7044968389562082 0.6259229830129976 0.6873232480290753 0.5098649887365728 0.9322687215070251 \ No newline at end of file diff --git a/src/pixel3dmm/preprocessing/PIPNet/data/COFW/meanface.txt b/src/pixel3dmm/preprocessing/PIPNet/data/COFW/meanface.txt new file mode 100644 index 0000000000000000000000000000000000000000..fe20714b576a9d85d67f82e227948824bc87c10e --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/data/COFW/meanface.txt @@ -0,0 +1 @@ +0.09344842654783869 0.15406877348086334 0.9323471108969382 0.1401049083310136 0.3997603796160685 0.15490567536186625 0.6237975504925628 0.1506668314387944 0.23501464872024747 0.10114569063499716 0.23657257629382072 0.14273999515886135 0.7844072096492979 0.09255827995641538 0.7886209940367209 0.13342958152383141 0.1702434206343547 0.2398254983581864 0.8642419047335136 0.23100885422325879 0.3779708093247684 0.24535590755251818 0.6567150531285483 0.24095057462080818 0.27793516230173154 0.20089460792973152 0.27633082606975745 0.26563845764538907 0.7570995084865105 0.19361548230508704 0.7635889825823677 0.2583984281705357 0.279266369046543 0.2302294117140321 0.7575495684331521 0.22349084426991003 0.38280645505717537 0.4925663990251028 0.6614317708106371 0.488658165265478 0.5189481268032609 0.4708399901570863 0.5225011032592264 0.539587476025657 0.32470035972074895 0.6648848905553355 0.7295419104987368 0.6593261745721221 0.5229449400615745 0.6265737161799486 0.5255912932309097 0.662324568779506 0.527155537232314 0.6983437257351308 0.5293851188286474 0.7515984253648098 0.5353511486450372 0.9458980717418055 \ No newline at end of file diff --git a/src/pixel3dmm/preprocessing/PIPNet/data/LaPa/.gitkeep b/src/pixel3dmm/preprocessing/PIPNet/data/LaPa/.gitkeep new file mode 100644 index 0000000000000000000000000000000000000000..8b137891791fe96927ad78e64b0aad7bded08bdc --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/data/LaPa/.gitkeep @@ -0,0 +1 @@ + diff --git a/src/pixel3dmm/preprocessing/PIPNet/data/LaPa/meanface.txt b/src/pixel3dmm/preprocessing/PIPNet/data/LaPa/meanface.txt new file mode 100644 index 0000000000000000000000000000000000000000..e691eb17ff30aaeae092940c039a4e18d025f75b --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/data/LaPa/meanface.txt @@ -0,0 +1 @@ +0.10530529000640856 0.21052138159149678 0.10346312076901258 0.2662726745714962 0.10217057333436477 0.32114553251993 0.10258422967397157 0.3760084841238558 0.10588192925607048 0.43109292350944967 0.11302386489664121 0.48621962292292703 0.12477205483336429 0.5414599600116855 0.14102743093352899 0.5955209925827968 0.1632719376567127 0.6466804471091275 0.1910599572550061 0.6946358073642266 0.22424599203957288 0.7390195138784417 0.26211514659329466 0.7794879334583175 0.30367025470450965 0.816012569068714 0.34766046281821733 0.850882786816955 0.3953177767293077 0.8804344608872823 0.4487173381588481 0.9005324177983531 0.5100338298158771 0.9070606418366286 0.5712716753687324 0.8983023653050762 0.6241767271581117 0.8763255848513388 0.6708553134700462 0.8450314801371582 0.7136791932198043 0.8087428383307392 0.7541248098100394 0.770812423091051 0.7905250092801029 0.7290677819826883 0.8219967896955132 0.6833908711520263 0.8479404285884548 0.6343345325292671 0.8681874714540011 0.5821458724936195 0.8824175512748297 0.5274128341115184 0.8920174566936556 0.471437455135775 0.8971160168752679 0.4160147078312381 0.8984258108227322 0.36087818978988345 0.8967746520532384 0.30593953132086726 0.8932401684842185 0.2510184159487108 0.8886303936473524 0.19551555989951783 0.19080691089284976 0.17688226731422843 0.23703774601603758 0.13493690623969778 0.2994011235863562 0.12377371262269846 0.36442443812566794 0.1334156515414588 0.4206974462185849 0.15576893350782198 0.41538261991372216 0.18521387259748126 0.3578316077351047 0.17023713987254602 0.29926531681027724 0.1647584864314877 0.24376522496647846 0.16810390551348878 0.5679133390211937 0.15195666209513556 0.6234099235893878 0.1271788852505303 0.68836638284106 0.11502664609938558 0.7517148773395326 0.12397312576453914 0.8003186915478934 0.164661447404218 0.7461363917064738 0.1568570738057735 0.6902508869620426 0.15554025558991308 0.6316039289402061 0.16367758210908348 0.5745440209110346 0.1811702067173649 0.49635250721509805 0.23144344163945024 0.49776198821318396 0.30385803807833195 0.4991020889198753 0.3763030566695691 0.5004707578148508 0.44878030556582904 0.4382571815965156 0.26036872039531744 0.4131953004760858 0.40603519461106263 0.3881451065329989 0.471487759479652 0.4214523196091174 0.4971740638884675 0.4594663412069896 0.5065521839440414 0.5024819453368541 0.5179592883408858 0.5451122880635956 0.5043415278881611 0.5824119573939653 0.49388732408483804 0.6146171697397168 0.4665300926927993 0.5867368809383912 0.4020947987203815 0.5559811904454144 0.2576938678584477 0.2531314405041606 0.252719744146067 0.2853408047822641 0.23135591608026138 0.3258440646145571 0.2229636137476243 0.36658273457129226 0.23242953378754497 0.39829919754027615 0.25834900060080085 0.3626412317888289 0.2666381129849394 0.3234940413093194 0.2711006990366015 0.28546434003392307 0.2657038110483953 0.3259425084155361 0.24452859898165027 0.5962922590838732 0.25440679232096053 0.6270469522613061 0.22729509647219456 0.6674316022765016 0.21638754266341426 0.7081748622553374 0.2234007704800147 0.7408849029025555 0.2436734338635688 0.7093069690599688 0.25797173644014293 0.6715889798302642 0.2648049864304249 0.6322345940201518 0.2615942138918854 0.6686493178688638 0.2381846027535789 0.35073794231894434 0.6264851851541189 0.40579598288417945 0.6042815280826724 0.4679809697527211 0.5906101560830487 0.5025555655287725 0.5975087613065031 0.5368258366138642 0.5893932526555288 0.5996684030376771 0.600799080968945 0.6565447626583086 0.62072352127923 0.6189097233474866 0.6655963252276111 0.5709337146008885 0.698894831978254 0.5048366317585606 0.713019897126309 0.4380289691984558 0.7014141971577583 0.38932170182206044 0.66978410405136 0.3739501137612586 0.6290623209341267 0.4264911280653227 0.6243811766819207 0.5031035985986991 0.6271183438753134 0.579761780602956 0.6215714757222834 0.6332962211716711 0.6243463702139462 0.5831229602285424 0.648154374088437 0.5038091891864612 0.6612169580713776 0.42442126476527914 0.6512543499529478 0.32595499952970813 0.2445329023949036 0.6686401132878527 0.2381823527614187 \ No newline at end of file diff --git a/src/pixel3dmm/preprocessing/PIPNet/data/WFLW/meanface.txt b/src/pixel3dmm/preprocessing/PIPNet/data/WFLW/meanface.txt new file mode 100644 index 0000000000000000000000000000000000000000..3e3b5961cc7aad9f18497945bbed78fa0611fdfe --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/data/WFLW/meanface.txt @@ -0,0 +1 @@ +0.07960419395480703 0.3921576875344978 0.08315055593117261 0.43509551571809146 0.08675705281580391 0.47810288286566444 0.09141892980469117 0.5210356946467262 0.09839925903528965 0.5637522280060038 0.10871037524559955 0.6060410614977951 0.12314562992759207 0.6475338700558225 0.14242389255404694 0.6877152027028081 0.16706295456951875 0.7259564546408682 0.19693946055282413 0.761730578566735 0.23131827931527224 0.7948205670466106 0.2691730934906831 0.825332081636482 0.3099415030959131 0.853325959406618 0.3535202097901413 0.8782538906229107 0.40089023799272033 0.8984102434399625 0.4529251732310723 0.9112191359814178 0.5078640056794708 0.9146712690731943 0.5616519666079889 0.9094327772020283 0.6119216923689698 0.8950540037623425 0.6574617882337107 0.8738084866764846 0.6994820494908942 0.8482660530943744 0.7388135339780575 0.8198750461527688 0.775158750479601 0.788989141243473 0.8078785221990765 0.7555462713420953 0.8361052138935441 0.7195542055115057 0.8592123871172533 0.6812759034843933 0.8771159986952748 0.6412243940605555 0.8902481006481506 0.5999743595282084 0.8992952868651163 0.5580032282594118 0.9050110573289222 0.5156548913779377 0.908338439928252 0.4731336721500472 0.9104896075281127 0.4305382486815422 0.9124796341441906 0.38798192678294363 0.18465941635742913 0.35063191749632183 0.24110421889338157 0.31190394310826886 0.3003235400132397 0.30828189837331976 0.3603094923651325 0.3135606490643205 0.4171060234289877 0.32433417646045615 0.416842139562573 0.3526729965541497 0.36011177591813404 0.3439660526998693 0.3000863121140166 0.33890077494044946 0.24116055928407834 0.34065620413845005 0.5709736930161899 0.321407825750195 0.6305694459247149 0.30972642336729495 0.6895161625920927 0.3036453838462943 0.7488591859761683 0.3069143844433495 0.8030471337135181 0.3435156012309415 0.7485083446528741 0.3348759588212388 0.6893025057931884 0.33403402013776456 0.6304822892126991 0.34038458762875695 0.5710009285609654 0.34988479902594455 0.4954171902473609 0.40202330022004634 0.49604903449415433 0.4592869389138444 0.49644391662771625 0.5162862508677217 0.4981161256057368 0.5703284628419502 0.40749001573145566 0.5983629921847019 0.4537396729649631 0.6057169923583451 0.5007345777827058 0.6116695615531077 0.5448481727980428 0.6044131443745976 0.5882140504891681 0.5961738788380111 0.24303324896316683 0.40721003719912746 0.27771706732644313 0.3907171413930685 0.31847706697401107 0.38417234007271117 0.3621792860449715 0.3900847721320633 0.3965299162804086 0.41071434661355205 0.3586805562211872 0.4203724421417311 0.31847860588240934 0.4237674602252073 0.2789458001651631 0.41942757306509065 0.5938514626567266 0.4090628827047304 0.6303565516542536 0.3864501652756091 0.6774844732813035 0.3809319896905685 0.7150854850525555 0.3875173254527522 0.747519807465081 0.4025187328459307 0.7155172856447009 0.4145958479293519 0.680051949453018 0.420041513473271 0.6359056750107122 0.41803782782566573 0.33916483987223056 0.6968581311227738 0.40008790639758807 0.6758101185779204 0.47181947887764153 0.6678850445191217 0.5025394453374782 0.6682917934792593 0.5337748367911458 0.6671949030019636 0.6015915330083903 0.6742535357237751 0.6587068892667173 0.6932163943648724 0.6192795131720007 0.7283129162844936 0.5665923267827963 0.7550248076404299 0.5031303335863617 0.7648348885181623 0.4371030429958871 0.7572539606688756 0.3814909500115824 0.7320595346122074 0.35129809553480984 0.6986839074746692 0.4247987356100664 0.69127609583798 0.5027677238758598 0.6911145821740593 0.576997542122097 0.6896269708051024 0.6471352843446794 0.6948977432227927 0.5799932528781817 0.7185288017567538 0.5024914756021335 0.7285408331555782 0.4218115644247556 0.7209126133193829 0.3219750495122499 0.40376441481225156 0.6751136343101699 0.40023415216110797 \ No newline at end of file diff --git a/src/pixel3dmm/preprocessing/PIPNet/data/data_300W/meanface.txt b/src/pixel3dmm/preprocessing/PIPNet/data/data_300W/meanface.txt new file mode 100644 index 0000000000000000000000000000000000000000..1a42843bcf006910f4ccd8c69082aa389aba9d63 --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/data/data_300W/meanface.txt @@ -0,0 +1 @@ +0.05558998895410058 0.23848280098218655 0.05894856684324656 0.3590187767402909 0.0736574254414371 0.4792196439871159 0.09980016420365162 0.5959029676167197 0.14678670154995865 0.7035615597409001 0.21847188218752928 0.7971705893013413 0.30554692814599393 0.8750572978073209 0.4018434142644611 0.9365018059444535 0.5100536090382116 0.9521295666029498 0.6162039414413925 0.9309467340899419 0.7094522484942942 0.8669275031738761 0.7940993502957612 0.7879369615524398 0.8627063649669019 0.6933756633633967 0.9072386130534111 0.5836975017700834 0.9298874997796132 0.4657004930314701 0.9405202670724796 0.346063993805527 0.9425419553088846 0.22558131891345742 0.13304298285530403 0.14853071838028062 0.18873587368440375 0.09596491613770254 0.2673231915839219 0.08084218279128136 0.34878638553224905 0.09253591849498964 0.4226713753717798 0.12466063383809506 0.5618513152452376 0.11839668911898667 0.6394952560845826 0.08480191391770678 0.7204375851516752 0.07249669092117161 0.7988615904537885 0.08766933146893043 0.8534884939460948 0.1380096813348583 0.49610677423740546 0.21516740699375395 0.49709661403980665 0.2928875699060973 0.4982292618461611 0.3699985379939941 0.49982965173254235 0.4494119144493957 0.406772397599095 0.5032397294041786 0.45231994786363067 0.5197953144002292 0.49969685987914064 0.5332489262413073 0.5470074224053442 0.518413595827126 0.5892261151542287 0.5023530079850803 0.22414578747180394 0.22835847349949062 0.27262947128194215 0.19915251892241678 0.3306759252861797 0.20026034220607236 0.38044435864341913 0.23839196034290633 0.32884072789429913 0.24902443794896897 0.2707409300714473 0.24950886025380967 0.6086826011068529 0.23465048639345917 0.660397116846103 0.1937087938594717 0.7177815187666494 0.19317079039835858 0.7652328176062365 0.22088822845258235 0.722727677909097 0.24195514178450958 0.6658378927310327 0.2441554205021945 0.32894370935769124 0.6496589505331646 0.39347179739100613 0.6216899667490776 0.4571976492475472 0.60794251109236 0.4990484623797022 0.6190124015360254 0.5465555522325872 0.6071477960565326 0.6116127327356168 0.6205387097430033 0.6742318496058836 0.6437466364395467 0.6144773141699744 0.7077526646009754 0.5526442055374252 0.7363350735898412 0.5018120662554302 0.7424476622366345 0.4554458875556401 0.7382303858617719 0.3923750731597415 0.7118887028663435 0.35530766372404593 0.6524479416354049 0.457111071610868 0.6467108367268608 0.49974082228815025 0.6508406774477011 0.5477027224368399 0.6451242819422733 0.6478392760505715 0.647852382880368 0.5488474760115958 0.6779061893042735 0.5001073351044452 0.6845280260362221 0.4564831746654594 0.6799300301441035 \ No newline at end of file diff --git a/src/pixel3dmm/preprocessing/PIPNet/data/data_300W_CELEBA/meanface.txt b/src/pixel3dmm/preprocessing/PIPNet/data/data_300W_CELEBA/meanface.txt new file mode 100644 index 0000000000000000000000000000000000000000..4dbf712e137abd2f2d7830eb1bcb83d08dc930c1 --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/data/data_300W_CELEBA/meanface.txt @@ -0,0 +1 @@ +0.12232440867025321 0.27962262481578615 0.1251741407890332 0.3822010530676433 0.137662109340586 0.484494826453967 0.15985504610693665 0.58379829864377 0.19972896480368596 0.675412639432648 0.2605579295545752 0.7550617213398176 0.33444765501965257 0.8213252459974902 0.4161697591327947 0.8735651108778814 0.5080087528764403 0.8868348215817158 0.5980992802776127 0.8688135857462302 0.6772596499687593 0.8143677086997837 0.7491211575789162 0.7471655230329272 0.8073766483264004 0.6667089668374325 0.8451875673796937 0.5733850777608563 0.864415472750196 0.4729803701239298 0.8734385478428245 0.3711768994830678 0.8751531101099292 0.268656781257751 0.18796548820344416 0.2030530402265248 0.23523864911193537 0.15830034643403879 0.3019430356817159 0.14541898323850677 0.37108573686879104 0.15536530774545093 0.4337977392176639 0.18270698888639544 0.5519376178836386 0.17738031243713215 0.6178610694743013 0.14878977678287292 0.6865865025820168 0.13831990409096662 0.7531734388993169 0.1512429054491697 0.7995673014066828 0.1941022399185316 0.49613115054318335 0.2597672071212774 0.4969637683612954 0.3259085874268994 0.49791780500402 0.39152877663527796 0.49926918905146594 0.4591065683857296 0.4202846654961633 0.5049368052770046 0.4589485206700924 0.5190228657842618 0.49916996608981484 0.5304667753993072 0.5393424804128895 0.5178452264471334 0.575195669558906 0.5041819599878575 0.26527901675348586 0.27098957028846976 0.3064399715133211 0.24611940114541314 0.3557195490030035 0.24706273924128783 0.39798274421817326 0.2795361944817882 0.35416233167951755 0.28858943241231877 0.3048346296119043 0.28900292977320297 0.5917141352695678 0.2763518687602816 0.6356260268180847 0.2414897723496627 0.6843481684971716 0.24103035776326823 0.7246470986193275 0.26462826587645844 0.6885499499583031 0.2825693401736116 0.6402432833345117 0.2844445142656967 0.3542788870635578 0.6295669131323691 0.4090264228452472 0.6057706295562828 0.4631091980648265 0.5940616118908922 0.49863392623478087 0.6034872665752211 0.5389612978421857 0.5933843819273095 0.5941962379203847 0.6047869787643673 0.6473762083732608 0.6245291762913125 0.5966343734828656 0.67897568285239 0.5441373367855241 0.7033053722799186 0.500984722244293 0.708509427837014 0.4616264195190659 0.7049230677252907 0.4080980619951271 0.6825102595145595 0.3766575821628222 0.6319366801368325 0.46303659510988915 0.6270534512838973 0.4992240769447232 0.6305695809640286 0.5399375315807448 0.6257030961252895 0.6249688623037122 0.6280212667827051 0.5409104430529676 0.6535813164521486 0.49953581963561644 0.6592166737899897 0.4625043556133079 0.6553049004525271 \ No newline at end of file diff --git a/src/pixel3dmm/preprocessing/PIPNet/data/data_300W_COFW_WFLW/meanface.txt b/src/pixel3dmm/preprocessing/PIPNet/data/data_300W_COFW_WFLW/meanface.txt new file mode 100644 index 0000000000000000000000000000000000000000..4dbf712e137abd2f2d7830eb1bcb83d08dc930c1 --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/data/data_300W_COFW_WFLW/meanface.txt @@ -0,0 +1 @@ +0.12232440867025321 0.27962262481578615 0.1251741407890332 0.3822010530676433 0.137662109340586 0.484494826453967 0.15985504610693665 0.58379829864377 0.19972896480368596 0.675412639432648 0.2605579295545752 0.7550617213398176 0.33444765501965257 0.8213252459974902 0.4161697591327947 0.8735651108778814 0.5080087528764403 0.8868348215817158 0.5980992802776127 0.8688135857462302 0.6772596499687593 0.8143677086997837 0.7491211575789162 0.7471655230329272 0.8073766483264004 0.6667089668374325 0.8451875673796937 0.5733850777608563 0.864415472750196 0.4729803701239298 0.8734385478428245 0.3711768994830678 0.8751531101099292 0.268656781257751 0.18796548820344416 0.2030530402265248 0.23523864911193537 0.15830034643403879 0.3019430356817159 0.14541898323850677 0.37108573686879104 0.15536530774545093 0.4337977392176639 0.18270698888639544 0.5519376178836386 0.17738031243713215 0.6178610694743013 0.14878977678287292 0.6865865025820168 0.13831990409096662 0.7531734388993169 0.1512429054491697 0.7995673014066828 0.1941022399185316 0.49613115054318335 0.2597672071212774 0.4969637683612954 0.3259085874268994 0.49791780500402 0.39152877663527796 0.49926918905146594 0.4591065683857296 0.4202846654961633 0.5049368052770046 0.4589485206700924 0.5190228657842618 0.49916996608981484 0.5304667753993072 0.5393424804128895 0.5178452264471334 0.575195669558906 0.5041819599878575 0.26527901675348586 0.27098957028846976 0.3064399715133211 0.24611940114541314 0.3557195490030035 0.24706273924128783 0.39798274421817326 0.2795361944817882 0.35416233167951755 0.28858943241231877 0.3048346296119043 0.28900292977320297 0.5917141352695678 0.2763518687602816 0.6356260268180847 0.2414897723496627 0.6843481684971716 0.24103035776326823 0.7246470986193275 0.26462826587645844 0.6885499499583031 0.2825693401736116 0.6402432833345117 0.2844445142656967 0.3542788870635578 0.6295669131323691 0.4090264228452472 0.6057706295562828 0.4631091980648265 0.5940616118908922 0.49863392623478087 0.6034872665752211 0.5389612978421857 0.5933843819273095 0.5941962379203847 0.6047869787643673 0.6473762083732608 0.6245291762913125 0.5966343734828656 0.67897568285239 0.5441373367855241 0.7033053722799186 0.500984722244293 0.708509427837014 0.4616264195190659 0.7049230677252907 0.4080980619951271 0.6825102595145595 0.3766575821628222 0.6319366801368325 0.46303659510988915 0.6270534512838973 0.4992240769447232 0.6305695809640286 0.5399375315807448 0.6257030961252895 0.6249688623037122 0.6280212667827051 0.5409104430529676 0.6535813164521486 0.49953581963561644 0.6592166737899897 0.4625043556133079 0.6553049004525271 \ No newline at end of file diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/AFLW/__pycache__/pip_32_16_60_r101_l2_l1_10_1_nb10.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/AFLW/__pycache__/pip_32_16_60_r101_l2_l1_10_1_nb10.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f43435f972fb5d7f71fd6b5a9b844d215c8583e6 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/AFLW/__pycache__/pip_32_16_60_r101_l2_l1_10_1_nb10.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/AFLW/__pycache__/pip_32_16_60_r152_l2_l1_10_1_nb10.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/AFLW/__pycache__/pip_32_16_60_r152_l2_l1_10_1_nb10.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1eb5c4376125fc95b2d1bc24e3c38182852fa2b8 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/AFLW/__pycache__/pip_32_16_60_r152_l2_l1_10_1_nb10.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/AFLW/__pycache__/pip_32_16_60_r18_focal_l1_01_1.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/AFLW/__pycache__/pip_32_16_60_r18_focal_l1_01_1.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..78a7e784a62434e8eb8e4825fc52418cb445d724 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/AFLW/__pycache__/pip_32_16_60_r18_focal_l1_01_1.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/AFLW/__pycache__/pip_32_16_60_r18_focal_l2_01_1.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/AFLW/__pycache__/pip_32_16_60_r18_focal_l2_01_1.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ac344db2702500e6df3ad618b499a9c954a788e0 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/AFLW/__pycache__/pip_32_16_60_r18_focal_l2_01_1.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/AFLW/__pycache__/pip_32_16_60_r18_l2_l1_10_1.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/AFLW/__pycache__/pip_32_16_60_r18_l2_l1_10_1.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6bd1815a0f817c2c32cc02ce03afd795d5d14650 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/AFLW/__pycache__/pip_32_16_60_r18_l2_l1_10_1.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/AFLW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb10.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/AFLW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb10.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9f6107c81d43737ea8cb513deace31344549be64 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/AFLW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb10.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/AFLW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb2.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/AFLW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb2.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e70cd91979112071249242410bec860901685907 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/AFLW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb2.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/AFLW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb5.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/AFLW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb5.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c30d2e52d9444d94cc30bd1556407408266208a5 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/AFLW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb5.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/AFLW/__pycache__/pip_32_16_60_r18_l2_l2_10_1.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/AFLW/__pycache__/pip_32_16_60_r18_l2_l2_10_1.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c217e82b6847e2beb10b719ecdda6b2fe2ec741a Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/AFLW/__pycache__/pip_32_16_60_r18_l2_l2_10_1.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/AFLW/__pycache__/pip_32_16_60_r50_l2_l1_10_1.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/AFLW/__pycache__/pip_32_16_60_r50_l2_l1_10_1.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..62da5c161fdcd95de2e8a0f4e7333f8bb6937219 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/AFLW/__pycache__/pip_32_16_60_r50_l2_l1_10_1.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/AFLW/__pycache__/pip_32_16_60_r50_l2_l1_10_1_nb10.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/AFLW/__pycache__/pip_32_16_60_r50_l2_l1_10_1_nb10.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f40509d4cc8151656db78cbc3d149bf17b0bb7e5 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/AFLW/__pycache__/pip_32_16_60_r50_l2_l1_10_1_nb10.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/AFLW/__pycache__/pip_32_16_60_r50_l2_l1_10_1_nb2.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/AFLW/__pycache__/pip_32_16_60_r50_l2_l1_10_1_nb2.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..15812d7c8ccda49b9917564aa00999c3b8fd1e91 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/AFLW/__pycache__/pip_32_16_60_r50_l2_l1_10_1_nb2.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/AFLW/__pycache__/pip_32_16_60_r50_l2_l1_10_1_nb5.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/AFLW/__pycache__/pip_32_16_60_r50_l2_l1_10_1_nb5.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..129ba9db8fbedd1170a320174a1b6fced5ba00d6 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/AFLW/__pycache__/pip_32_16_60_r50_l2_l1_10_1_nb5.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/AFLW/pip_32_16_60_r101_l2_l1_10_1_nb10.py b/src/pixel3dmm/preprocessing/PIPNet/experiments/AFLW/pip_32_16_60_r101_l2_l1_10_1_nb10.py new file mode 100644 index 0000000000000000000000000000000000000000..ee7edfd2ecb8368c3709c0e49fce23b7af884ae1 --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/experiments/AFLW/pip_32_16_60_r101_l2_l1_10_1_nb10.py @@ -0,0 +1,21 @@ + +class Config(): + def __init__(self): + self.det_head = 'pip' + self.net_stride = 32 + self.batch_size = 16 + self.init_lr = 0.0001 + self.num_epochs = 60 + self.decay_steps = [30, 50] + self.input_size = 256 + self.backbone = 'resnet101' + self.pretrained = True + self.criterion_cls = 'l2' + self.criterion_reg = 'l1' + self.cls_loss_weight = 10 + self.reg_loss_weight = 1 + self.num_lms = 19 + self.save_interval = self.num_epochs + self.num_nb = 10 + self.use_gpu = True + self.gpu_id = 4 diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/AFLW/pip_32_16_60_r18_l2_l1_10_1_nb10.py b/src/pixel3dmm/preprocessing/PIPNet/experiments/AFLW/pip_32_16_60_r18_l2_l1_10_1_nb10.py new file mode 100644 index 0000000000000000000000000000000000000000..1ed376e11dfe211b4fd6a8bdb755a2a98559675e --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/experiments/AFLW/pip_32_16_60_r18_l2_l1_10_1_nb10.py @@ -0,0 +1,21 @@ + +class Config(): + def __init__(self): + self.det_head = 'pip' + self.net_stride = 32 + self.batch_size = 16 + self.init_lr = 0.0001 + self.num_epochs = 60 + self.decay_steps = [30, 50] + self.input_size = 256 + self.backbone = 'resnet18' + self.pretrained = True + self.criterion_cls = 'l2' + self.criterion_reg = 'l1' + self.cls_loss_weight = 10 + self.reg_loss_weight = 1 + self.num_lms = 19 + self.save_interval = self.num_epochs + self.num_nb = 10 + self.use_gpu = True + self.gpu_id = 3 diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/AFLW/pip_32_16_60_r50_l2_l1_10_1_nb10.py b/src/pixel3dmm/preprocessing/PIPNet/experiments/AFLW/pip_32_16_60_r50_l2_l1_10_1_nb10.py new file mode 100644 index 0000000000000000000000000000000000000000..10e1faa20704d9b5b4639586afd50d3467376de2 --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/experiments/AFLW/pip_32_16_60_r50_l2_l1_10_1_nb10.py @@ -0,0 +1,21 @@ + +class Config(): + def __init__(self): + self.det_head = 'pip' + self.net_stride = 32 + self.batch_size = 16 + self.init_lr = 0.0001 + self.num_epochs = 60 + self.decay_steps = [30, 50] + self.input_size = 256 + self.backbone = 'resnet50' + self.pretrained = True + self.criterion_cls = 'l2' + self.criterion_reg = 'l1' + self.cls_loss_weight = 10 + self.reg_loss_weight = 1 + self.num_lms = 19 + self.save_interval = self.num_epochs + self.num_nb = 10 + self.use_gpu = True + self.gpu_id = 2 diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/COFW/__pycache__/pip_32_16_60_r101_l2_l1_10_1_nb10.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/COFW/__pycache__/pip_32_16_60_r101_l2_l1_10_1_nb10.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d571b352b9ca9f9eb3e55c7c7c074d2ac2cd794e Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/COFW/__pycache__/pip_32_16_60_r101_l2_l1_10_1_nb10.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/COFW/__pycache__/pip_32_16_60_r152_l2_l1_10_1_nb10.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/COFW/__pycache__/pip_32_16_60_r152_l2_l1_10_1_nb10.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3a2f0010a301ede7a72a992f30ad7474ef0e5641 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/COFW/__pycache__/pip_32_16_60_r152_l2_l1_10_1_nb10.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/COFW/__pycache__/pip_32_16_60_r18_focal_l1_01_1.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/COFW/__pycache__/pip_32_16_60_r18_focal_l1_01_1.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d44c89c19c11eb8b1eb6c0e05cbe76b643a2c5be Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/COFW/__pycache__/pip_32_16_60_r18_focal_l1_01_1.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/COFW/__pycache__/pip_32_16_60_r18_focal_l2_01_1.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/COFW/__pycache__/pip_32_16_60_r18_focal_l2_01_1.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d0d2fa2e19c21d20aada953076fa8c75423fb73e Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/COFW/__pycache__/pip_32_16_60_r18_focal_l2_01_1.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/COFW/__pycache__/pip_32_16_60_r18_l2_l1_10_1.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/COFW/__pycache__/pip_32_16_60_r18_l2_l1_10_1.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b691b126e6bcb6b69758456016ceccb29a8fbd35 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/COFW/__pycache__/pip_32_16_60_r18_l2_l1_10_1.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/COFW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb10.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/COFW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb10.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..43c06d7a76a61d3690525864564d92d4ebe76821 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/COFW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb10.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/COFW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb2.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/COFW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb2.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8a1bea8a6ffa4e0b591a4cd19855b83363ffcf5c Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/COFW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb2.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/COFW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb5.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/COFW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb5.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..41c73f4a0f35d2300a3d0ef43459dba2edb223ad Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/COFW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb5.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/COFW/__pycache__/pip_32_16_60_r18_l2_l2_10_1.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/COFW/__pycache__/pip_32_16_60_r18_l2_l2_10_1.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5571e2859e0306430af73cfc06729dbf31c367a1 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/COFW/__pycache__/pip_32_16_60_r18_l2_l2_10_1.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/COFW/__pycache__/pip_32_16_60_r50_l2_l1_10_1.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/COFW/__pycache__/pip_32_16_60_r50_l2_l1_10_1.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e7e6e61236a30d528e3e631e8f8d31a3ac22dadb Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/COFW/__pycache__/pip_32_16_60_r50_l2_l1_10_1.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/COFW/__pycache__/pip_32_16_60_r50_l2_l1_10_1_nb10.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/COFW/__pycache__/pip_32_16_60_r50_l2_l1_10_1_nb10.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8163eaa1e2ac270e4353adad74c52db90503539e Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/COFW/__pycache__/pip_32_16_60_r50_l2_l1_10_1_nb10.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/COFW/__pycache__/pip_32_16_60_r50_l2_l1_10_1_nb2.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/COFW/__pycache__/pip_32_16_60_r50_l2_l1_10_1_nb2.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..04623269bbcc226d8b0ea68710d09bc64a5fc5ba Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/COFW/__pycache__/pip_32_16_60_r50_l2_l1_10_1_nb2.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/COFW/__pycache__/pip_32_16_60_r50_l2_l1_10_1_nb5.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/COFW/__pycache__/pip_32_16_60_r50_l2_l1_10_1_nb5.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e1a2200a3d1d6f9ce6ef0b19e826e5b93e8585f7 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/COFW/__pycache__/pip_32_16_60_r50_l2_l1_10_1_nb5.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/COFW/pip_32_16_60_r101_l2_l1_10_1_nb10.py b/src/pixel3dmm/preprocessing/PIPNet/experiments/COFW/pip_32_16_60_r101_l2_l1_10_1_nb10.py new file mode 100644 index 0000000000000000000000000000000000000000..70e626682abf4ecb1b2f4e78e5f13cfc582c8276 --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/experiments/COFW/pip_32_16_60_r101_l2_l1_10_1_nb10.py @@ -0,0 +1,21 @@ + +class Config(): + def __init__(self): + self.det_head = 'pip' + self.net_stride = 32 + self.batch_size = 16 + self.init_lr = 0.0001 + self.num_epochs = 60 + self.decay_steps = [30, 50] + self.input_size = 256 + self.backbone = 'resnet101' + self.pretrained = True + self.criterion_cls = 'l2' + self.criterion_reg = 'l1' + self.cls_loss_weight = 10 + self.reg_loss_weight = 1 + self.num_lms = 29 + self.save_interval = self.num_epochs + self.num_nb = 10 + self.use_gpu = True + self.gpu_id = 4 diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/COFW/pip_32_16_60_r18_l2_l1_10_1_nb10.py b/src/pixel3dmm/preprocessing/PIPNet/experiments/COFW/pip_32_16_60_r18_l2_l1_10_1_nb10.py new file mode 100644 index 0000000000000000000000000000000000000000..e15f28fadba84f5aeefa5626c1ed22bd11c89891 --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/experiments/COFW/pip_32_16_60_r18_l2_l1_10_1_nb10.py @@ -0,0 +1,21 @@ + +class Config(): + def __init__(self): + self.det_head = 'pip' + self.net_stride = 32 + self.batch_size = 16 + self.init_lr = 0.0001 + self.num_epochs = 60 + self.decay_steps = [30, 50] + self.input_size = 256 + self.backbone = 'resnet18' + self.pretrained = True + self.criterion_cls = 'l2' + self.criterion_reg = 'l1' + self.cls_loss_weight = 10 + self.reg_loss_weight = 1 + self.num_lms = 29 + self.save_interval = self.num_epochs + self.num_nb = 10 + self.use_gpu = True + self.gpu_id = 0 diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/COFW/pip_32_16_60_r50_l2_l1_10_1_nb10.py b/src/pixel3dmm/preprocessing/PIPNet/experiments/COFW/pip_32_16_60_r50_l2_l1_10_1_nb10.py new file mode 100644 index 0000000000000000000000000000000000000000..7f895b59997dc2ba214bf4daf7cdf81946c72d01 --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/experiments/COFW/pip_32_16_60_r50_l2_l1_10_1_nb10.py @@ -0,0 +1,21 @@ + +class Config(): + def __init__(self): + self.det_head = 'pip' + self.net_stride = 32 + self.batch_size = 16 + self.init_lr = 0.0001 + self.num_epochs = 60 + self.decay_steps = [30, 50] + self.input_size = 256 + self.backbone = 'resnet50' + self.pretrained = True + self.criterion_cls = 'l2' + self.criterion_reg = 'l1' + self.cls_loss_weight = 10 + self.reg_loss_weight = 1 + self.num_lms = 29 + self.save_interval = self.num_epochs + self.num_nb = 10 + self.use_gpu = True + self.gpu_id = 2 diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/LaPa/.gitkeep b/src/pixel3dmm/preprocessing/PIPNet/experiments/LaPa/.gitkeep new file mode 100644 index 0000000000000000000000000000000000000000..8b137891791fe96927ad78e64b0aad7bded08bdc --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/experiments/LaPa/.gitkeep @@ -0,0 +1 @@ + diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/LaPa/pip_32_16_60_r101_l2_l1_10_1_nb10.py b/src/pixel3dmm/preprocessing/PIPNet/experiments/LaPa/pip_32_16_60_r101_l2_l1_10_1_nb10.py new file mode 100644 index 0000000000000000000000000000000000000000..905e013b3032b433b30cef01146b39a3e741f420 --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/experiments/LaPa/pip_32_16_60_r101_l2_l1_10_1_nb10.py @@ -0,0 +1,21 @@ + +class Config(): + def __init__(self): + self.det_head = 'pip' + self.net_stride = 32 + self.batch_size = 16 + self.init_lr = 0.0001 + self.num_epochs = 60 + self.decay_steps = [30, 50] + self.input_size = 256 + self.backbone = 'resnet101' + self.pretrained = True + self.criterion_cls = 'l2' + self.criterion_reg = 'l1' + self.cls_loss_weight = 10 + self.reg_loss_weight = 1 + self.num_lms = 106 + self.save_interval = self.num_epochs + self.num_nb = 10 + self.use_gpu = True + self.gpu_id = 1 diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/LaPa/pip_32_16_60_r18_l2_l1_10_1_nb10.py b/src/pixel3dmm/preprocessing/PIPNet/experiments/LaPa/pip_32_16_60_r18_l2_l1_10_1_nb10.py new file mode 100644 index 0000000000000000000000000000000000000000..018b4d82ee597781bf8900e5b730ec26bc67009d --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/experiments/LaPa/pip_32_16_60_r18_l2_l1_10_1_nb10.py @@ -0,0 +1,21 @@ + +class Config(): + def __init__(self): + self.det_head = 'pip' + self.net_stride = 32 + self.batch_size = 16 + self.init_lr = 0.0001 + self.num_epochs = 60 + self.decay_steps = [30, 50] + self.input_size = 256 + self.backbone = 'resnet18' + self.pretrained = True + self.criterion_cls = 'l2' + self.criterion_reg = 'l1' + self.cls_loss_weight = 10 + self.reg_loss_weight = 1 + self.num_lms = 106 + self.save_interval = self.num_epochs + self.num_nb = 10 + self.use_gpu = True + self.gpu_id = 1 diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/LaPa/pip_32_16_60_r50_l2_l1_10_1_nb10.py b/src/pixel3dmm/preprocessing/PIPNet/experiments/LaPa/pip_32_16_60_r50_l2_l1_10_1_nb10.py new file mode 100644 index 0000000000000000000000000000000000000000..af1b52e323d1def97465ca758d82372a0ef4050a --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/experiments/LaPa/pip_32_16_60_r50_l2_l1_10_1_nb10.py @@ -0,0 +1,21 @@ + +class Config(): + def __init__(self): + self.det_head = 'pip' + self.net_stride = 32 + self.batch_size = 16 + self.init_lr = 0.0001 + self.num_epochs = 60 + self.decay_steps = [30, 50] + self.input_size = 256 + self.backbone = 'resnet50' + self.pretrained = True + self.criterion_cls = 'l2' + self.criterion_reg = 'l1' + self.cls_loss_weight = 10 + self.reg_loss_weight = 1 + self.num_lms = 106 + self.save_interval = self.num_epochs + self.num_nb = 10 + self.use_gpu = True + self.gpu_id = 1 diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/coord2_r101_l1.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/coord2_r101_l1.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c91252fbd99e2e0ce0592192477943c3a4b948b8 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/coord2_r101_l1.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/coord2_r18_l1.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/coord2_r18_l1.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..da50765df09299ab2de45f4dd8c333f1e7714820 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/coord2_r18_l1.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/coord2_r50_l1.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/coord2_r50_l1.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6b51e734004706767ea0629536042ff279e07c13 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/coord2_r50_l1.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/coord_r101_l1.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/coord_r101_l1.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..72502157a78d0a6d66abe4ae58185b353551b09e Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/coord_r101_l1.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/coord_r18_l1.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/coord_r18_l1.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5c090b877ac1d66241826ec578e463c5364929f8 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/coord_r18_l1.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/coord_r18_l2.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/coord_r18_l2.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1b5b3b23962e47407fce10bdf839db9737378457 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/coord_r18_l2.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/coord_r50_l1.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/coord_r50_l1.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5ebedba4c56a4c9da21f501c12a1148903140c72 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/coord_r50_l1.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/map_1_16_60_r18_l2.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/map_1_16_60_r18_l2.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e8aaafac35e793c4cccd2cbfc166eaddcb42eb9d Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/map_1_16_60_r18_l2.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/map_2_16_60_r101_l2.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/map_2_16_60_r101_l2.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7645b0616a768e1ab34ca8b59f014d2ab8543ca4 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/map_2_16_60_r101_l2.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/map_2_16_60_r18_l2.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/map_2_16_60_r18_l2.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4b73d2749dc443ce29e395c568c580fb84ebaf3b Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/map_2_16_60_r18_l2.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/map_2_16_60_r50_l2.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/map_2_16_60_r50_l2.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b24adf69bd50a6c5ed8e132a14c58711a8629840 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/map_2_16_60_r50_l2.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/map_4_16_60_r101_l2.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/map_4_16_60_r101_l2.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..242e78351685bbd5d9133a9c34b93a3827f39707 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/map_4_16_60_r101_l2.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/map_4_16_60_r18_l1.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/map_4_16_60_r18_l1.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..da977287e9924364af90b9441698b5af19fbdb16 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/map_4_16_60_r18_l1.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/map_4_16_60_r18_l2.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/map_4_16_60_r18_l2.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4949344798341d7012b3ac13f4edcafa3d1f4d4b Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/map_4_16_60_r18_l2.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/map_4_16_60_r50_l2.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/map_4_16_60_r50_l2.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..59614d54f67f6a90fb1ffaddbd10d21b1f47190f Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/map_4_16_60_r50_l2.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_128_16_60_r18_l2_l1_10_1_nb10.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_128_16_60_r18_l2_l1_10_1_nb10.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..563a95b787d9c4f54f5e218d35b7555700a83a5b Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_128_16_60_r18_l2_l1_10_1_nb10.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_16_16_60_r18_l2_l1_10_1_nb10.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_16_16_60_r18_l2_l1_10_1_nb10.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..95271f969068550d45983123d42c78e15ea15f93 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_16_16_60_r18_l2_l1_10_1_nb10.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r101_l2_l1_10_1_nb10.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r101_l2_l1_10_1_nb10.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..112df31f012dc3287c69fc5cc561c6f6a4e3c14b Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r101_l2_l1_10_1_nb10.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r152_l2_l1_10_1_nb10.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r152_l2_l1_10_1_nb10.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ea4b9cc55952a6be6c8aefe574b964f381e63f46 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r152_l2_l1_10_1_nb10.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r18_focal_l1_01_1.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r18_focal_l1_01_1.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fcc7124bc2c6541687df1d6426ef7af03587209c Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r18_focal_l1_01_1.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r18_focal_l2_01_1.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r18_focal_l2_01_1.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8cf8a79eede618f981002e394ddba1304dd0ec50 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r18_focal_l2_01_1.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r18_l2_l1_10_1.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r18_l2_l1_10_1.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7bfd62172a691e3d75f38bf4c5e1ddebc690e757 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r18_l2_l1_10_1.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb1.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb1.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4c8b3e7a167f1610da9590461af5175617cdcc68 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb1.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb10.cpython-36.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb10.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3ed0b2cb4f6936a96ea622292ff8ff507643cb60 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb10.cpython-36.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb10.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb10.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c5f3e6d4388d455d268770cd7b551c67e90125c5 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb10.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb10_nopre.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb10_nopre.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5d195ad254417ceb39d4ca0fb24b0da2aa8fd7b6 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb10_nopre.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb10_prior.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb10_prior.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ab7cb97ec88f18a045307507e77ef294baf653bc Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb10_prior.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb15.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb15.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ef0614bf5dc8b938bbf92917ad4101ee50a2c5ca Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb15.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb2.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb2.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..595e339c4f8bff70f6c40187c8c93eefd13baa3c Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb2.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb20.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb20.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f32d249fa78239a51b7a781296454caa93b6b8dd Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb20.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb25.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb25.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1db4d9744ee23b9cc92395ebb0015b9c0df2260d Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb25.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb3.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb3.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f6436b85bf01b421aa396adbef8d0cfe49212156 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb3.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb30.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb30.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e68513d26cdc6aec2181b737b5dd2c3d063bbcdf Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb30.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb40.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb40.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e68a29f7a18156a7c28dad7f6b798cb98f291060 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb40.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb5.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb5.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5e039cadc138ef01ace493dafaf6676a45e1c965 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb5.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb60.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb60.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..61541b06b1e7d1ffb707369b5c99c4404c1288fd Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb60.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r18_l2_l2_10_1.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r18_l2_l2_10_1.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a8b4499799785bfc8033c6372865856b3dc4b6ae Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r18_l2_l2_10_1.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r50_l2_l1_10_1.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r50_l2_l1_10_1.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e250452944943824ed94157b790b9e2ae6204af8 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r50_l2_l1_10_1.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r50_l2_l1_10_1_nb10.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r50_l2_l1_10_1_nb10.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c182dcb5d7752d2cb2cb29bf1c7f9899515f2b4f Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r50_l2_l1_10_1_nb10.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r50_l2_l1_10_1_nb10_nopre.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r50_l2_l1_10_1_nb10_nopre.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ef63dbc493506cea48fa3ae131f33eb21802dbc4 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r50_l2_l1_10_1_nb10_nopre.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r50_l2_l1_10_1_nb2.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r50_l2_l1_10_1_nb2.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a8653f8f41a292bc6bafc99426641502b4084923 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r50_l2_l1_10_1_nb2.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r50_l2_l1_10_1_nb20.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r50_l2_l1_10_1_nb20.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..45144d81bbebdcff9fd339f8963deb9e2cc1df4d Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r50_l2_l1_10_1_nb20.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r50_l2_l1_10_1_nb5.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r50_l2_l1_10_1_nb5.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7d9c458a2be16a2823591a5df7435a144d84d319 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_32_16_60_r50_l2_l1_10_1_nb5.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_64_16_60_r18_l2_l1_10_1_nb10.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_64_16_60_r18_l2_l1_10_1_nb10.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7460a6d341f644ce114d60b401c2360a6ee57b28 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/__pycache__/pip_64_16_60_r18_l2_l1_10_1_nb10.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/pip_32_16_60_r101_l2_l1_10_1_nb10.py b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/pip_32_16_60_r101_l2_l1_10_1_nb10.py new file mode 100644 index 0000000000000000000000000000000000000000..2148be8de44f736489160dc2a8fb62a8ef8e3a78 --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/pip_32_16_60_r101_l2_l1_10_1_nb10.py @@ -0,0 +1,21 @@ + +class Config(): + def __init__(self): + self.det_head = 'pip' + self.net_stride = 32 + self.batch_size = 16 + self.init_lr = 0.0001 + self.num_epochs = 60 + self.decay_steps = [30, 50] + self.input_size = 256 + self.backbone = 'resnet101' + self.pretrained = True + self.criterion_cls = 'l2' + self.criterion_reg = 'l1' + self.cls_loss_weight = 10 + self.reg_loss_weight = 1 + self.num_lms = 98 + self.save_interval = self.num_epochs + self.num_nb = 10 + self.use_gpu = True + self.gpu_id = 3 diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/pip_32_16_60_r18_l2_l1_10_1_nb10.py b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/pip_32_16_60_r18_l2_l1_10_1_nb10.py new file mode 100644 index 0000000000000000000000000000000000000000..a3599a6603c96fe7500a4bdc21e6568272f7884f --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/pip_32_16_60_r18_l2_l1_10_1_nb10.py @@ -0,0 +1,21 @@ + +class Config(): + def __init__(self): + self.det_head = 'pip' + self.net_stride = 32 + self.batch_size = 16 + self.init_lr = 0.0001 + self.num_epochs = 60 + self.decay_steps = [30, 50] + self.input_size = 256 + self.backbone = 'resnet18' + self.pretrained = True + self.criterion_cls = 'l2' + self.criterion_reg = 'l1' + self.cls_loss_weight = 10 + self.reg_loss_weight = 1 + self.num_lms = 98 + self.save_interval = self.num_epochs + self.num_nb = 10 + self.use_gpu = True + self.gpu_id = 2 diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/pip_32_16_60_r50_l2_l1_10_1_nb10.py b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/pip_32_16_60_r50_l2_l1_10_1_nb10.py new file mode 100644 index 0000000000000000000000000000000000000000..c0f35906e8225504e7c9cffe2f812250beaa805b --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/experiments/WFLW/pip_32_16_60_r50_l2_l1_10_1_nb10.py @@ -0,0 +1,21 @@ + +class Config(): + def __init__(self): + self.det_head = 'pip' + self.net_stride = 32 + self.batch_size = 16 + self.init_lr = 0.0001 + self.num_epochs = 60 + self.decay_steps = [30, 50] + self.input_size = 256 + self.backbone = 'resnet50' + self.pretrained = True + self.criterion_cls = 'l2' + self.criterion_reg = 'l1' + self.cls_loss_weight = 10 + self.reg_loss_weight = 1 + self.num_lms = 98 + self.save_interval = self.num_epochs + self.num_nb = 10 + self.use_gpu = True + self.gpu_id = 1 diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/coord.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/coord.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..81cb5b02d05b34d48cb30a2f5dd95b4c06e679e5 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/coord.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/coord2_r18_l1.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/coord2_r18_l1.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d61f0cb2a3f9f3b3c31add10eccce6a67ef841e2 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/coord2_r18_l1.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/coord_r18_l1.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/coord_r18_l1.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5684e25160d57a8a06a4ea41f8632aee1d026496 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/coord_r18_l1.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/full_pip_32_16_60.cpython-36.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/full_pip_32_16_60.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..58f3567825eebf2c673accc9b8101e7a1a901228 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/full_pip_32_16_60.cpython-36.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/map_1_16_60_r18_l2.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/map_1_16_60_r18_l2.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..366949dab95a8897e7c5688d52eca80498e25a3c Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/map_1_16_60_r18_l2.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/map_2_16_60_r18_l2.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/map_2_16_60_r18_l2.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8292d8cb0c6d5f050d9e3d916ccb063869349aea Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/map_2_16_60_r18_l2.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/map_4_16_60_r18_l2.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/map_4_16_60_r18_l2.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4fec9530a846a38acaf3ff4c25f1e75d77ac2543 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/map_4_16_60_r18_l2.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_128_16_60_r18_l2_l1_10_1_nb10.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_128_16_60_r18_l2_l1_10_1_nb10.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ac07d09a31d941d404d1a671ff72168cac191a3d Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_128_16_60_r18_l2_l1_10_1_nb10.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_16_16_60_r18_l2_l1_10_1_nb10.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_16_16_60_r18_l2_l1_10_1_nb10.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..90debda481ab20b8050c8c6f1972ecf31f38f9e1 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_16_16_60_r18_l2_l1_10_1_nb10.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r101_l2_l1_10_1_nb10.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r101_l2_l1_10_1_nb10.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d80ff2a6b3998b8f08d5f7465061a77b0c7ab98f Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r101_l2_l1_10_1_nb10.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r152_l2_l1_10_1_nb10.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r152_l2_l1_10_1_nb10.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..354d7f0904f4664913dec92dde43bc9d95bc9b88 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r152_l2_l1_10_1_nb10.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_focal_l1_01_05.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_focal_l1_01_05.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..18cd6d161c5899995f86e35389427022dfe9bf01 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_focal_l1_01_05.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_focal_l1_01_1.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_focal_l1_01_1.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..aa4f3b8ed1c0723f46b129953233d0cb38f50d3d Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_focal_l1_01_1.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_focal_l2_005_1.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_focal_l2_005_1.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a326ebab419d357bd8ed39032ce025bd672a6cd6 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_focal_l2_005_1.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_focal_l2_01_1.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_focal_l2_01_1.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..deb2b26b470ad77a4b9ef9532f4a4d60924d167e Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_focal_l2_01_1.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_focal_l2_03_1.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_focal_l2_03_1.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..64b54bb2c3d2189a9e92aae5a85dfa4f897a3702 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_focal_l2_03_1.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_focal_l2_05_1.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_focal_l2_05_1.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..426622dab9222c5b269a3daf182850812321146d Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_focal_l2_05_1.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_focal_l2_10_1.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_focal_l2_10_1.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..22d3f07dffc444657b321883e898c14c983332a1 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_focal_l2_10_1.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_focal_l2_1_1.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_focal_l2_1_1.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bf2f33eadc0734e0a16ece2886a65cbd061c26cf Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_focal_l2_1_1.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_l1_l1_10_1.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_l1_l1_10_1.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c1e4767a93d9a989b2315efbf145fb005508b51d Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_l1_l1_10_1.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_l1_l1_1_1.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_l1_l1_1_1.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f6ebf3c48724fb9775b69e35d48ba78b0ab84cdc Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_l1_l1_1_1.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_l1_l1_2_1.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_l1_l1_2_1.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7fecf986b16af96756e269bf68a27ab54d2a07e4 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_l1_l1_2_1.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_l1_l1_5_1.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_l1_l1_5_1.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d718b3549deee91d310b69db27645aeba236e118 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_l1_l1_5_1.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_l2_l1_10_05.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_l2_l1_10_05.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7cd37e34a3a4641515f48019d4b89e7ec61004ff Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_l2_l1_10_05.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_l2_l1_10_1.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_l2_l1_10_1.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7f48f6dbea32223a42270cfd16f07b586e546b44 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_l2_l1_10_1.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb10.cpython-36.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb10.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6aa94b0a285750a4c5d01c9eb202502182eb58c0 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb10.cpython-36.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb10.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb10.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..625b4d71eed64123e945c76f58a6172292db9b78 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb10.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb10_nopre.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb10_nopre.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..752756681e8062d49af80b464d37b3393f3a42f2 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb10_nopre.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb10_prior.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb10_prior.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..839794e78cfb1f74e2255dfd0db34f2e8741faf1 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb10_prior.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb2.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb2.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a8a5103c85045319aa2974a8f72997138cbc12fb Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb2.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb20.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb20.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bb546d60484b47dcf2de4d1cc3ae97653045fd96 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb20.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb30.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb30.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..96994b278b12349140d4480e51f564db1846fab8 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb30.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb40.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb40.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..147d16d2bcf6b1ebbed635a77dc3b9cd8631fcfe Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb40.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb5.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb5.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..78aba43330816738155cff2de833c8ef0dcd0393 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb5.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_l2_l2_10_1.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_l2_l2_10_1.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dd3057e6554ea756c1852b9c63f797b8b0b4599f Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r18_l2_l2_10_1.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r50_l2_l1_10_1.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r50_l2_l1_10_1.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6e26d8582937ef597b5012e522fc42de4b634b4f Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r50_l2_l1_10_1.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r50_l2_l1_10_1_nb10.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r50_l2_l1_10_1_nb10.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7bf0bdb4bbab3e9825333cf30737f6040088732c Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r50_l2_l1_10_1_nb10.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r50_l2_l1_10_1_nb2.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r50_l2_l1_10_1_nb2.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c494ed1e13a5b830205fb0706829d0edcb779558 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r50_l2_l1_10_1_nb2.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r50_l2_l1_10_1_nb20.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r50_l2_l1_10_1_nb20.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5946c9284930a90cc0ac4e312cabddb1c6cb5212 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r50_l2_l1_10_1_nb20.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r50_l2_l1_10_1_nb5.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r50_l2_l1_10_1_nb5.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..84d0a61bc8fb62a1f34614c6c3d99ebc6394b786 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_32_16_60_r50_l2_l1_10_1_nb5.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_64_16_60_r18_l2_l1_10_1_nb10.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_64_16_60_r18_l2_l1_10_1_nb10.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3fc5b205adeb70f5842bb813ccb8607af9ed5ffc Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/pip_64_16_60_r18_l2_l1_10_1_nb10.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/semi100flip_pip_32_16_60.cpython-36.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/semi100flip_pip_32_16_60.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b2f1fc736d328af5ddbb6d1c533aad051c1438fd Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/semi100flip_pip_32_16_60.cpython-36.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/semi100rot_pip_32_16_60.cpython-36.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/semi100rot_pip_32_16_60.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f9392c529b6092ac58c974be188b820cf7de880b Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/semi100rot_pip_32_16_60.cpython-36.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/semi100std_pip_32_16_60.cpython-36.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/semi100std_pip_32_16_60.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a48ed5cd789cd03ad5210a3baf317ee18aa032cf Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/semi100std_pip_32_16_60.cpython-36.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/semi100trans_pip_32_16_60.cpython-36.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/semi100trans_pip_32_16_60.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..669d19d0fad1180da8bcfbcec4b0b691f2c32901 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/semi100trans_pip_32_16_60.cpython-36.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/semi100transflip_pip_32_16_60.cpython-36.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/semi100transflip_pip_32_16_60.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4b34ee87b7cbe1501d613447d0208febbd3e1dfd Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/semi100transflip_pip_32_16_60.cpython-36.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/semi100transfliprot_pip_32_16_60.cpython-36.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/semi100transfliprot_pip_32_16_60.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..90797d7934b20df42fb3f6367431caf6b9728b2b Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/__pycache__/semi100transfliprot_pip_32_16_60.cpython-36.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/pip_32_16_60_r101_l2_l1_10_1_nb10.py b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/pip_32_16_60_r101_l2_l1_10_1_nb10.py new file mode 100644 index 0000000000000000000000000000000000000000..d08b533dedaaebfa3400f4ae87decd95fbd8bfef --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/pip_32_16_60_r101_l2_l1_10_1_nb10.py @@ -0,0 +1,21 @@ + +class Config(): + def __init__(self): + self.det_head = 'pip' + self.net_stride = 32 + self.batch_size = 16 + self.init_lr = 0.0001 + self.num_epochs = 60 + self.decay_steps = [30, 50] + self.input_size = 256 + self.backbone = 'resnet101' + self.pretrained = True + self.criterion_cls = 'l2' + self.criterion_reg = 'l1' + self.cls_loss_weight = 10 + self.reg_loss_weight = 1 + self.num_lms = 68 + self.save_interval = self.num_epochs + self.num_nb = 10 + self.use_gpu = True + self.gpu_id = 0 diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/pip_32_16_60_r18_l2_l1_10_1_nb10.py b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/pip_32_16_60_r18_l2_l1_10_1_nb10.py new file mode 100644 index 0000000000000000000000000000000000000000..5c0a89475453a8c220bd6174f4165d03ff609e14 --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/pip_32_16_60_r18_l2_l1_10_1_nb10.py @@ -0,0 +1,21 @@ + +class Config(): + def __init__(self): + self.det_head = 'pip' + self.net_stride = 32 + self.batch_size = 16 + self.init_lr = 0.0001 + self.num_epochs = 60 + self.decay_steps = [30, 50] + self.input_size = 256 + self.backbone = 'resnet18' + self.pretrained = True + self.criterion_cls = 'l2' + self.criterion_reg = 'l1' + self.cls_loss_weight = 10 + self.reg_loss_weight = 1 + self.num_lms = 68 + self.save_interval = self.num_epochs + self.num_nb = 10 + self.use_gpu = True + self.gpu_id = 2 diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/pip_32_16_60_r50_l2_l1_10_1_nb10.py b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/pip_32_16_60_r50_l2_l1_10_1_nb10.py new file mode 100644 index 0000000000000000000000000000000000000000..1e84367abcd5bd80af4966d33ab31cc5acb97088 --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W/pip_32_16_60_r50_l2_l1_10_1_nb10.py @@ -0,0 +1,21 @@ + +class Config(): + def __init__(self): + self.det_head = 'pip' + self.net_stride = 32 + self.batch_size = 16 + self.init_lr = 0.0001 + self.num_epochs = 60 + self.decay_steps = [30, 50] + self.input_size = 256 + self.backbone = 'resnet50' + self.pretrained = True + self.criterion_cls = 'l2' + self.criterion_reg = 'l1' + self.cls_loss_weight = 10 + self.reg_loss_weight = 1 + self.num_lms = 68 + self.save_interval = self.num_epochs + self.num_nb = 10 + self.use_gpu = True + self.gpu_id = 1 diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W_CELEBA/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb10_wcc.cpython-36.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W_CELEBA/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb10_wcc.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1f25bef0a6f76165de46ddd1bb63265b2d8faa9a Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W_CELEBA/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb10_wcc.cpython-36.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W_CELEBA/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb10_wcc.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W_CELEBA/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb10_wcc.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f036799e703b20619b36c9449ccc4616ce7c708b Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W_CELEBA/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb10_wcc.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W_CELEBA/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb10_wocc.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W_CELEBA/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb10_wocc.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..26298c4203edbfec14d275012aba5445ad98ddff Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W_CELEBA/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb10_wocc.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W_CELEBA/pip_32_16_60_r18_l2_l1_10_1_nb10_wcc.py b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W_CELEBA/pip_32_16_60_r18_l2_l1_10_1_nb10_wcc.py new file mode 100644 index 0000000000000000000000000000000000000000..f3adf0b84c17f02a16b0b333f31d6c88316a3d83 --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W_CELEBA/pip_32_16_60_r18_l2_l1_10_1_nb10_wcc.py @@ -0,0 +1,23 @@ +# with curriculum + +class Config(): + def __init__(self): + self.det_head = 'pip' + self.net_stride = 32 + self.batch_size = 16 + self.init_lr = 0.0001 + self.num_epochs = 60 + self.decay_steps = [30, 50] + self.input_size = 256 + self.backbone = 'resnet18' + self.pretrained = True + self.criterion_cls = 'l2' + self.criterion_reg = 'l1' + self.cls_loss_weight = 10 + self.reg_loss_weight = 1 + self.num_lms = 68 + self.save_interval = self.num_epochs + self.num_nb = 10 + self.use_gpu = True + self.gpu_id = 4 + self.curriculum = True diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W_COFW_WFLW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb10_wcc.cpython-36.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W_COFW_WFLW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb10_wcc.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..eb4ff993d942c8a6a22f84a1619be427e1113236 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W_COFW_WFLW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb10_wcc.cpython-36.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W_COFW_WFLW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb10_wcc.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W_COFW_WFLW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb10_wcc.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4c24e0c01f26080da60a8c3df8ac9093f1b571a8 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W_COFW_WFLW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb10_wcc.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W_COFW_WFLW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb10_wocc.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W_COFW_WFLW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb10_wocc.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3344e3d7e86f667ee0bc2594fb109e3ef05bad38 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W_COFW_WFLW/__pycache__/pip_32_16_60_r18_l2_l1_10_1_nb10_wocc.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W_COFW_WFLW/pip_32_16_60_r18_l2_l1_10_1_nb10_wcc.py b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W_COFW_WFLW/pip_32_16_60_r18_l2_l1_10_1_nb10_wcc.py new file mode 100644 index 0000000000000000000000000000000000000000..09403895467dc8a11ce59460b86718cc6dc9f25a --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/experiments/data_300W_COFW_WFLW/pip_32_16_60_r18_l2_l1_10_1_nb10_wcc.py @@ -0,0 +1,23 @@ +# with curriculum + +class Config(): + def __init__(self): + self.det_head = 'pip' + self.net_stride = 32 + self.batch_size = 16 + self.init_lr = 0.0001 + self.num_epochs = 60 + self.decay_steps = [30, 50] + self.input_size = 256 + self.backbone = 'resnet18' + self.pretrained = True + self.criterion_cls = 'l2' + self.criterion_reg = 'l1' + self.cls_loss_weight = 10 + self.reg_loss_weight = 1 + self.num_lms = 68 + self.save_interval = self.num_epochs + self.num_nb = 10 + self.use_gpu = True + self.gpu_id = 1 + self.curriculum = True diff --git a/src/pixel3dmm/preprocessing/PIPNet/images/1.jpg b/src/pixel3dmm/preprocessing/PIPNet/images/1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b84882e3373ac2345b93d862eef25d1d0adbee17 --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/images/1.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4db580aec7d10b378cb5a2fbf9fa92794d7272b6c010819e0d807aa9c1c14f0f +size 192416 diff --git a/src/pixel3dmm/preprocessing/PIPNet/images/1_out_WFLW_model.jpg b/src/pixel3dmm/preprocessing/PIPNet/images/1_out_WFLW_model.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6a04b49c179cb1dd264a0439875c05ac3fecb343 --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/images/1_out_WFLW_model.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1ff016afeeec14f63c6e47387579555f2e88df416d0561322c6dddeaeed11f2a +size 204511 diff --git a/src/pixel3dmm/preprocessing/PIPNet/images/2.jpg b/src/pixel3dmm/preprocessing/PIPNet/images/2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6713bf5ee158896f712c8e924dd58537b075e5b0 --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/images/2.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:779151d281dbf4817d41617385c90bfce09dfab41a2efd915df60f2eff352cfe +size 255833 diff --git a/src/pixel3dmm/preprocessing/PIPNet/images/3.jpg b/src/pixel3dmm/preprocessing/PIPNet/images/3.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7116e6ffb9d8fe9a7bffe1d2436b857842f56654 --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/images/3.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:613664679df9a2278941cdf64d712e0c5d179c04708426dfade668cb0d8056de +size 180650 diff --git a/src/pixel3dmm/preprocessing/PIPNet/images/detection_heads.png b/src/pixel3dmm/preprocessing/PIPNet/images/detection_heads.png new file mode 100644 index 0000000000000000000000000000000000000000..28883c7560b44d0de48064b4f40d170ec303b0b9 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/images/detection_heads.png differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/images/speed.png b/src/pixel3dmm/preprocessing/PIPNet/images/speed.png new file mode 100644 index 0000000000000000000000000000000000000000..d503e79bc530edff766f4e5522b0a12c7dbf7bf2 --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/images/speed.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:049c7dea6c4d19149f3fcdeac802409486e6f2b8e4c7736f8b298b929fb75bc2 +size 225036 diff --git a/src/pixel3dmm/preprocessing/PIPNet/lib/__pycache__/data_utils.cpython-36.pyc b/src/pixel3dmm/preprocessing/PIPNet/lib/__pycache__/data_utils.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8e57d1dfa4184b7c37c2c6fe4eb909405060b2a9 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/lib/__pycache__/data_utils.cpython-36.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/lib/__pycache__/data_utils.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/lib/__pycache__/data_utils.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9f81af864dd9819e63f44d8cfad7668c9e0ce2ba Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/lib/__pycache__/data_utils.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/lib/__pycache__/data_utils_ssl.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/lib/__pycache__/data_utils_ssl.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bffa9ce978beff1d4fa24d184c4fb004ece4cf24 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/lib/__pycache__/data_utils_ssl.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/lib/__pycache__/data_utils_uda.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/lib/__pycache__/data_utils_uda.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..65e4db5902fa8a45c518ba242cbdab7a3b26de72 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/lib/__pycache__/data_utils_uda.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/lib/__pycache__/functions.cpython-36.pyc b/src/pixel3dmm/preprocessing/PIPNet/lib/__pycache__/functions.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..70fb37c404b1d9b6488d4feb1e7a13dbce57f109 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/lib/__pycache__/functions.cpython-36.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/lib/__pycache__/functions.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/lib/__pycache__/functions.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..89819f53efe4e98e33ae439e8f368cafdcc4776c Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/lib/__pycache__/functions.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/lib/__pycache__/functions_ssl.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/lib/__pycache__/functions_ssl.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..66a2f4d7a4f70d0780b305cb9d455b9f4a167c16 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/lib/__pycache__/functions_ssl.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/lib/__pycache__/functions_uda.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/lib/__pycache__/functions_uda.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..79dbc222c54309f379194e030ea676400dc2ec93 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/lib/__pycache__/functions_uda.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/lib/__pycache__/losses.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/lib/__pycache__/losses.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e1c500fdab7e14fd70b4fc30cb243d7434106664 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/lib/__pycache__/losses.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/lib/__pycache__/networks.cpython-36.pyc b/src/pixel3dmm/preprocessing/PIPNet/lib/__pycache__/networks.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7434ac19c2b92e57899c9118af92d9b8b54c3378 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/lib/__pycache__/networks.cpython-36.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/lib/__pycache__/networks.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/lib/__pycache__/networks.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..87429b3d2c7298fadb9f8f5502c072567e38b670 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/lib/__pycache__/networks.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/lib/__pycache__/networks_ssl.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/lib/__pycache__/networks_ssl.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..aff4f318f673c178931fa581fc76fe41edcf6cca Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/lib/__pycache__/networks_ssl.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/lib/__pycache__/networks_uda.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/lib/__pycache__/networks_uda.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d028cb2d4da711cc1af1c9369b641ffe8a3b43bd Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/lib/__pycache__/networks_uda.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/lib/__pycache__/utils.cpython-37.pyc b/src/pixel3dmm/preprocessing/PIPNet/lib/__pycache__/utils.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fb7f29c0aab95782d9e6939c251e824ba9ec9ba1 Binary files /dev/null and b/src/pixel3dmm/preprocessing/PIPNet/lib/__pycache__/utils.cpython-37.pyc differ diff --git a/src/pixel3dmm/preprocessing/PIPNet/lib/data_utils.py b/src/pixel3dmm/preprocessing/PIPNet/lib/data_utils.py new file mode 100644 index 0000000000000000000000000000000000000000..2ba8e93b20dfcebbdc1895dda6563bd6ee5870bb --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/lib/data_utils.py @@ -0,0 +1,166 @@ +import torch.utils.data as data +import torch +from PIL import Image, ImageFilter +import os, cv2 +import numpy as np +import random +from scipy.stats import norm +from math import floor + +def random_translate(image, target): + if random.random() > 0.5: + image_height, image_width = image.size + a = 1 + b = 0 + #c = 30 #left/right (i.e. 5/-5) + c = int((random.random()-0.5) * 60) + d = 0 + e = 1 + #f = 30 #up/down (i.e. 5/-5) + f = int((random.random()-0.5) * 60) + image = image.transform(image.size, Image.AFFINE, (a, b, c, d, e, f)) + target_translate = target.copy() + target_translate = target_translate.reshape(-1, 2) + target_translate[:, 0] -= 1.*c/image_width + target_translate[:, 1] -= 1.*f/image_height + target_translate = target_translate.flatten() + target_translate[target_translate < 0] = 0 + target_translate[target_translate > 1] = 1 + return image, target_translate + else: + return image, target + +def random_blur(image): + if random.random() > 0.7: + image = image.filter(ImageFilter.GaussianBlur(random.random()*5)) + return image + +def random_occlusion(image): + if random.random() > 0.5: + image_np = np.array(image).astype(np.uint8) + image_np = image_np[:,:,::-1] + image_height, image_width, _ = image_np.shape + occ_height = int(image_height*0.4*random.random()) + occ_width = int(image_width*0.4*random.random()) + occ_xmin = int((image_width - occ_width - 10) * random.random()) + occ_ymin = int((image_height - occ_height - 10) * random.random()) + image_np[occ_ymin:occ_ymin+occ_height, occ_xmin:occ_xmin+occ_width, 0] = int(random.random() * 255) + image_np[occ_ymin:occ_ymin+occ_height, occ_xmin:occ_xmin+occ_width, 1] = int(random.random() * 255) + image_np[occ_ymin:occ_ymin+occ_height, occ_xmin:occ_xmin+occ_width, 2] = int(random.random() * 255) + image_pil = Image.fromarray(image_np[:,:,::-1].astype('uint8'), 'RGB') + return image_pil + else: + return image + +def random_flip(image, target, points_flip): + if random.random() > 0.5: + image = image.transpose(Image.FLIP_LEFT_RIGHT) + target = np.array(target).reshape(-1, 2) + target = target[points_flip, :] + target[:,0] = 1-target[:,0] + target = target.flatten() + return image, target + else: + return image, target + +def random_rotate(image, target, angle_max): + if random.random() > 0.5: + center_x = 0.5 + center_y = 0.5 + landmark_num= int(len(target) / 2) + target_center = np.array(target) - np.array([center_x, center_y]*landmark_num) + target_center = target_center.reshape(landmark_num, 2) + theta_max = np.radians(angle_max) + theta = random.uniform(-theta_max, theta_max) + angle = np.degrees(theta) + image = image.rotate(angle) + + c, s = np.cos(theta), np.sin(theta) + rot = np.array(((c,-s), (s, c))) + target_center_rot = np.matmul(target_center, rot) + target_rot = target_center_rot.reshape(landmark_num*2) + np.array([center_x, center_y]*landmark_num) + return image, target_rot + else: + return image, target + +def gen_target_pip(target, meanface_indices, target_map, target_local_x, target_local_y, target_nb_x, target_nb_y): + num_nb = len(meanface_indices[0]) + map_channel, map_height, map_width = target_map.shape + target = target.reshape(-1, 2) + assert map_channel == target.shape[0] + + for i in range(map_channel): + mu_x = int(floor(target[i][0] * map_width)) + mu_y = int(floor(target[i][1] * map_height)) + mu_x = max(0, mu_x) + mu_y = max(0, mu_y) + mu_x = min(mu_x, map_width-1) + mu_y = min(mu_y, map_height-1) + target_map[i, mu_y, mu_x] = 1 + shift_x = target[i][0] * map_width - mu_x + shift_y = target[i][1] * map_height - mu_y + target_local_x[i, mu_y, mu_x] = shift_x + target_local_y[i, mu_y, mu_x] = shift_y + + for j in range(num_nb): + nb_x = target[meanface_indices[i][j]][0] * map_width - mu_x + nb_y = target[meanface_indices[i][j]][1] * map_height - mu_y + target_nb_x[num_nb*i+j, mu_y, mu_x] = nb_x + target_nb_y[num_nb*i+j, mu_y, mu_x] = nb_y + + return target_map, target_local_x, target_local_y, target_nb_x, target_nb_y + +class ImageFolder_pip(data.Dataset): + def __init__(self, root, imgs, input_size, num_lms, net_stride, points_flip, meanface_indices, transform=None, target_transform=None): + self.root = root + self.imgs = imgs + self.num_lms = num_lms + self.net_stride = net_stride + self.points_flip = points_flip + self.meanface_indices = meanface_indices + self.num_nb = len(meanface_indices[0]) + self.transform = transform + self.target_transform = target_transform + self.input_size = input_size + + def __getitem__(self, index): + + img_name, target = self.imgs[index] + + img = Image.open(os.path.join(self.root, img_name)).convert('RGB') + img, target = random_translate(img, target) + img = random_occlusion(img) + img, target = random_flip(img, target, self.points_flip) + img, target = random_rotate(img, target, 30) + img = random_blur(img) + + target_map = np.zeros((self.num_lms, int(self.input_size/self.net_stride), int(self.input_size/self.net_stride))) + target_local_x = np.zeros((self.num_lms, int(self.input_size/self.net_stride), int(self.input_size/self.net_stride))) + target_local_y = np.zeros((self.num_lms, int(self.input_size/self.net_stride), int(self.input_size/self.net_stride))) + target_nb_x = np.zeros((self.num_nb*self.num_lms, int(self.input_size/self.net_stride), int(self.input_size/self.net_stride))) + target_nb_y = np.zeros((self.num_nb*self.num_lms, int(self.input_size/self.net_stride), int(self.input_size/self.net_stride))) + target_map, target_local_x, target_local_y, target_nb_x, target_nb_y = gen_target_pip(target, self.meanface_indices, target_map, target_local_x, target_local_y, target_nb_x, target_nb_y) + + target_map = torch.from_numpy(target_map).float() + target_local_x = torch.from_numpy(target_local_x).float() + target_local_y = torch.from_numpy(target_local_y).float() + target_nb_x = torch.from_numpy(target_nb_x).float() + target_nb_y = torch.from_numpy(target_nb_y).float() + + if self.transform is not None: + img = self.transform(img) + if self.target_transform is not None: + target_map = self.target_transform(target_map) + target_local_x = self.target_transform(target_local_x) + target_local_y = self.target_transform(target_local_y) + target_nb_x = self.target_transform(target_nb_x) + target_nb_y = self.target_transform(target_nb_y) + + return img, target_map, target_local_x, target_local_y, target_nb_x, target_nb_y + + def __len__(self): + return len(self.imgs) + +if __name__ == '__main__': + pass + diff --git a/src/pixel3dmm/preprocessing/PIPNet/lib/data_utils_gssl.py b/src/pixel3dmm/preprocessing/PIPNet/lib/data_utils_gssl.py new file mode 100644 index 0000000000000000000000000000000000000000..af0d8acb4455a9b3fdfd13fd26e1a6eecb87101d --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/lib/data_utils_gssl.py @@ -0,0 +1,290 @@ +import torch.utils.data as data +import torch +from PIL import Image, ImageFilter +import os, cv2 +import numpy as np +import random +from scipy.stats import norm +from math import floor + +def random_translate(image, target): + if random.random() > 0.5: + image_height, image_width = image.size + a = 1 + b = 0 + #c = 30 #left/right (i.e. 5/-5) + c = int((random.random()-0.5) * 60) + d = 0 + e = 1 + #f = 30 #up/down (i.e. 5/-5) + f = int((random.random()-0.5) * 60) + image = image.transform(image.size, Image.AFFINE, (a, b, c, d, e, f)) + target_translate = target.copy() + target_translate = target_translate.reshape(-1, 2) + target_translate[:, 0] -= 1.*c/image_width + target_translate[:, 1] -= 1.*f/image_height + target_translate = target_translate.flatten() + target_translate[target_translate < 0] = 0 + target_translate[target_translate > 1] = 1 + return image, target_translate + else: + return image, target + +def random_blur(image): + if random.random() > 0.7: + image = image.filter(ImageFilter.GaussianBlur(random.random()*5)) + return image + +def random_occlusion(image): + if random.random() > 0.5: + image_np = np.array(image).astype(np.uint8) + image_np = image_np[:,:,::-1] + image_height, image_width, _ = image_np.shape + occ_height = int(image_height*0.4*random.random()) + occ_width = int(image_width*0.4*random.random()) + occ_xmin = int((image_width - occ_width - 10) * random.random()) + occ_ymin = int((image_height - occ_height - 10) * random.random()) + image_np[occ_ymin:occ_ymin+occ_height, occ_xmin:occ_xmin+occ_width, 0] = int(random.random() * 255) + image_np[occ_ymin:occ_ymin+occ_height, occ_xmin:occ_xmin+occ_width, 1] = int(random.random() * 255) + image_np[occ_ymin:occ_ymin+occ_height, occ_xmin:occ_xmin+occ_width, 2] = int(random.random() * 255) + image_pil = Image.fromarray(image_np[:,:,::-1].astype('uint8'), 'RGB') + return image_pil + else: + return image + +def random_flip(image, target, points_flip): + if random.random() > 0.5: + image = image.transpose(Image.FLIP_LEFT_RIGHT) + target = np.array(target).reshape(-1, 2) + target = target[points_flip, :] + target[:,0] = 1-target[:,0] + target = target.flatten() + return image, target + else: + return image, target + +def random_rotate(image, target, angle_max): + if random.random() > 0.5: + center_x = 0.5 + center_y = 0.5 + landmark_num= int(len(target) / 2) + target_center = np.array(target) - np.array([center_x, center_y]*landmark_num) + target_center = target_center.reshape(landmark_num, 2) + theta_max = np.radians(angle_max) + theta = random.uniform(-theta_max, theta_max) + angle = np.degrees(theta) + image = image.rotate(angle) + + c, s = np.cos(theta), np.sin(theta) + rot = np.array(((c,-s), (s, c))) + target_center_rot = np.matmul(target_center, rot) + target_rot = target_center_rot.reshape(landmark_num*2) + np.array([center_x, center_y]*landmark_num) + return image, target_rot + else: + return image, target + +def gen_target_pip(target, meanface_indices, target_map1, target_map2, target_map3, target_local_x, target_local_y, target_nb_x, target_nb_y): + num_nb = len(meanface_indices[0]) + map_channel1, map_height1, map_width1 = target_map1.shape + map_channel2, map_height2, map_width2 = target_map2.shape + map_channel3, map_height3, map_width3 = target_map3.shape + target = target.reshape(-1, 2) + assert map_channel1 == target.shape[0] + + for i in range(map_channel1): + mu_x1 = int(floor(target[i][0] * map_width1)) + mu_y1 = int(floor(target[i][1] * map_height1)) + mu_x1 = max(0, mu_x1) + mu_y1 = max(0, mu_y1) + mu_x1 = min(mu_x1, map_width1-1) + mu_y1 = min(mu_y1, map_height1-1) + target_map1[i, mu_y1, mu_x1] = 1 + + shift_x = target[i][0] * map_width1 - mu_x1 + shift_y = target[i][1] * map_height1 - mu_y1 + target_local_x[i, mu_y1, mu_x1] = shift_x + target_local_y[i, mu_y1, mu_x1] = shift_y + + for j in range(num_nb): + nb_x = target[meanface_indices[i][j]][0] * map_width1 - mu_x1 + nb_y = target[meanface_indices[i][j]][1] * map_height1 - mu_y1 + target_nb_x[num_nb*i+j, mu_y1, mu_x1] = nb_x + target_nb_y[num_nb*i+j, mu_y1, mu_x1] = nb_y + + mu_x2 = int(floor(target[i][0] * map_width2)) + mu_y2 = int(floor(target[i][1] * map_height2)) + mu_x2 = max(0, mu_x2) + mu_y2 = max(0, mu_y2) + mu_x2 = min(mu_x2, map_width2-1) + mu_y2 = min(mu_y2, map_height2-1) + target_map2[i, mu_y2, mu_x2] = 1 + + mu_x3 = int(floor(target[i][0] * map_width3)) + mu_y3 = int(floor(target[i][1] * map_height3)) + mu_x3 = max(0, mu_x3) + mu_y3 = max(0, mu_y3) + mu_x3 = min(mu_x3, map_width3-1) + mu_y3 = min(mu_y3, map_height3-1) + target_map3[i, mu_y3, mu_x3] = 1 + + return target_map1, target_map2, target_map3, target_local_x, target_local_y, target_nb_x, target_nb_y + +def gen_target_pip_cls1(target, target_map1): + map_channel1, map_height1, map_width1 = target_map1.shape + target = target.reshape(-1, 2) + assert map_channel1 == target.shape[0] + + for i in range(map_channel1): + mu_x1 = int(floor(target[i][0] * map_width1)) + mu_y1 = int(floor(target[i][1] * map_height1)) + mu_x1 = max(0, mu_x1) + mu_y1 = max(0, mu_y1) + mu_x1 = min(mu_x1, map_width1-1) + mu_y1 = min(mu_y1, map_height1-1) + target_map1[i, mu_y1, mu_x1] = 1 + + return target_map1 + +def gen_target_pip_cls2(target, target_map2): + map_channel2, map_height2, map_width2 = target_map2.shape + target = target.reshape(-1, 2) + assert map_channel2 == target.shape[0] + + for i in range(map_channel2): + mu_x2 = int(floor(target[i][0] * map_width2)) + mu_y2 = int(floor(target[i][1] * map_height2)) + mu_x2 = max(0, mu_x2) + mu_y2 = max(0, mu_y2) + mu_x2 = min(mu_x2, map_width2-1) + mu_y2 = min(mu_y2, map_height2-1) + target_map2[i, mu_y2, mu_x2] = 1 + + return target_map2 + +def gen_target_pip_cls3(target, target_map3): + map_channel3, map_height3, map_width3 = target_map3.shape + target = target.reshape(-1, 2) + assert map_channel3 == target.shape[0] + + for i in range(map_channel3): + mu_x3 = int(floor(target[i][0] * map_width3)) + mu_y3 = int(floor(target[i][1] * map_height3)) + mu_x3 = max(0, mu_x3) + mu_y3 = max(0, mu_y3) + mu_x3 = min(mu_x3, map_width3-1) + mu_y3 = min(mu_y3, map_height3-1) + target_map3[i, mu_y3, mu_x3] = 1 + + return target_map3 + +class ImageFolder_pip(data.Dataset): + def __init__(self, root, imgs, input_size, num_lms, net_stride, points_flip, meanface_indices, transform=None, target_transform=None): + self.root = root + self.imgs = imgs + self.num_lms = num_lms + self.net_stride = net_stride + self.points_flip = points_flip + self.meanface_indices = meanface_indices + self.num_nb = len(meanface_indices[0]) + self.transform = transform + self.target_transform = target_transform + self.input_size = input_size + + def __getitem__(self, index): + """ + Args: + index (int): Index + Returns: + tuple: (image, target) where target is class_index of the target class. + """ + img_name, target_type, target = self.imgs[index] + img = Image.open(os.path.join(self.root, img_name)).convert('RGB') + + img, target = random_translate(img, target) + img = random_occlusion(img) + img, target = random_flip(img, target, self.points_flip) + img, target = random_rotate(img, target, 30) + img = random_blur(img) + + target_map1 = np.zeros((self.num_lms, int(self.input_size/self.net_stride), int(self.input_size/self.net_stride))) + target_map2 = np.zeros((self.num_lms, int(self.input_size/self.net_stride/2), int(self.input_size/self.net_stride/2))) + target_map3 = np.zeros((self.num_lms, int(self.input_size/self.net_stride/4), int(self.input_size/self.net_stride/4))) + target_local_x = np.zeros((self.num_lms, int(self.input_size/self.net_stride), int(self.input_size/self.net_stride))) + target_local_y = np.zeros((self.num_lms, int(self.input_size/self.net_stride), int(self.input_size/self.net_stride))) + target_nb_x = np.zeros((self.num_nb*self.num_lms, int(self.input_size/self.net_stride), int(self.input_size/self.net_stride))) + target_nb_y = np.zeros((self.num_nb*self.num_lms, int(self.input_size/self.net_stride), int(self.input_size/self.net_stride))) + + mask_map1 = np.ones((self.num_lms, int(self.input_size/self.net_stride), int(self.input_size/self.net_stride))) + mask_map2 = np.ones((self.num_lms, int(self.input_size/self.net_stride/2), int(self.input_size/self.net_stride/2))) + mask_map3 = np.ones((self.num_lms, int(self.input_size/self.net_stride/4), int(self.input_size/self.net_stride/4))) + mask_local_x = np.ones((self.num_lms, int(self.input_size/self.net_stride), int(self.input_size/self.net_stride))) + mask_local_y = np.ones((self.num_lms, int(self.input_size/self.net_stride), int(self.input_size/self.net_stride))) + mask_nb_x = np.ones((self.num_nb*self.num_lms, int(self.input_size/self.net_stride), int(self.input_size/self.net_stride))) + mask_nb_y = np.ones((self.num_nb*self.num_lms, int(self.input_size/self.net_stride), int(self.input_size/self.net_stride))) + + if target_type == 'std': + target_map1, target_map2, target_map3, target_local_x, target_local_y, target_nb_x, target_nb_y = gen_target_pip(target, self.meanface_indices, target_map1, target_map2, target_map3, target_local_x, target_local_y, target_nb_x, target_nb_y) + mask_map2 = np.zeros((self.num_lms, int(self.input_size/self.net_stride/2), int(self.input_size/self.net_stride/2))) + mask_map3 = np.zeros((self.num_lms, int(self.input_size/self.net_stride/4), int(self.input_size/self.net_stride/4))) + elif target_type == 'cls1': + target_map1 = gen_target_pip_cls1(target, target_map1) + mask_map2 = np.zeros((self.num_lms, int(self.input_size/self.net_stride/2), int(self.input_size/self.net_stride/2))) + mask_map3 = np.zeros((self.num_lms, int(self.input_size/self.net_stride/4), int(self.input_size/self.net_stride/4))) + mask_local_x = np.zeros((self.num_lms, int(self.input_size/self.net_stride), int(self.input_size/self.net_stride))) + mask_local_y = np.zeros((self.num_lms, int(self.input_size/self.net_stride), int(self.input_size/self.net_stride))) + mask_nb_x = np.zeros((self.num_nb*self.num_lms, int(self.input_size/self.net_stride), int(self.input_size/self.net_stride))) + mask_nb_y = np.zeros((self.num_nb*self.num_lms, int(self.input_size/self.net_stride), int(self.input_size/self.net_stride))) + elif target_type == 'cls2': + target_map2 = gen_target_pip_cls2(target, target_map2) + mask_map1 = np.zeros((self.num_lms, int(self.input_size/self.net_stride), int(self.input_size/self.net_stride))) + mask_map3 = np.zeros((self.num_lms, int(self.input_size/self.net_stride/4), int(self.input_size/self.net_stride/4))) + mask_local_x = np.zeros((self.num_lms, int(self.input_size/self.net_stride), int(self.input_size/self.net_stride))) + mask_local_y = np.zeros((self.num_lms, int(self.input_size/self.net_stride), int(self.input_size/self.net_stride))) + mask_nb_x = np.zeros((self.num_nb*self.num_lms, int(self.input_size/self.net_stride), int(self.input_size/self.net_stride))) + mask_nb_y = np.zeros((self.num_nb*self.num_lms, int(self.input_size/self.net_stride), int(self.input_size/self.net_stride))) + elif target_type == 'cls3': + target_map3 = gen_target_pip_cls3(target, target_map3) + mask_map1 = np.zeros((self.num_lms, int(self.input_size/self.net_stride), int(self.input_size/self.net_stride))) + mask_map2 = np.zeros((self.num_lms, int(self.input_size/self.net_stride/2), int(self.input_size/self.net_stride/2))) + mask_local_x = np.zeros((self.num_lms, int(self.input_size/self.net_stride), int(self.input_size/self.net_stride))) + mask_local_y = np.zeros((self.num_lms, int(self.input_size/self.net_stride), int(self.input_size/self.net_stride))) + mask_nb_x = np.zeros((self.num_nb*self.num_lms, int(self.input_size/self.net_stride), int(self.input_size/self.net_stride))) + mask_nb_y = np.zeros((self.num_nb*self.num_lms, int(self.input_size/self.net_stride), int(self.input_size/self.net_stride))) + else: + print('No such target type!') + exit(0) + + target_map1 = torch.from_numpy(target_map1).float() + target_map2 = torch.from_numpy(target_map2).float() + target_map3 = torch.from_numpy(target_map3).float() + target_local_x = torch.from_numpy(target_local_x).float() + target_local_y = torch.from_numpy(target_local_y).float() + target_nb_x = torch.from_numpy(target_nb_x).float() + target_nb_y = torch.from_numpy(target_nb_y).float() + mask_map1 = torch.from_numpy(mask_map1).float() + mask_map2 = torch.from_numpy(mask_map2).float() + mask_map3 = torch.from_numpy(mask_map3).float() + mask_local_x = torch.from_numpy(mask_local_x).float() + mask_local_y = torch.from_numpy(mask_local_y).float() + mask_nb_x = torch.from_numpy(mask_nb_x).float() + mask_nb_y = torch.from_numpy(mask_nb_y).float() + + if self.transform is not None: + img = self.transform(img) + if self.target_transform is not None: + target_map1 = self.target_transform(target_map1) + target_map2 = self.target_transform(target_map2) + target_map3 = self.target_transform(target_map3) + target_local_x = self.target_transform(target_local_x) + target_local_y = self.target_transform(target_local_y) + target_nb_x = self.target_transform(target_nb_x) + target_nb_y = self.target_transform(target_nb_y) + + return img, target_map1, target_map2, target_map3, target_local_x, target_local_y, target_nb_x, target_nb_y, mask_map1, mask_map2, mask_map3, mask_local_x, mask_local_y, mask_nb_x, mask_nb_y + + def __len__(self): + return len(self.imgs) + +if __name__ == '__main__': + pass + diff --git a/src/pixel3dmm/preprocessing/PIPNet/lib/demo.py b/src/pixel3dmm/preprocessing/PIPNet/lib/demo.py new file mode 100644 index 0000000000000000000000000000000000000000..fdb935ced7131905a8dfae256afe396632ab3f22 --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/lib/demo.py @@ -0,0 +1,133 @@ +import cv2, os +import sys +sys.path.insert(0, 'FaceBoxesV2') +sys.path.insert(0, '..') +import numpy as np +import pickle +import importlib +from math import floor +from faceboxes_detector import * +import time + +import torch +import torch.nn as nn +import torch.nn.parallel +import torch.optim as optim +import torch.utils.data +import torch.nn.functional as F +import torchvision.transforms as transforms +import torchvision.datasets as datasets +import torchvision.models as models + +from networks import * +import data_utils +from functions import * +from mobilenetv3 import mobilenetv3_large + +if not len(sys.argv) == 3: + print('Format:') + print('python lib/demo.py config_file image_file') + exit(0) +experiment_name = sys.argv[1].split('/')[-1][:-3] +data_name = sys.argv[1].split('/')[-2] +config_path = '.experiments.{}.{}'.format(data_name, experiment_name) +image_file = sys.argv[2] + +my_config = importlib.import_module(config_path, package='PIPNet') +Config = getattr(my_config, 'Config') +cfg = Config() +cfg.experiment_name = experiment_name +cfg.data_name = data_name + +save_dir = os.path.join('./snapshots', cfg.data_name, cfg.experiment_name) + +meanface_indices, reverse_index1, reverse_index2, max_len = get_meanface(os.path.join('data', cfg.data_name, 'meanface.txt'), cfg.num_nb) + +if cfg.backbone == 'resnet18': + resnet18 = models.resnet18(pretrained=cfg.pretrained) + net = Pip_resnet18(resnet18, cfg.num_nb, num_lms=cfg.num_lms, input_size=cfg.input_size, net_stride=cfg.net_stride) +elif cfg.backbone == 'resnet50': + resnet50 = models.resnet50(pretrained=cfg.pretrained) + net = Pip_resnet50(resnet50, cfg.num_nb, num_lms=cfg.num_lms, input_size=cfg.input_size, net_stride=cfg.net_stride) +elif cfg.backbone == 'resnet101': + resnet101 = models.resnet101(pretrained=cfg.pretrained) + net = Pip_resnet101(resnet101, cfg.num_nb, num_lms=cfg.num_lms, input_size=cfg.input_size, net_stride=cfg.net_stride) +elif cfg.backbone == 'mobilenet_v2': + mbnet = models.mobilenet_v2(pretrained=cfg.pretrained) + net = Pip_mbnetv2(mbnet, cfg.num_nb, num_lms=cfg.num_lms, input_size=cfg.input_size, net_stride=cfg.net_stride) +elif cfg.backbone == 'mobilenet_v3': + mbnet = mobilenetv3_large() + if cfg.pretrained: + mbnet.load_state_dict(torch.load('lib/mobilenetv3-large-1cd25616.pth')) + net = Pip_mbnetv3(mbnet, cfg.num_nb, num_lms=cfg.num_lms, input_size=cfg.input_size, net_stride=cfg.net_stride) +else: + print('No such backbone!') + exit(0) + +if cfg.use_gpu: + device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") +else: + device = torch.device("cpu") +net = net.to(device) + +weight_file = os.path.join(save_dir, 'epoch%d.pth' % (cfg.num_epochs-1)) +state_dict = torch.load(weight_file, map_location=device) +net.load_state_dict(state_dict) + +normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406], + std=[0.229, 0.224, 0.225]) +preprocess = transforms.Compose([transforms.Resize((cfg.input_size, cfg.input_size)), transforms.ToTensor(), normalize]) + +def demo_image(image_file, net, preprocess, input_size, net_stride, num_nb, use_gpu, device): + detector = FaceBoxesDetector('FaceBoxes', 'FaceBoxesV2/weights/FaceBoxesV2.pth', use_gpu, device) + my_thresh = 0.6 + det_box_scale = 1.2 + + net.eval() + image = cv2.imread(image_file) + image_height, image_width, _ = image.shape + detections, _ = detector.detect(image, my_thresh, 1) + for i in range(len(detections)): + det_xmin = detections[i][2] + det_ymin = detections[i][3] + det_width = detections[i][4] + det_height = detections[i][5] + det_xmax = det_xmin + det_width - 1 + det_ymax = det_ymin + det_height - 1 + + det_xmin -= int(det_width * (det_box_scale-1)/2) + # remove a part of top area for alignment, see paper for details + det_ymin += int(det_height * (det_box_scale-1)/2) + det_xmax += int(det_width * (det_box_scale-1)/2) + det_ymax += int(det_height * (det_box_scale-1)/2) + det_xmin = max(det_xmin, 0) + det_ymin = max(det_ymin, 0) + det_xmax = min(det_xmax, image_width-1) + det_ymax = min(det_ymax, image_height-1) + det_width = det_xmax - det_xmin + 1 + det_height = det_ymax - det_ymin + 1 + cv2.rectangle(image, (det_xmin, det_ymin), (det_xmax, det_ymax), (0, 0, 255), 2) + det_crop = image[det_ymin:det_ymax, det_xmin:det_xmax, :] + det_crop = cv2.resize(det_crop, (input_size, input_size)) + inputs = Image.fromarray(det_crop[:,:,::-1].astype('uint8'), 'RGB') + inputs = preprocess(inputs).unsqueeze(0) + inputs = inputs.to(device) + lms_pred_x, lms_pred_y, lms_pred_nb_x, lms_pred_nb_y, outputs_cls, max_cls = forward_pip(net, inputs, preprocess, input_size, net_stride, num_nb) + lms_pred = torch.cat((lms_pred_x, lms_pred_y), dim=1).flatten() + tmp_nb_x = lms_pred_nb_x[reverse_index1, reverse_index2].view(cfg.num_lms, max_len) + tmp_nb_y = lms_pred_nb_y[reverse_index1, reverse_index2].view(cfg.num_lms, max_len) + tmp_x = torch.mean(torch.cat((lms_pred_x, tmp_nb_x), dim=1), dim=1).view(-1,1) + tmp_y = torch.mean(torch.cat((lms_pred_y, tmp_nb_y), dim=1), dim=1).view(-1,1) + lms_pred_merge = torch.cat((tmp_x, tmp_y), dim=1).flatten() + lms_pred = lms_pred.cpu().numpy() + lms_pred_merge = lms_pred_merge.cpu().numpy() + for i in range(cfg.num_lms): + x_pred = lms_pred_merge[i*2] * det_width + y_pred = lms_pred_merge[i*2+1] * det_height + cv2.circle(image, (int(x_pred)+det_xmin, int(y_pred)+det_ymin), 1, (0, 0, 255), 2) + #cv2.imwrite('images/1_out.jpg', image) + cv2.imshow('1', image) + cv2.waitKey(0) + + +demo_image(image_file, net, preprocess, cfg.input_size, cfg.net_stride, cfg.num_nb, cfg.use_gpu, device) diff --git a/src/pixel3dmm/preprocessing/PIPNet/lib/demo_video.py b/src/pixel3dmm/preprocessing/PIPNet/lib/demo_video.py new file mode 100644 index 0000000000000000000000000000000000000000..519e251c8ef084d630dc1521d70f84a1da919d32 --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/lib/demo_video.py @@ -0,0 +1,141 @@ +import cv2, os +import sys +sys.path.insert(0, 'FaceBoxesV2') +sys.path.insert(0, '..') +import numpy as np +import pickle +import importlib +from math import floor +from faceboxes_detector import * +import time + +import torch +import torch.nn as nn +import torch.nn.parallel +import torch.optim as optim +import torch.utils.data +import torch.nn.functional as F +import torchvision.transforms as transforms +import torchvision.datasets as datasets +import torchvision.models as models + +from networks import * +import data_utils +from functions import * + +if not len(sys.argv) == 3: + print('Format:') + print('python lib/demo_video.py config_file video_file') + exit(0) +experiment_name = sys.argv[1].split('/')[-1][:-3] +data_name = sys.argv[1].split('/')[-2] +config_path = '.experiments.{}.{}'.format(data_name, experiment_name) +video_file = sys.argv[2] + +my_config = importlib.import_module(config_path, package='PIPNet') +Config = getattr(my_config, 'Config') +cfg = Config() +cfg.experiment_name = experiment_name +cfg.data_name = data_name + +save_dir = os.path.join('./snapshots', cfg.data_name, cfg.experiment_name) + +meanface_indices, reverse_index1, reverse_index2, max_len = get_meanface(os.path.join('data', cfg.data_name, 'meanface.txt'), cfg.num_nb) + +if cfg.backbone == 'resnet18': + resnet18 = models.resnet18(pretrained=cfg.pretrained) + net = Pip_resnet18(resnet18, cfg.num_nb, num_lms=cfg.num_lms, input_size=cfg.input_size, net_stride=cfg.net_stride) +elif cfg.backbone == 'resnet50': + resnet50 = models.resnet50(pretrained=cfg.pretrained) + net = Pip_resnet50(resnet50, cfg.num_nb, num_lms=cfg.num_lms, input_size=cfg.input_size, net_stride=cfg.net_stride) +elif cfg.backbone == 'resnet101': + resnet101 = models.resnet101(pretrained=cfg.pretrained) + net = Pip_resnet101(resnet101, cfg.num_nb, num_lms=cfg.num_lms, input_size=cfg.input_size, net_stride=cfg.net_stride) +else: + print('No such backbone!') + exit(0) + +if cfg.use_gpu: + device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") +else: + device = torch.device("cpu") +net = net.to(device) + +weight_file = os.path.join(save_dir, 'epoch%d.pth' % (cfg.num_epochs-1)) +state_dict = torch.load(weight_file, map_location=device) +net.load_state_dict(state_dict) + +normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406], + std=[0.229, 0.224, 0.225]) +preprocess = transforms.Compose([transforms.Resize((cfg.input_size, cfg.input_size)), transforms.ToTensor(), normalize]) + +def demo_video(video_file, net, preprocess, input_size, net_stride, num_nb, use_gpu, device): + detector = FaceBoxesDetector('FaceBoxes', 'FaceBoxesV2/weights/FaceBoxesV2.pth', use_gpu, device) + my_thresh = 0.9 + det_box_scale = 1.2 + + net.eval() + if video_file == 'camera': + cap = cv2.VideoCapture(0) + else: + cap = cv2.VideoCapture(video_file) + if (cap.isOpened()== False): + print("Error opening video stream or file") + frame_width = int(cap.get(3)) + frame_height = int(cap.get(4)) + count = 0 + while(cap.isOpened()): + ret, frame = cap.read() + if ret == True: + detections, _ = detector.detect(frame, my_thresh, 1) + for i in range(len(detections)): + det_xmin = detections[i][2] + det_ymin = detections[i][3] + det_width = detections[i][4] + det_height = detections[i][5] + det_xmax = det_xmin + det_width - 1 + det_ymax = det_ymin + det_height - 1 + + det_xmin -= int(det_width * (det_box_scale-1)/2) + # remove a part of top area for alignment, see paper for details + det_ymin += int(det_height * (det_box_scale-1)/2) + det_xmax += int(det_width * (det_box_scale-1)/2) + det_ymax += int(det_height * (det_box_scale-1)/2) + det_xmin = max(det_xmin, 0) + det_ymin = max(det_ymin, 0) + det_xmax = min(det_xmax, frame_width-1) + det_ymax = min(det_ymax, frame_height-1) + det_width = det_xmax - det_xmin + 1 + det_height = det_ymax - det_ymin + 1 + cv2.rectangle(frame, (det_xmin, det_ymin), (det_xmax, det_ymax), (0, 0, 255), 2) + det_crop = frame[det_ymin:det_ymax, det_xmin:det_xmax, :] + det_crop = cv2.resize(det_crop, (input_size, input_size)) + inputs = Image.fromarray(det_crop[:,:,::-1].astype('uint8'), 'RGB') + inputs = preprocess(inputs).unsqueeze(0) + inputs = inputs.to(device) + lms_pred_x, lms_pred_y, lms_pred_nb_x, lms_pred_nb_y, outputs_cls, max_cls = forward_pip(net, inputs, preprocess, input_size, net_stride, num_nb) + lms_pred = torch.cat((lms_pred_x, lms_pred_y), dim=1).flatten() + tmp_nb_x = lms_pred_nb_x[reverse_index1, reverse_index2].view(cfg.num_lms, max_len) + tmp_nb_y = lms_pred_nb_y[reverse_index1, reverse_index2].view(cfg.num_lms, max_len) + tmp_x = torch.mean(torch.cat((lms_pred_x, tmp_nb_x), dim=1), dim=1).view(-1,1) + tmp_y = torch.mean(torch.cat((lms_pred_y, tmp_nb_y), dim=1), dim=1).view(-1,1) + lms_pred_merge = torch.cat((tmp_x, tmp_y), dim=1).flatten() + lms_pred = lms_pred.cpu().numpy() + lms_pred_merge = lms_pred_merge.cpu().numpy() + for i in range(cfg.num_lms): + x_pred = lms_pred_merge[i*2] * det_width + y_pred = lms_pred_merge[i*2+1] * det_height + cv2.circle(frame, (int(x_pred)+det_xmin, int(y_pred)+det_ymin), 1, (0, 0, 255), 2) + + count += 1 + #cv2.imwrite('video_out2/'+str(count)+'.jpg', frame) + cv2.imshow('1', frame) + if cv2.waitKey(1) & 0xFF == ord('q'): + break + else: + break + + cap.release() + cv2.destroyAllWindows() + +demo_video(video_file, net, preprocess, cfg.input_size, cfg.net_stride, cfg.num_nb, cfg.use_gpu, device) diff --git a/src/pixel3dmm/preprocessing/PIPNet/lib/functions.py b/src/pixel3dmm/preprocessing/PIPNet/lib/functions.py new file mode 100644 index 0000000000000000000000000000000000000000..6144d3a0977e159075e2f2522314e5f26ac5553d --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/lib/functions.py @@ -0,0 +1,210 @@ +import os, cv2 +import numpy as np +from PIL import Image, ImageFilter +import logging +import torch +import torch.nn as nn +import random +import time +from scipy.integrate import simps + + +def get_label(data_name, label_file, task_type=None): + label_path = os.path.join('data', data_name, label_file) + with open(label_path, 'r') as f: + labels = f.readlines() + labels = [x.strip().split() for x in labels] + if len(labels[0])==1: + return labels + + labels_new = [] + for label in labels: + image_name = label[0] + target = label[1:] + target = np.array([float(x) for x in target]) + if task_type is None: + labels_new.append([image_name, target]) + else: + labels_new.append([image_name, task_type, target]) + return labels_new + +def get_meanface(meanface_file, num_nb): + with open(meanface_file) as f: + meanface = f.readlines()[0] + + meanface = meanface.strip().split() + meanface = [float(x) for x in meanface] + meanface = np.array(meanface).reshape(-1, 2) + # each landmark predicts num_nb neighbors + meanface_indices = [] + for i in range(meanface.shape[0]): + pt = meanface[i,:] + dists = np.sum(np.power(pt-meanface, 2), axis=1) + indices = np.argsort(dists) + meanface_indices.append(indices[1:1+num_nb]) + + # each landmark predicted by X neighbors, X varies + meanface_indices_reversed = {} + for i in range(meanface.shape[0]): + meanface_indices_reversed[i] = [[],[]] + for i in range(meanface.shape[0]): + for j in range(num_nb): + meanface_indices_reversed[meanface_indices[i][j]][0].append(i) + meanface_indices_reversed[meanface_indices[i][j]][1].append(j) + + max_len = 0 + for i in range(meanface.shape[0]): + tmp_len = len(meanface_indices_reversed[i][0]) + if tmp_len > max_len: + max_len = tmp_len + + # tricks, make them have equal length for efficient computation + for i in range(meanface.shape[0]): + tmp_len = len(meanface_indices_reversed[i][0]) + meanface_indices_reversed[i][0] += meanface_indices_reversed[i][0]*10 + meanface_indices_reversed[i][1] += meanface_indices_reversed[i][1]*10 + meanface_indices_reversed[i][0] = meanface_indices_reversed[i][0][:max_len] + meanface_indices_reversed[i][1] = meanface_indices_reversed[i][1][:max_len] + + # make the indices 1-dim + reverse_index1 = [] + reverse_index2 = [] + for i in range(meanface.shape[0]): + reverse_index1 += meanface_indices_reversed[i][0] + reverse_index2 += meanface_indices_reversed[i][1] + return meanface_indices, reverse_index1, reverse_index2, max_len + +def compute_loss_pip(outputs_map, outputs_local_x, outputs_local_y, outputs_nb_x, outputs_nb_y, labels_map, labels_local_x, labels_local_y, labels_nb_x, labels_nb_y, criterion_cls, criterion_reg, num_nb): + + tmp_batch, tmp_channel, tmp_height, tmp_width = outputs_map.size() + labels_map = labels_map.view(tmp_batch*tmp_channel, -1) + labels_max_ids = torch.argmax(labels_map, 1) + labels_max_ids = labels_max_ids.view(-1, 1) + labels_max_ids_nb = labels_max_ids.repeat(1, num_nb).view(-1, 1) + + outputs_local_x = outputs_local_x.view(tmp_batch*tmp_channel, -1) + outputs_local_x_select = torch.gather(outputs_local_x, 1, labels_max_ids) + outputs_local_y = outputs_local_y.view(tmp_batch*tmp_channel, -1) + outputs_local_y_select = torch.gather(outputs_local_y, 1, labels_max_ids) + outputs_nb_x = outputs_nb_x.view(tmp_batch*num_nb*tmp_channel, -1) + outputs_nb_x_select = torch.gather(outputs_nb_x, 1, labels_max_ids_nb) + outputs_nb_y = outputs_nb_y.view(tmp_batch*num_nb*tmp_channel, -1) + outputs_nb_y_select = torch.gather(outputs_nb_y, 1, labels_max_ids_nb) + + labels_local_x = labels_local_x.view(tmp_batch*tmp_channel, -1) + labels_local_x_select = torch.gather(labels_local_x, 1, labels_max_ids) + labels_local_y = labels_local_y.view(tmp_batch*tmp_channel, -1) + labels_local_y_select = torch.gather(labels_local_y, 1, labels_max_ids) + labels_nb_x = labels_nb_x.view(tmp_batch*num_nb*tmp_channel, -1) + labels_nb_x_select = torch.gather(labels_nb_x, 1, labels_max_ids_nb) + labels_nb_y = labels_nb_y.view(tmp_batch*num_nb*tmp_channel, -1) + labels_nb_y_select = torch.gather(labels_nb_y, 1, labels_max_ids_nb) + + labels_map = labels_map.view(tmp_batch, tmp_channel, tmp_height, tmp_width) + loss_map = criterion_cls(outputs_map, labels_map) + loss_x = criterion_reg(outputs_local_x_select, labels_local_x_select) + loss_y = criterion_reg(outputs_local_y_select, labels_local_y_select) + loss_nb_x = criterion_reg(outputs_nb_x_select, labels_nb_x_select) + loss_nb_y = criterion_reg(outputs_nb_y_select, labels_nb_y_select) + return loss_map, loss_x, loss_y, loss_nb_x, loss_nb_y + +def train_model(det_head, net, train_loader, criterion_cls, criterion_reg, cls_loss_weight, reg_loss_weight, num_nb, optimizer, num_epochs, scheduler, save_dir, save_interval, device): + for epoch in range(num_epochs): + print('Epoch {}/{}'.format(epoch, num_epochs - 1)) + logging.info('Epoch {}/{}'.format(epoch, num_epochs - 1)) + print('-' * 10) + logging.info('-' * 10) + net.train() + epoch_loss = 0.0 + + for i, data in enumerate(train_loader): + if det_head == 'pip': + inputs, labels_map, labels_x, labels_y, labels_nb_x, labels_nb_y = data + inputs = inputs.to(device) + labels_map = labels_map.to(device) + labels_x = labels_x.to(device) + labels_y = labels_y.to(device) + labels_nb_x = labels_nb_x.to(device) + labels_nb_y = labels_nb_y.to(device) + outputs_map, outputs_x, outputs_y, outputs_nb_x, outputs_nb_y = net(inputs) + loss_map, loss_x, loss_y, loss_nb_x, loss_nb_y = compute_loss_pip(outputs_map, outputs_x, outputs_y, outputs_nb_x, outputs_nb_y, labels_map, labels_x, labels_y, labels_nb_x, labels_nb_y, criterion_cls, criterion_reg, num_nb) + loss = cls_loss_weight*loss_map + reg_loss_weight*loss_x + reg_loss_weight*loss_y + reg_loss_weight*loss_nb_x + reg_loss_weight*loss_nb_y + else: + print('No such head:', det_head) + exit(0) + + optimizer.zero_grad() + loss.backward() + optimizer.step() + if i%10 == 0: + if det_head == 'pip': + print('[Epoch {:d}/{:d}, Batch {:d}/{:d}] '.format( + epoch, num_epochs-1, i, len(train_loader)-1, loss.item(), cls_loss_weight*loss_map.item(), reg_loss_weight*loss_x.item(), reg_loss_weight*loss_y.item(), reg_loss_weight*loss_nb_x.item(), reg_loss_weight*loss_nb_y.item())) + logging.info('[Epoch {:d}/{:d}, Batch {:d}/{:d}] '.format( + epoch, num_epochs-1, i, len(train_loader)-1, loss.item(), cls_loss_weight*loss_map.item(), reg_loss_weight*loss_x.item(), reg_loss_weight*loss_y.item(), reg_loss_weight*loss_nb_x.item(), reg_loss_weight*loss_nb_y.item())) + else: + print('No such head:', det_head) + exit(0) + epoch_loss += loss.item() + epoch_loss /= len(train_loader) + if epoch%(save_interval-1) == 0 and epoch > 0: + filename = os.path.join(save_dir, 'epoch%d.pth' % epoch) + torch.save(net.state_dict(), filename) + print(filename, 'saved') + scheduler.step() + return net + +def forward_pip(net, inputs, preprocess, input_size, net_stride, num_nb): + net.eval() + with torch.no_grad(): + outputs_cls, outputs_x, outputs_y, outputs_nb_x, outputs_nb_y = net(inputs) + tmp_batch, tmp_channel, tmp_height, tmp_width = outputs_cls.size() + assert tmp_batch == 1 + + outputs_cls = outputs_cls.view(tmp_batch*tmp_channel, -1) + max_ids = torch.argmax(outputs_cls, 1) + max_cls = torch.max(outputs_cls, 1)[0] + max_ids = max_ids.view(-1, 1) + max_ids_nb = max_ids.repeat(1, num_nb).view(-1, 1) + + outputs_x = outputs_x.view(tmp_batch*tmp_channel, -1) + outputs_x_select = torch.gather(outputs_x, 1, max_ids) + outputs_x_select = outputs_x_select.squeeze(1) + outputs_y = outputs_y.view(tmp_batch*tmp_channel, -1) + outputs_y_select = torch.gather(outputs_y, 1, max_ids) + outputs_y_select = outputs_y_select.squeeze(1) + + outputs_nb_x = outputs_nb_x.view(tmp_batch*num_nb*tmp_channel, -1) + outputs_nb_x_select = torch.gather(outputs_nb_x, 1, max_ids_nb) + outputs_nb_x_select = outputs_nb_x_select.squeeze(1).view(-1, num_nb) + outputs_nb_y = outputs_nb_y.view(tmp_batch*num_nb*tmp_channel, -1) + outputs_nb_y_select = torch.gather(outputs_nb_y, 1, max_ids_nb) + outputs_nb_y_select = outputs_nb_y_select.squeeze(1).view(-1, num_nb) + + tmp_x = (max_ids%tmp_width).view(-1,1).float()+outputs_x_select.view(-1,1) + tmp_y = (max_ids//tmp_width).view(-1,1).float()+outputs_y_select.view(-1,1) + tmp_x /= 1.0 * input_size / net_stride + tmp_y /= 1.0 * input_size / net_stride + + tmp_nb_x = (max_ids%tmp_width).view(-1,1).float()+outputs_nb_x_select + tmp_nb_y = (max_ids//tmp_width).view(-1,1).float()+outputs_nb_y_select + tmp_nb_x = tmp_nb_x.view(-1, num_nb) + tmp_nb_y = tmp_nb_y.view(-1, num_nb) + tmp_nb_x /= 1.0 * input_size / net_stride + tmp_nb_y /= 1.0 * input_size / net_stride + + return tmp_x, tmp_y, tmp_nb_x, tmp_nb_y, outputs_cls, max_cls + +def compute_nme(lms_pred, lms_gt, norm): + lms_pred = lms_pred.reshape((-1, 2)) + lms_gt = lms_gt.reshape((-1, 2)) + nme = np.mean(np.linalg.norm(lms_pred - lms_gt, axis=1)) / norm + return nme + +def compute_fr_and_auc(nmes, thres=0.1, step=0.0001): + num_data = len(nmes) + xs = np.arange(0, thres + step, step) + ys = np.array([np.count_nonzero(nmes <= x) for x in xs]) / float(num_data) + fr = 1.0 - ys[-1] + auc = simps(ys, x=xs) / thres + return fr, auc diff --git a/src/pixel3dmm/preprocessing/PIPNet/lib/functions_gssl.py b/src/pixel3dmm/preprocessing/PIPNet/lib/functions_gssl.py new file mode 100644 index 0000000000000000000000000000000000000000..a89dcd936af289860ce3ca4c43339901debf05b3 --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/lib/functions_gssl.py @@ -0,0 +1,241 @@ +import os, cv2 +import numpy as np +from PIL import Image, ImageFilter +import logging +import torch +import torch.nn as nn +import random + +def get_label(data_name, label_file, task_type=None): + label_path = os.path.join('data', data_name, label_file) + with open(label_path, 'r') as f: + labels = f.readlines() + labels = [x.strip().split() for x in labels] + if len(labels[0])==1: + return labels + + labels_new = [] + for label in labels: + image_name = label[0] + target = label[1:] + target = np.array([float(x) for x in target]) + if task_type is None: + labels_new.append([image_name, target]) + else: + labels_new.append([image_name, task_type, target]) + return labels_new + +def get_meanface(meanface_file, num_nb): + with open(meanface_file) as f: + meanface = f.readlines()[0] + + meanface = meanface.strip().split() + meanface = [float(x) for x in meanface] + meanface = np.array(meanface).reshape(-1, 2) + # each landmark predicts num_nb neighbors + meanface_indices = [] + for i in range(meanface.shape[0]): + pt = meanface[i,:] + dists = np.sum(np.power(pt-meanface, 2), axis=1) + indices = np.argsort(dists) + meanface_indices.append(indices[1:1+num_nb]) + + # each landmark predicted by X neighbors, X varies + meanface_indices_reversed = {} + for i in range(meanface.shape[0]): + meanface_indices_reversed[i] = [[],[]] + for i in range(meanface.shape[0]): + for j in range(num_nb): + meanface_indices_reversed[meanface_indices[i][j]][0].append(i) + meanface_indices_reversed[meanface_indices[i][j]][1].append(j) + + max_len = 0 + for i in range(meanface.shape[0]): + tmp_len = len(meanface_indices_reversed[i][0]) + if tmp_len > max_len: + max_len = tmp_len + + # tricks, make them have equal length for efficient computation + for i in range(meanface.shape[0]): + tmp_len = len(meanface_indices_reversed[i][0]) + meanface_indices_reversed[i][0] += meanface_indices_reversed[i][0]*10 + meanface_indices_reversed[i][1] += meanface_indices_reversed[i][1]*10 + meanface_indices_reversed[i][0] = meanface_indices_reversed[i][0][:max_len] + meanface_indices_reversed[i][1] = meanface_indices_reversed[i][1][:max_len] + + # make the indices 1-dim + reverse_index1 = [] + reverse_index2 = [] + for i in range(meanface.shape[0]): + reverse_index1 += meanface_indices_reversed[i][0] + reverse_index2 += meanface_indices_reversed[i][1] + return meanface_indices, reverse_index1, reverse_index2, max_len + +def compute_loss_pip(outputs_map1, outputs_map2, outputs_map3, outputs_local_x, outputs_local_y, outputs_nb_x, outputs_nb_y, labels_map1, labels_map2, labels_map3, labels_local_x, labels_local_y, labels_nb_x, labels_nb_y, masks_map1, masks_map2, masks_map3, masks_local_x, masks_local_y, masks_nb_x, masks_nb_y, criterion_cls, criterion_reg, num_nb): + + tmp_batch, tmp_channel, tmp_height, tmp_width = outputs_map1.size() + labels_map1 = labels_map1.view(tmp_batch*tmp_channel, -1) + labels_max_ids = torch.argmax(labels_map1, 1) + labels_max_ids = labels_max_ids.view(-1, 1) + labels_max_ids_nb = labels_max_ids.repeat(1, num_nb).view(-1, 1) + + outputs_local_x = outputs_local_x.view(tmp_batch*tmp_channel, -1) + outputs_local_x_select = torch.gather(outputs_local_x, 1, labels_max_ids) + outputs_local_y = outputs_local_y.view(tmp_batch*tmp_channel, -1) + outputs_local_y_select = torch.gather(outputs_local_y, 1, labels_max_ids) + outputs_nb_x = outputs_nb_x.view(tmp_batch*num_nb*tmp_channel, -1) + outputs_nb_x_select = torch.gather(outputs_nb_x, 1, labels_max_ids_nb) + outputs_nb_y = outputs_nb_y.view(tmp_batch*num_nb*tmp_channel, -1) + outputs_nb_y_select = torch.gather(outputs_nb_y, 1, labels_max_ids_nb) + + labels_local_x = labels_local_x.view(tmp_batch*tmp_channel, -1) + labels_local_x_select = torch.gather(labels_local_x, 1, labels_max_ids) + labels_local_y = labels_local_y.view(tmp_batch*tmp_channel, -1) + labels_local_y_select = torch.gather(labels_local_y, 1, labels_max_ids) + labels_nb_x = labels_nb_x.view(tmp_batch*num_nb*tmp_channel, -1) + labels_nb_x_select = torch.gather(labels_nb_x, 1, labels_max_ids_nb) + labels_nb_y = labels_nb_y.view(tmp_batch*num_nb*tmp_channel, -1) + labels_nb_y_select = torch.gather(labels_nb_y, 1, labels_max_ids_nb) + + masks_local_x = masks_local_x.view(tmp_batch*tmp_channel, -1) + masks_local_x_select = torch.gather(masks_local_x, 1, labels_max_ids) + masks_local_y = masks_local_y.view(tmp_batch*tmp_channel, -1) + masks_local_y_select = torch.gather(masks_local_y, 1, labels_max_ids) + masks_nb_x = masks_nb_x.view(tmp_batch*num_nb*tmp_channel, -1) + masks_nb_x_select = torch.gather(masks_nb_x, 1, labels_max_ids_nb) + masks_nb_y = masks_nb_y.view(tmp_batch*num_nb*tmp_channel, -1) + masks_nb_y_select = torch.gather(masks_nb_y, 1, labels_max_ids_nb) + + ########################################## + outputs_map1 = outputs_map1.view(tmp_batch*tmp_channel, -1) + outputs_map2 = outputs_map2.view(tmp_batch*tmp_channel, -1) + outputs_map3 = outputs_map3.view(tmp_batch*tmp_channel, -1) + labels_map2 = labels_map2.view(tmp_batch*tmp_channel, -1) + labels_map3 = labels_map3.view(tmp_batch*tmp_channel, -1) + masks_map1 = masks_map1.view(tmp_batch*tmp_channel, -1) + masks_map2 = masks_map2.view(tmp_batch*tmp_channel, -1) + masks_map3 = masks_map3.view(tmp_batch*tmp_channel, -1) + outputs_map = torch.cat([outputs_map1, outputs_map2, outputs_map3], 1) + labels_map = torch.cat([labels_map1, labels_map2, labels_map3], 1) + masks_map = torch.cat([masks_map1, masks_map2, masks_map3], 1) + loss_map = criterion_cls(outputs_map*masks_map, labels_map*masks_map) + if not masks_map.sum() == 0: + loss_map /= masks_map.sum() + ########################################## + + loss_x = criterion_reg(outputs_local_x_select*masks_local_x_select, labels_local_x_select*masks_local_x_select) + if not masks_local_x_select.sum() == 0: + loss_x /= masks_local_x_select.sum() + loss_y = criterion_reg(outputs_local_y_select*masks_local_y_select, labels_local_y_select*masks_local_y_select) + if not masks_local_y_select.sum() == 0: + loss_y /= masks_local_y_select.sum() + loss_nb_x = criterion_reg(outputs_nb_x_select*masks_nb_x_select, labels_nb_x_select*masks_nb_x_select) + if not masks_nb_x_select.sum() == 0: + loss_nb_x /= masks_nb_x_select.sum() + loss_nb_y = criterion_reg(outputs_nb_y_select*masks_nb_y_select, labels_nb_y_select*masks_nb_y_select) + if not masks_nb_y_select.sum() == 0: + loss_nb_y /= masks_nb_y_select.sum() + return loss_map, loss_x, loss_y, loss_nb_x, loss_nb_y + +def train_model(det_head, net, train_loader, criterion_cls, criterion_reg, cls_loss_weight, reg_loss_weight, num_nb, optimizer, num_epochs, scheduler, save_dir, save_interval, device): + for epoch in range(num_epochs): + print('Epoch {}/{}'.format(epoch, num_epochs - 1)) + logging.info('Epoch {}/{}'.format(epoch, num_epochs - 1)) + print('-' * 10) + logging.info('-' * 10) + net.train() + epoch_loss = 0.0 + + for i, data in enumerate(train_loader): + if det_head == 'pip': + inputs, labels_map1, labels_map2, labels_map3, labels_x, labels_y, labels_nb_x, labels_nb_y, masks_map1, masks_map2, masks_map3, masks_x, masks_y, masks_nb_x, masks_nb_y = data + inputs = inputs.to(device) + labels_map1 = labels_map1.to(device) + labels_map2 = labels_map2.to(device) + labels_map3 = labels_map3.to(device) + labels_x = labels_x.to(device) + labels_y = labels_y.to(device) + labels_nb_x = labels_nb_x.to(device) + labels_nb_y = labels_nb_y.to(device) + masks_map1 = masks_map1.to(device) + masks_map2 = masks_map2.to(device) + masks_map3 = masks_map3.to(device) + masks_x = masks_x.to(device) + masks_y = masks_y.to(device) + masks_nb_x = masks_nb_x.to(device) + masks_nb_y = masks_nb_y.to(device) + outputs_map1, outputs_map2, outputs_map3, outputs_x, outputs_y, outputs_nb_x, outputs_nb_y = net(inputs) + loss_map, loss_x, loss_y, loss_nb_x, loss_nb_y = compute_loss_pip(outputs_map1, outputs_map2, outputs_map3, outputs_x, outputs_y, outputs_nb_x, outputs_nb_y, labels_map1, labels_map2, labels_map3, labels_x, labels_y, labels_nb_x, labels_nb_y, masks_map1, masks_map2, masks_map3, masks_x, masks_y, masks_nb_x, masks_nb_y, criterion_cls, criterion_reg, num_nb) + loss = cls_loss_weight*loss_map + reg_loss_weight*loss_x + reg_loss_weight*loss_y + reg_loss_weight*loss_nb_x + reg_loss_weight*loss_nb_y + else: + print('No such head:', det_head) + exit(0) + + optimizer.zero_grad() + loss.backward() + optimizer.step() + if i%10 == 0: + if det_head == 'pip': + print('[Epoch {:d}/{:d}, Batch {:d}/{:d}] '.format( + epoch, num_epochs-1, i, len(train_loader)-1, loss.item(), cls_loss_weight*loss_map.item(), reg_loss_weight*loss_x.item(), reg_loss_weight*loss_y.item(), reg_loss_weight*loss_nb_x.item(), reg_loss_weight*loss_nb_y.item())) + logging.info('[Epoch {:d}/{:d}, Batch {:d}/{:d}] '.format( + epoch, num_epochs-1, i, len(train_loader)-1, loss.item(), cls_loss_weight*loss_map.item(), reg_loss_weight*loss_x.item(), reg_loss_weight*loss_y.item(), reg_loss_weight*loss_nb_x.item(), reg_loss_weight*loss_nb_y.item())) + else: + print('No such head:', det_head) + exit(0) + epoch_loss += loss.item() + epoch_loss /= len(train_loader) + if epoch%(save_interval-1) == 0 and epoch > 0: + filename = os.path.join(save_dir, 'epoch%d.pth' % epoch) + torch.save(net.state_dict(), filename) + print(filename, 'saved') + scheduler.step() + return net + +def forward_pip(net, inputs, preprocess, input_size, net_stride, num_nb): + net.eval() + with torch.no_grad(): + outputs_cls1, outputs_cls2, outputs_cls3, outputs_x, outputs_y, outputs_nb_x, outputs_nb_y = net(inputs) + tmp_batch, tmp_channel, tmp_height, tmp_width = outputs_cls1.size() + assert tmp_batch == 1 + + outputs_cls1 = outputs_cls1.view(tmp_batch*tmp_channel, -1) + max_ids = torch.argmax(outputs_cls1, 1) + max_cls = torch.max(outputs_cls1, 1)[0] + max_ids = max_ids.view(-1, 1) + max_ids_nb = max_ids.repeat(1, num_nb).view(-1, 1) + + outputs_x = outputs_x.view(tmp_batch*tmp_channel, -1) + outputs_x_select = torch.gather(outputs_x, 1, max_ids) + outputs_x_select = outputs_x_select.squeeze(1) + outputs_y = outputs_y.view(tmp_batch*tmp_channel, -1) + outputs_y_select = torch.gather(outputs_y, 1, max_ids) + outputs_y_select = outputs_y_select.squeeze(1) + + outputs_nb_x = outputs_nb_x.view(tmp_batch*num_nb*tmp_channel, -1) + outputs_nb_x_select = torch.gather(outputs_nb_x, 1, max_ids_nb) + outputs_nb_x_select = outputs_nb_x_select.squeeze(1).view(-1, num_nb) + outputs_nb_y = outputs_nb_y.view(tmp_batch*num_nb*tmp_channel, -1) + outputs_nb_y_select = torch.gather(outputs_nb_y, 1, max_ids_nb) + outputs_nb_y_select = outputs_nb_y_select.squeeze(1).view(-1, num_nb) + + tmp_x = (max_ids%tmp_width).view(-1,1).float()+outputs_x_select.view(-1,1) + tmp_y = (max_ids//tmp_width).view(-1,1).float()+outputs_y_select.view(-1,1) + tmp_x /= 1.0 * input_size / net_stride + tmp_y /= 1.0 * input_size / net_stride + + tmp_nb_x = (max_ids%tmp_width).view(-1,1).float()+outputs_nb_x_select + tmp_nb_y = (max_ids//tmp_width).view(-1,1).float()+outputs_nb_y_select + tmp_nb_x = tmp_nb_x.view(-1, num_nb) + tmp_nb_y = tmp_nb_y.view(-1, num_nb) + tmp_nb_x /= 1.0 * input_size / net_stride + tmp_nb_y /= 1.0 * input_size / net_stride + + return tmp_x, tmp_y, tmp_nb_x, tmp_nb_y, [outputs_cls1, outputs_cls2, outputs_cls3], max_cls + +def compute_nme(lms_pred, lms_gt, norm): + lms_pred = lms_pred.reshape((-1, 2)) + lms_gt = lms_gt.reshape((-1, 2)) + nme = np.mean(np.linalg.norm(lms_pred - lms_gt, axis=1)) / norm + return nme + diff --git a/src/pixel3dmm/preprocessing/PIPNet/lib/mobilenetv3-large-1cd25616.pth b/src/pixel3dmm/preprocessing/PIPNet/lib/mobilenetv3-large-1cd25616.pth new file mode 100644 index 0000000000000000000000000000000000000000..a77d9a7650a73e0a33e0fe5e819796033485d6d6 --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/lib/mobilenetv3-large-1cd25616.pth @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1cd25616db4b6481677fcbe5f6932520894cb34860ed86f7080f03eedf937b11 +size 22077746 diff --git a/src/pixel3dmm/preprocessing/PIPNet/lib/mobilenetv3.py b/src/pixel3dmm/preprocessing/PIPNet/lib/mobilenetv3.py new file mode 100644 index 0000000000000000000000000000000000000000..7297df7eb7773863b83c4b2de999ecfdb9e5c507 --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/lib/mobilenetv3.py @@ -0,0 +1,233 @@ +""" +Creates a MobileNetV3 Model as defined in: +Andrew Howard, Mark Sandler, Grace Chu, Liang-Chieh Chen, Bo Chen, Mingxing Tan, Weijun Wang, Yukun Zhu, Ruoming Pang, Vijay Vasudevan, Quoc V. Le, Hartwig Adam. (2019). +Searching for MobileNetV3 +arXiv preprint arXiv:1905.02244. +""" + +import torch +import torch.nn as nn +import math + + +__all__ = ['mobilenetv3_large', 'mobilenetv3_small'] + + +def _make_divisible(v, divisor, min_value=None): + """ + This function is taken from the original tf repo. + It ensures that all layers have a channel number that is divisible by 8 + It can be seen here: + https://github.com/tensorflow/models/blob/master/research/slim/nets/mobilenet/mobilenet.py + :param v: + :param divisor: + :param min_value: + :return: + """ + if min_value is None: + min_value = divisor + new_v = max(min_value, int(v + divisor / 2) // divisor * divisor) + # Make sure that round down does not go down by more than 10%. + if new_v < 0.9 * v: + new_v += divisor + return new_v + + +class h_sigmoid(nn.Module): + def __init__(self, inplace=True): + super(h_sigmoid, self).__init__() + self.relu = nn.ReLU6(inplace=inplace) + + def forward(self, x): + return self.relu(x + 3) / 6 + + +class h_swish(nn.Module): + def __init__(self, inplace=True): + super(h_swish, self).__init__() + self.sigmoid = h_sigmoid(inplace=inplace) + + def forward(self, x): + return x * self.sigmoid(x) + + +class SELayer(nn.Module): + def __init__(self, channel, reduction=4): + super(SELayer, self).__init__() + self.avg_pool = nn.AdaptiveAvgPool2d(1) + self.fc = nn.Sequential( + nn.Linear(channel, _make_divisible(channel // reduction, 8)), + nn.ReLU(inplace=True), + nn.Linear(_make_divisible(channel // reduction, 8), channel), + h_sigmoid() + ) + + def forward(self, x): + b, c, _, _ = x.size() + y = self.avg_pool(x).view(b, c) + y = self.fc(y).view(b, c, 1, 1) + return x * y + + +def conv_3x3_bn(inp, oup, stride): + return nn.Sequential( + nn.Conv2d(inp, oup, 3, stride, 1, bias=False), + nn.BatchNorm2d(oup), + h_swish() + ) + + +def conv_1x1_bn(inp, oup): + return nn.Sequential( + nn.Conv2d(inp, oup, 1, 1, 0, bias=False), + nn.BatchNorm2d(oup), + h_swish() + ) + + +class InvertedResidual(nn.Module): + def __init__(self, inp, hidden_dim, oup, kernel_size, stride, use_se, use_hs): + super(InvertedResidual, self).__init__() + assert stride in [1, 2] + + self.identity = stride == 1 and inp == oup + + if inp == hidden_dim: + self.conv = nn.Sequential( + # dw + nn.Conv2d(hidden_dim, hidden_dim, kernel_size, stride, (kernel_size - 1) // 2, groups=hidden_dim, bias=False), + nn.BatchNorm2d(hidden_dim), + h_swish() if use_hs else nn.ReLU(inplace=True), + # Squeeze-and-Excite + SELayer(hidden_dim) if use_se else nn.Identity(), + # pw-linear + nn.Conv2d(hidden_dim, oup, 1, 1, 0, bias=False), + nn.BatchNorm2d(oup), + ) + else: + self.conv = nn.Sequential( + # pw + nn.Conv2d(inp, hidden_dim, 1, 1, 0, bias=False), + nn.BatchNorm2d(hidden_dim), + h_swish() if use_hs else nn.ReLU(inplace=True), + # dw + nn.Conv2d(hidden_dim, hidden_dim, kernel_size, stride, (kernel_size - 1) // 2, groups=hidden_dim, bias=False), + nn.BatchNorm2d(hidden_dim), + # Squeeze-and-Excite + SELayer(hidden_dim) if use_se else nn.Identity(), + h_swish() if use_hs else nn.ReLU(inplace=True), + # pw-linear + nn.Conv2d(hidden_dim, oup, 1, 1, 0, bias=False), + nn.BatchNorm2d(oup), + ) + + def forward(self, x): + if self.identity: + return x + self.conv(x) + else: + return self.conv(x) + + +class MobileNetV3(nn.Module): + def __init__(self, cfgs, mode, num_classes=1000, width_mult=1.): + super(MobileNetV3, self).__init__() + # setting of inverted residual blocks + self.cfgs = cfgs + assert mode in ['large', 'small'] + + # building first layer + input_channel = _make_divisible(16 * width_mult, 8) + layers = [conv_3x3_bn(3, input_channel, 2)] + # building inverted residual blocks + block = InvertedResidual + for k, t, c, use_se, use_hs, s in self.cfgs: + output_channel = _make_divisible(c * width_mult, 8) + exp_size = _make_divisible(input_channel * t, 8) + layers.append(block(input_channel, exp_size, output_channel, k, s, use_se, use_hs)) + input_channel = output_channel + self.features = nn.Sequential(*layers) + # building last several layers + self.conv = conv_1x1_bn(input_channel, exp_size) + self.avgpool = nn.AdaptiveAvgPool2d((1, 1)) + output_channel = {'large': 1280, 'small': 1024} + output_channel = _make_divisible(output_channel[mode] * width_mult, 8) if width_mult > 1.0 else output_channel[mode] + self.classifier = nn.Sequential( + nn.Linear(exp_size, output_channel), + h_swish(), + nn.Dropout(0.2), + nn.Linear(output_channel, num_classes), + ) + + self._initialize_weights() + + def forward(self, x): + x = self.features(x) + x = self.conv(x) + x = self.avgpool(x) + x = x.view(x.size(0), -1) + x = self.classifier(x) + return x + + def _initialize_weights(self): + for m in self.modules(): + if isinstance(m, nn.Conv2d): + n = m.kernel_size[0] * m.kernel_size[1] * m.out_channels + m.weight.data.normal_(0, math.sqrt(2. / n)) + if m.bias is not None: + m.bias.data.zero_() + elif isinstance(m, nn.BatchNorm2d): + m.weight.data.fill_(1) + m.bias.data.zero_() + elif isinstance(m, nn.Linear): + m.weight.data.normal_(0, 0.01) + m.bias.data.zero_() + + +def mobilenetv3_large(**kwargs): + """ + Constructs a MobileNetV3-Large model + """ + cfgs = [ + # k, t, c, SE, HS, s + [3, 1, 16, 0, 0, 1], + [3, 4, 24, 0, 0, 2], + [3, 3, 24, 0, 0, 1], + [5, 3, 40, 1, 0, 2], + [5, 3, 40, 1, 0, 1], + [5, 3, 40, 1, 0, 1], + [3, 6, 80, 0, 1, 2], + [3, 2.5, 80, 0, 1, 1], + [3, 2.3, 80, 0, 1, 1], + [3, 2.3, 80, 0, 1, 1], + [3, 6, 112, 1, 1, 1], + [3, 6, 112, 1, 1, 1], + [5, 6, 160, 1, 1, 2], + [5, 6, 160, 1, 1, 1], + [5, 6, 160, 1, 1, 1] + ] + return MobileNetV3(cfgs, mode='large', **kwargs) + + +def mobilenetv3_small(**kwargs): + """ + Constructs a MobileNetV3-Small model + """ + cfgs = [ + # k, t, c, SE, HS, s + [3, 1, 16, 1, 0, 2], + [3, 4.5, 24, 0, 0, 2], + [3, 3.67, 24, 0, 0, 1], + [5, 4, 40, 1, 1, 2], + [5, 6, 40, 1, 1, 1], + [5, 6, 40, 1, 1, 1], + [5, 3, 48, 1, 1, 1], + [5, 3, 48, 1, 1, 1], + [5, 6, 96, 1, 1, 2], + [5, 6, 96, 1, 1, 1], + [5, 6, 96, 1, 1, 1], + ] + + return MobileNetV3(cfgs, mode='small', **kwargs) + + + diff --git a/src/pixel3dmm/preprocessing/PIPNet/lib/networks.py b/src/pixel3dmm/preprocessing/PIPNet/lib/networks.py new file mode 100644 index 0000000000000000000000000000000000000000..bc05f039a5c3a14fe41a4f4bbef0342701a9ec28 --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/lib/networks.py @@ -0,0 +1,415 @@ +import torch +import torch.nn as nn +import torch.nn.functional as F +import torchvision.models as models +import numpy as np + +# net_stride output_size +# 128 2x2 +# 64 4x4 +# 32 8x8 +# pip regression, resnet101 +class Pip_resnet101(nn.Module): + def __init__(self, resnet, num_nb, num_lms=68, input_size=256, net_stride=32): + super(Pip_resnet101, self).__init__() + self.num_nb = num_nb + self.num_lms = num_lms + self.input_size = input_size + self.net_stride = net_stride + self.conv1 = resnet.conv1 + self.bn1 = resnet.bn1 + self.maxpool = resnet.maxpool + self.sigmoid = nn.Sigmoid() + self.layer1 = resnet.layer1 + self.layer2 = resnet.layer2 + self.layer3 = resnet.layer3 + self.layer4 = resnet.layer4 + if self.net_stride == 128: + self.layer5 = nn.Conv2d(2048, 512, kernel_size=3, stride=2, padding=1) + self.bn5 = nn.BatchNorm2d(512) + self.layer6 = nn.Conv2d(512, 512, kernel_size=3, stride=2, padding=1) + self.bn6 = nn.BatchNorm2d(512) + # init + nn.init.normal_(self.layer5.weight, std=0.001) + if self.layer5.bias is not None: + nn.init.constant_(self.layer5.bias, 0) + nn.init.constant_(self.bn5.weight, 1) + nn.init.constant_(self.bn5.bias, 0) + + nn.init.normal_(self.layer6.weight, std=0.001) + if self.layer6.bias is not None: + nn.init.constant_(self.layer6.bias, 0) + nn.init.constant_(self.bn6.weight, 1) + nn.init.constant_(self.bn6.bias, 0) + elif self.net_stride == 64: + self.layer5 = nn.Conv2d(2048, 512, kernel_size=3, stride=2, padding=1) + self.bn5 = nn.BatchNorm2d(512) + # init + nn.init.normal_(self.layer5.weight, std=0.001) + if self.layer5.bias is not None: + nn.init.constant_(self.layer5.bias, 0) + nn.init.constant_(self.bn5.weight, 1) + nn.init.constant_(self.bn5.bias, 0) + elif self.net_stride == 32: + pass + else: + print('No such net_stride!') + exit(0) + + self.cls_layer = nn.Conv2d(2048, num_lms, kernel_size=1, stride=1, padding=0) + self.x_layer = nn.Conv2d(2048, num_lms, kernel_size=1, stride=1, padding=0) + self.y_layer = nn.Conv2d(2048, num_lms, kernel_size=1, stride=1, padding=0) + self.nb_x_layer = nn.Conv2d(2048, num_nb*num_lms, kernel_size=1, stride=1, padding=0) + self.nb_y_layer = nn.Conv2d(2048, num_nb*num_lms, kernel_size=1, stride=1, padding=0) + + nn.init.normal_(self.cls_layer.weight, std=0.001) + if self.cls_layer.bias is not None: + nn.init.constant_(self.cls_layer.bias, 0) + + nn.init.normal_(self.x_layer.weight, std=0.001) + if self.x_layer.bias is not None: + nn.init.constant_(self.x_layer.bias, 0) + + nn.init.normal_(self.y_layer.weight, std=0.001) + if self.y_layer.bias is not None: + nn.init.constant_(self.y_layer.bias, 0) + + nn.init.normal_(self.nb_x_layer.weight, std=0.001) + if self.nb_x_layer.bias is not None: + nn.init.constant_(self.nb_x_layer.bias, 0) + + nn.init.normal_(self.nb_y_layer.weight, std=0.001) + if self.nb_y_layer.bias is not None: + nn.init.constant_(self.nb_y_layer.bias, 0) + + def forward(self, x): + x = self.conv1(x) + x = self.bn1(x) + x = F.relu(x) + x = self.maxpool(x) + x = self.layer1(x) + x = self.layer2(x) + x = self.layer3(x) + x = self.layer4(x) + if self.net_stride == 128: + x = F.relu(self.bn5(self.layer5(x))) + x = F.relu(self.bn6(self.layer6(x))) + elif self.net_stride == 64: + x = F.relu(self.bn5(self.layer5(x))) + else: + pass + x1 = self.cls_layer(x) + x2 = self.x_layer(x) + x3 = self.y_layer(x) + x4 = self.nb_x_layer(x) + x5 = self.nb_y_layer(x) + return x1, x2, x3, x4, x5 + +# net_stride output_size +# 128 2x2 +# 64 4x4 +# 32 8x8 +# pip regression, resnet50 +class Pip_resnet50(nn.Module): + def __init__(self, resnet, num_nb, num_lms=68, input_size=256, net_stride=32): + super(Pip_resnet50, self).__init__() + self.num_nb = num_nb + self.num_lms = num_lms + self.input_size = input_size + self.net_stride = net_stride + self.conv1 = resnet.conv1 + self.bn1 = resnet.bn1 + self.maxpool = resnet.maxpool + self.sigmoid = nn.Sigmoid() + self.layer1 = resnet.layer1 + self.layer2 = resnet.layer2 + self.layer3 = resnet.layer3 + self.layer4 = resnet.layer4 + if self.net_stride == 128: + self.layer5 = nn.Conv2d(2048, 512, kernel_size=3, stride=2, padding=1) + self.bn5 = nn.BatchNorm2d(512) + self.layer6 = nn.Conv2d(512, 512, kernel_size=3, stride=2, padding=1) + self.bn6 = nn.BatchNorm2d(512) + # init + nn.init.normal_(self.layer5.weight, std=0.001) + if self.layer5.bias is not None: + nn.init.constant_(self.layer5.bias, 0) + nn.init.constant_(self.bn5.weight, 1) + nn.init.constant_(self.bn5.bias, 0) + + nn.init.normal_(self.layer6.weight, std=0.001) + if self.layer6.bias is not None: + nn.init.constant_(self.layer6.bias, 0) + nn.init.constant_(self.bn6.weight, 1) + nn.init.constant_(self.bn6.bias, 0) + elif self.net_stride == 64: + self.layer5 = nn.Conv2d(2048, 512, kernel_size=3, stride=2, padding=1) + self.bn5 = nn.BatchNorm2d(512) + # init + nn.init.normal_(self.layer5.weight, std=0.001) + if self.layer5.bias is not None: + nn.init.constant_(self.layer5.bias, 0) + nn.init.constant_(self.bn5.weight, 1) + nn.init.constant_(self.bn5.bias, 0) + elif self.net_stride == 32: + pass + else: + print('No such net_stride!') + exit(0) + + self.cls_layer = nn.Conv2d(2048, num_lms, kernel_size=1, stride=1, padding=0) + self.x_layer = nn.Conv2d(2048, num_lms, kernel_size=1, stride=1, padding=0) + self.y_layer = nn.Conv2d(2048, num_lms, kernel_size=1, stride=1, padding=0) + self.nb_x_layer = nn.Conv2d(2048, num_nb*num_lms, kernel_size=1, stride=1, padding=0) + self.nb_y_layer = nn.Conv2d(2048, num_nb*num_lms, kernel_size=1, stride=1, padding=0) + + nn.init.normal_(self.cls_layer.weight, std=0.001) + if self.cls_layer.bias is not None: + nn.init.constant_(self.cls_layer.bias, 0) + + nn.init.normal_(self.x_layer.weight, std=0.001) + if self.x_layer.bias is not None: + nn.init.constant_(self.x_layer.bias, 0) + + nn.init.normal_(self.y_layer.weight, std=0.001) + if self.y_layer.bias is not None: + nn.init.constant_(self.y_layer.bias, 0) + + nn.init.normal_(self.nb_x_layer.weight, std=0.001) + if self.nb_x_layer.bias is not None: + nn.init.constant_(self.nb_x_layer.bias, 0) + + nn.init.normal_(self.nb_y_layer.weight, std=0.001) + if self.nb_y_layer.bias is not None: + nn.init.constant_(self.nb_y_layer.bias, 0) + + def forward(self, x): + x = self.conv1(x) + x = self.bn1(x) + x = F.relu(x) + x = self.maxpool(x) + x = self.layer1(x) + x = self.layer2(x) + x = self.layer3(x) + x = self.layer4(x) + if self.net_stride == 128: + x = F.relu(self.bn5(self.layer5(x))) + x = F.relu(self.bn6(self.layer6(x))) + elif self.net_stride == 64: + x = F.relu(self.bn5(self.layer5(x))) + else: + pass + x1 = self.cls_layer(x) + x2 = self.x_layer(x) + x3 = self.y_layer(x) + x4 = self.nb_x_layer(x) + x5 = self.nb_y_layer(x) + return x1, x2, x3, x4, x5 + +# net_stride output_size +# 128 2x2 +# 64 4x4 +# 32 8x8 +# pip regression, resnet18 +class Pip_resnet18(nn.Module): + def __init__(self, resnet, num_nb, num_lms=68, input_size=256, net_stride=32): + super(Pip_resnet18, self).__init__() + self.num_nb = num_nb + self.num_lms = num_lms + self.input_size = input_size + self.net_stride = net_stride + self.conv1 = resnet.conv1 + self.bn1 = resnet.bn1 + self.maxpool = resnet.maxpool + self.sigmoid = nn.Sigmoid() + self.layer1 = resnet.layer1 + self.layer2 = resnet.layer2 + self.layer3 = resnet.layer3 + self.layer4 = resnet.layer4 + if self.net_stride == 128: + self.layer5 = nn.Conv2d(512, 512, kernel_size=3, stride=2, padding=1) + self.bn5 = nn.BatchNorm2d(512) + self.layer6 = nn.Conv2d(512, 512, kernel_size=3, stride=2, padding=1) + self.bn6 = nn.BatchNorm2d(512) + # init + nn.init.normal_(self.layer5.weight, std=0.001) + if self.layer5.bias is not None: + nn.init.constant_(self.layer5.bias, 0) + nn.init.constant_(self.bn5.weight, 1) + nn.init.constant_(self.bn5.bias, 0) + + nn.init.normal_(self.layer6.weight, std=0.001) + if self.layer6.bias is not None: + nn.init.constant_(self.layer6.bias, 0) + nn.init.constant_(self.bn6.weight, 1) + nn.init.constant_(self.bn6.bias, 0) + elif self.net_stride == 64: + self.layer5 = nn.Conv2d(512, 512, kernel_size=3, stride=2, padding=1) + self.bn5 = nn.BatchNorm2d(512) + # init + nn.init.normal_(self.layer5.weight, std=0.001) + if self.layer5.bias is not None: + nn.init.constant_(self.layer5.bias, 0) + nn.init.constant_(self.bn5.weight, 1) + nn.init.constant_(self.bn5.bias, 0) + elif self.net_stride == 32: + pass + elif self.net_stride == 16: + self.deconv1 = nn.ConvTranspose2d(512, 512, kernel_size=4, stride=2, padding=1, bias=False) + self.bn_deconv1 = nn.BatchNorm2d(512) + nn.init.normal_(self.deconv1.weight, std=0.001) + if self.deconv1.bias is not None: + nn.init.constant_(self.deconv1.bias, 0) + nn.init.constant_(self.bn_deconv1.weight, 1) + nn.init.constant_(self.bn_deconv1.bias, 0) + else: + print('No such net_stride!') + exit(0) + + self.cls_layer = nn.Conv2d(512, num_lms, kernel_size=1, stride=1, padding=0) + self.x_layer = nn.Conv2d(512, num_lms, kernel_size=1, stride=1, padding=0) + self.y_layer = nn.Conv2d(512, num_lms, kernel_size=1, stride=1, padding=0) + self.nb_x_layer = nn.Conv2d(512, num_nb*num_lms, kernel_size=1, stride=1, padding=0) + self.nb_y_layer = nn.Conv2d(512, num_nb*num_lms, kernel_size=1, stride=1, padding=0) + + nn.init.normal_(self.cls_layer.weight, std=0.001) + if self.cls_layer.bias is not None: + nn.init.constant_(self.cls_layer.bias, 0) + + nn.init.normal_(self.x_layer.weight, std=0.001) + if self.x_layer.bias is not None: + nn.init.constant_(self.x_layer.bias, 0) + + nn.init.normal_(self.y_layer.weight, std=0.001) + if self.y_layer.bias is not None: + nn.init.constant_(self.y_layer.bias, 0) + + nn.init.normal_(self.nb_x_layer.weight, std=0.001) + if self.nb_x_layer.bias is not None: + nn.init.constant_(self.nb_x_layer.bias, 0) + + nn.init.normal_(self.nb_y_layer.weight, std=0.001) + if self.nb_y_layer.bias is not None: + nn.init.constant_(self.nb_y_layer.bias, 0) + + def forward(self, x): + x = self.conv1(x) + x = self.bn1(x) + x = F.relu(x) + x = self.maxpool(x) + x = self.layer1(x) + x = self.layer2(x) + x = self.layer3(x) + x = self.layer4(x) + if self.net_stride == 128: + x = F.relu(self.bn5(self.layer5(x))) + x = F.relu(self.bn6(self.layer6(x))) + elif self.net_stride == 64: + x = F.relu(self.bn5(self.layer5(x))) + elif self.net_stride == 16: + x = F.relu(self.bn_deconv1(self.deconv1(x))) + else: + pass + x1 = self.cls_layer(x) + x2 = self.x_layer(x) + x3 = self.y_layer(x) + x4 = self.nb_x_layer(x) + x5 = self.nb_y_layer(x) + return x1, x2, x3, x4, x5 + +class Pip_mbnetv2(nn.Module): + def __init__(self, mbnet, num_nb, num_lms=68, input_size=256, net_stride=32): + super(Pip_mbnetv2, self).__init__() + self.num_nb = num_nb + self.num_lms = num_lms + self.input_size = input_size + self.net_stride = net_stride + self.features = mbnet.features + self.sigmoid = nn.Sigmoid() + + self.cls_layer = nn.Conv2d(1280, num_lms, kernel_size=1, stride=1, padding=0) + self.x_layer = nn.Conv2d(1280, num_lms, kernel_size=1, stride=1, padding=0) + self.y_layer = nn.Conv2d(1280, num_lms, kernel_size=1, stride=1, padding=0) + self.nb_x_layer = nn.Conv2d(1280, num_nb*num_lms, kernel_size=1, stride=1, padding=0) + self.nb_y_layer = nn.Conv2d(1280, num_nb*num_lms, kernel_size=1, stride=1, padding=0) + + nn.init.normal_(self.cls_layer.weight, std=0.001) + if self.cls_layer.bias is not None: + nn.init.constant_(self.cls_layer.bias, 0) + + nn.init.normal_(self.x_layer.weight, std=0.001) + if self.x_layer.bias is not None: + nn.init.constant_(self.x_layer.bias, 0) + + nn.init.normal_(self.y_layer.weight, std=0.001) + if self.y_layer.bias is not None: + nn.init.constant_(self.y_layer.bias, 0) + + nn.init.normal_(self.nb_x_layer.weight, std=0.001) + if self.nb_x_layer.bias is not None: + nn.init.constant_(self.nb_x_layer.bias, 0) + + nn.init.normal_(self.nb_y_layer.weight, std=0.001) + if self.nb_y_layer.bias is not None: + nn.init.constant_(self.nb_y_layer.bias, 0) + + def forward(self, x): + x = self.features(x) + x1 = self.cls_layer(x) + x2 = self.x_layer(x) + x3 = self.y_layer(x) + x4 = self.nb_x_layer(x) + x5 = self.nb_y_layer(x) + return x1, x2, x3, x4, x5 + +class Pip_mbnetv3(nn.Module): + def __init__(self, mbnet, num_nb, num_lms=68, input_size=256, net_stride=32): + super(Pip_mbnetv3, self).__init__() + self.num_nb = num_nb + self.num_lms = num_lms + self.input_size = input_size + self.net_stride = net_stride + self.features = mbnet.features + self.conv = mbnet.conv + self.sigmoid = nn.Sigmoid() + + self.cls_layer = nn.Conv2d(960, num_lms, kernel_size=1, stride=1, padding=0) + self.x_layer = nn.Conv2d(960, num_lms, kernel_size=1, stride=1, padding=0) + self.y_layer = nn.Conv2d(960, num_lms, kernel_size=1, stride=1, padding=0) + self.nb_x_layer = nn.Conv2d(960, num_nb*num_lms, kernel_size=1, stride=1, padding=0) + self.nb_y_layer = nn.Conv2d(960, num_nb*num_lms, kernel_size=1, stride=1, padding=0) + + nn.init.normal_(self.cls_layer.weight, std=0.001) + if self.cls_layer.bias is not None: + nn.init.constant_(self.cls_layer.bias, 0) + + nn.init.normal_(self.x_layer.weight, std=0.001) + if self.x_layer.bias is not None: + nn.init.constant_(self.x_layer.bias, 0) + + nn.init.normal_(self.y_layer.weight, std=0.001) + if self.y_layer.bias is not None: + nn.init.constant_(self.y_layer.bias, 0) + + nn.init.normal_(self.nb_x_layer.weight, std=0.001) + if self.nb_x_layer.bias is not None: + nn.init.constant_(self.nb_x_layer.bias, 0) + + nn.init.normal_(self.nb_y_layer.weight, std=0.001) + if self.nb_y_layer.bias is not None: + nn.init.constant_(self.nb_y_layer.bias, 0) + + def forward(self, x): + x = self.features(x) + x = self.conv(x) + x1 = self.cls_layer(x) + x2 = self.x_layer(x) + x3 = self.y_layer(x) + x4 = self.nb_x_layer(x) + x5 = self.nb_y_layer(x) + return x1, x2, x3, x4, x5 + + +if __name__ == '__main__': + pass + diff --git a/src/pixel3dmm/preprocessing/PIPNet/lib/networks_gssl.py b/src/pixel3dmm/preprocessing/PIPNet/lib/networks_gssl.py new file mode 100644 index 0000000000000000000000000000000000000000..405f5d8e328afb4f0b735a7b8d3a37cf63ad72e8 --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/lib/networks_gssl.py @@ -0,0 +1,80 @@ +import torch +import torch.nn as nn +import torch.nn.functional as F +import torchvision.models as models +import numpy as np +import time + +# net_stride output_size +# 128 2x2 +# 64 4x4 +# 32 8x8 +# pip regression, resnet18, for GSSL +class Pip_resnet18(nn.Module): + def __init__(self, resnet, num_nb, num_lms=68, input_size=256, net_stride=32): + super(Pip_resnet18, self).__init__() + self.num_nb = num_nb + self.num_lms = num_lms + self.input_size = input_size + self.net_stride = net_stride + self.conv1 = resnet.conv1 + self.bn1 = resnet.bn1 + self.maxpool = resnet.maxpool + self.sigmoid = nn.Sigmoid() + self.layer1 = resnet.layer1 + self.layer2 = resnet.layer2 + self.layer3 = resnet.layer3 + self.layer4 = resnet.layer4 + + self.my_maxpool = nn.MaxPool2d(kernel_size=2, stride=2, padding=0) + + self.cls_layer = nn.Conv2d(512, num_lms, kernel_size=1, stride=1, padding=0) + self.x_layer = nn.Conv2d(512, num_lms, kernel_size=1, stride=1, padding=0) + self.y_layer = nn.Conv2d(512, num_lms, kernel_size=1, stride=1, padding=0) + self.nb_x_layer = nn.Conv2d(512, num_nb*num_lms, kernel_size=1, stride=1, padding=0) + self.nb_y_layer = nn.Conv2d(512, num_nb*num_lms, kernel_size=1, stride=1, padding=0) + + # init + nn.init.normal_(self.cls_layer.weight, std=0.001) + if self.cls_layer.bias is not None: + nn.init.constant_(self.cls_layer.bias, 0) + + nn.init.normal_(self.x_layer.weight, std=0.001) + if self.x_layer.bias is not None: + nn.init.constant_(self.x_layer.bias, 0) + + nn.init.normal_(self.y_layer.weight, std=0.001) + if self.y_layer.bias is not None: + nn.init.constant_(self.y_layer.bias, 0) + + nn.init.normal_(self.nb_x_layer.weight, std=0.001) + if self.nb_x_layer.bias is not None: + nn.init.constant_(self.nb_x_layer.bias, 0) + + nn.init.normal_(self.nb_y_layer.weight, std=0.001) + if self.nb_y_layer.bias is not None: + nn.init.constant_(self.nb_y_layer.bias, 0) + + def forward(self, x): + x = self.conv1(x) + x = self.bn1(x) + x = F.relu(x) + x = self.maxpool(x) + x = self.layer1(x) + x = self.layer2(x) + x = self.layer3(x) + x = self.layer4(x) + cls1 = self.cls_layer(x) + offset_x = self.x_layer(x) + offset_y = self.y_layer(x) + nb_x = self.nb_x_layer(x) + nb_y = self.nb_y_layer(x) + x = self.my_maxpool(x) + cls2 = self.cls_layer(x) + x = self.my_maxpool(x) + cls3 = self.cls_layer(x) + return cls1, cls2, cls3, offset_x, offset_y, nb_x, nb_y + +if __name__ == '__main__': + pass + diff --git a/src/pixel3dmm/preprocessing/PIPNet/lib/preprocess.py b/src/pixel3dmm/preprocessing/PIPNet/lib/preprocess.py new file mode 100644 index 0000000000000000000000000000000000000000..72fba2897c8e6e8acf3f539ed724d3b6cb58874a --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/lib/preprocess.py @@ -0,0 +1,559 @@ +import os, cv2 +import hdf5storage +import numpy as np +import sys + +def process_300w(root_folder, folder_name, image_name, label_name, target_size): + image_path = os.path.join(root_folder, folder_name, image_name) + label_path = os.path.join(root_folder, folder_name, label_name) + + with open(label_path, 'r') as ff: + anno = ff.readlines()[3:-1] + anno = [x.strip().split() for x in anno] + anno = [[int(float(x[0])), int(float(x[1]))] for x in anno] + image = cv2.imread(image_path) + image_height, image_width, _ = image.shape + anno_x = [x[0] for x in anno] + anno_y = [x[1] for x in anno] + bbox_xmin = min(anno_x) + bbox_ymin = min(anno_y) + bbox_xmax = max(anno_x) + bbox_ymax = max(anno_y) + bbox_width = bbox_xmax - bbox_xmin + bbox_height = bbox_ymax - bbox_ymin + scale = 1.1 + bbox_xmin -= int((scale-1)/2*bbox_width) + bbox_ymin -= int((scale-1)/2*bbox_height) + bbox_width *= scale + bbox_height *= scale + bbox_width = int(bbox_width) + bbox_height = int(bbox_height) + bbox_xmin = max(bbox_xmin, 0) + bbox_ymin = max(bbox_ymin, 0) + bbox_width = min(bbox_width, image_width-bbox_xmin-1) + bbox_height = min(bbox_height, image_height-bbox_ymin-1) + anno = [[(x-bbox_xmin)/bbox_width, (y-bbox_ymin)/bbox_height] for x,y in anno] + + bbox_xmax = bbox_xmin + bbox_width + bbox_ymax = bbox_ymin + bbox_height + image_crop = image[bbox_ymin:bbox_ymax, bbox_xmin:bbox_xmax, :] + image_crop = cv2.resize(image_crop, (target_size, target_size)) + return image_crop, anno + +def process_cofw(image, bbox, anno, target_size): + image_height, image_width, _ = image.shape + anno_x = anno[:29] + anno_y = anno[29:58] + ################################ + xmin, ymin, width, height = bbox + xmax = xmin + width -1 + ymax = ymin + height -1 + ################################ + xmin = max(xmin, 0) + ymin = max(ymin, 0) + xmax = min(xmax, image_width-1) + ymax = min(ymax, image_height-1) + anno_x = (anno_x - xmin) / (xmax - xmin) + anno_y = (anno_y - ymin) / (ymax - ymin) + anno = np.concatenate([anno_x.reshape(-1,1), anno_y.reshape(-1,1)], axis=1) + anno = list(anno) + anno = [list(x) for x in anno] + image_crop = image[int(ymin):int(ymax), int(xmin):int(xmax), :] + image_crop = cv2.resize(image_crop, (target_size, target_size)) + return image_crop, anno + +def process_wflw(anno, target_size): + image_name = anno[-1] + image_path = os.path.join('..', 'data', 'WFLW', 'WFLW_images', image_name) + image = cv2.imread(image_path) + image_height, image_width, _ = image.shape + lms = anno[:196] + lms = [float(x) for x in lms] + lms_x = lms[0::2] + lms_y = lms[1::2] + lms_x = [x if x >=0 else 0 for x in lms_x] + lms_x = [x if x <=image_width else image_width for x in lms_x] + lms_y = [y if y >=0 else 0 for y in lms_y] + lms_y = [y if y <=image_height else image_height for y in lms_y] + lms = [[x,y] for x,y in zip(lms_x, lms_y)] + lms = [x for z in lms for x in z] + bbox = anno[196:200] + bbox = [float(x) for x in bbox] + attrs = anno[200:206] + attrs = np.array([int(x) for x in attrs]) + bbox_xmin, bbox_ymin, bbox_xmax, bbox_ymax = bbox + + width = bbox_xmax - bbox_xmin + height = bbox_ymax - bbox_ymin + scale = 1.2 + bbox_xmin -= width * (scale-1)/2 + bbox_ymin -= height * (scale-1)/2 + bbox_xmax += width * (scale-1)/2 + bbox_ymax += height * (scale-1)/2 + bbox_xmin = max(bbox_xmin, 0) + bbox_ymin = max(bbox_ymin, 0) + bbox_xmax = min(bbox_xmax, image_width-1) + bbox_ymax = min(bbox_ymax, image_height-1) + width = bbox_xmax - bbox_xmin + height = bbox_ymax - bbox_ymin + image_crop = image[int(bbox_ymin):int(bbox_ymax), int(bbox_xmin):int(bbox_xmax), :] + image_crop = cv2.resize(image_crop, (target_size, target_size)) + + tmp1 = [bbox_xmin, bbox_ymin]*98 + tmp1 = np.array(tmp1) + tmp2 = [width, height]*98 + tmp2 = np.array(tmp2) + lms = np.array(lms) - tmp1 + lms = lms / tmp2 + lms = lms.tolist() + lms = zip(lms[0::2], lms[1::2]) + return image_crop, list(lms) + +def process_aflw(root_folder, image_name, bbox, anno, target_size): + image = cv2.imread(os.path.join(root_folder, 'AFLW', 'flickr', image_name)) + image_height, image_width, _ = image.shape + anno_x = anno[:19] + anno_y = anno[19:] + anno_x = [x if x >=0 else 0 for x in anno_x] + anno_x = [x if x <=image_width else image_width for x in anno_x] + anno_y = [y if y >=0 else 0 for y in anno_y] + anno_y = [y if y <=image_height else image_height for y in anno_y] + anno_x_min = min(anno_x) + anno_x_max = max(anno_x) + anno_y_min = min(anno_y) + anno_y_max = max(anno_y) + xmin, xmax, ymin, ymax = bbox + + xmin = max(xmin, 0) + ymin = max(ymin, 0) + xmax = min(xmax, image_width-1) + ymax = min(ymax, image_height-1) + + image_crop = image[int(ymin):int(ymax), int(xmin):int(xmax), :] + image_crop = cv2.resize(image_crop, (target_size, target_size)) + + anno_x = (np.array(anno_x) - xmin) / (xmax - xmin) + anno_y = (np.array(anno_y) - ymin) / (ymax - ymin) + + anno = np.concatenate([anno_x.reshape(-1,1), anno_y.reshape(-1,1)], axis=1).flatten() + anno = zip(anno[0::2], anno[1::2]) + return image_crop, anno + +def gen_meanface(root_folder, data_name): + with open(os.path.join(root_folder, data_name, 'train.txt'), 'r') as f: + annos = f.readlines() + annos = [x.strip().split()[1:] for x in annos] + annos = [[float(x) for x in anno] for anno in annos] + annos = np.array(annos) + meanface = np.mean(annos, axis=0) + meanface = meanface.tolist() + meanface = [str(x) for x in meanface] + + with open(os.path.join(root_folder, data_name, 'meanface.txt'), 'w') as f: + f.write(' '.join(meanface)) + +def convert_wflw(root_folder, data_name): + with open(os.path.join('../data/WFLW/test.txt'), 'r') as f: + annos = f.readlines() + annos = [x.strip().split() for x in annos] + annos_new = [] + for anno in annos: + annos_new.append([]) + # name + annos_new[-1].append(anno[0]) + anno = anno[1:] + # jaw + for i in range(17): + annos_new[-1].append(anno[i*2*2]) + annos_new[-1].append(anno[i*2*2+1]) + # left eyebrow + annos_new[-1].append(anno[33*2]) + annos_new[-1].append(anno[33*2+1]) + annos_new[-1].append(anno[34*2]) + annos_new[-1].append(str((float(anno[34*2+1])+float(anno[41*2+1]))/2)) + annos_new[-1].append(anno[35*2]) + annos_new[-1].append(str((float(anno[35*2+1])+float(anno[40*2+1]))/2)) + annos_new[-1].append(anno[36*2]) + annos_new[-1].append(str((float(anno[36*2+1])+float(anno[39*2+1]))/2)) + annos_new[-1].append(anno[37*2]) + annos_new[-1].append(str((float(anno[37*2+1])+float(anno[38*2+1]))/2)) + # right eyebrow + annos_new[-1].append(anno[42*2]) + annos_new[-1].append(str((float(anno[42*2+1])+float(anno[50*2+1]))/2)) + annos_new[-1].append(anno[43*2]) + annos_new[-1].append(str((float(anno[43*2+1])+float(anno[49*2+1]))/2)) + annos_new[-1].append(anno[44*2]) + annos_new[-1].append(str((float(anno[44*2+1])+float(anno[48*2+1]))/2)) + annos_new[-1].append(anno[45*2]) + annos_new[-1].append(str((float(anno[45*2+1])+float(anno[47*2+1]))/2)) + annos_new[-1].append(anno[46*2]) + annos_new[-1].append(anno[46*2+1]) + # nose + for i in range(51, 60): + annos_new[-1].append(anno[i*2]) + annos_new[-1].append(anno[i*2+1]) + # left eye + annos_new[-1].append(anno[60*2]) + annos_new[-1].append(anno[60*2+1]) + annos_new[-1].append(str(0.666*float(anno[61*2])+0.333*float(anno[62*2]))) + annos_new[-1].append(str(0.666*float(anno[61*2+1])+0.333*float(anno[62*2+1]))) + annos_new[-1].append(str(0.666*float(anno[63*2])+0.333*float(anno[62*2]))) + annos_new[-1].append(str(0.666*float(anno[63*2+1])+0.333*float(anno[62*2+1]))) + annos_new[-1].append(anno[64*2]) + annos_new[-1].append(anno[64*2+1]) + annos_new[-1].append(str(0.666*float(anno[65*2])+0.333*float(anno[66*2]))) + annos_new[-1].append(str(0.666*float(anno[65*2+1])+0.333*float(anno[66*2+1]))) + annos_new[-1].append(str(0.666*float(anno[67*2])+0.333*float(anno[66*2]))) + annos_new[-1].append(str(0.666*float(anno[67*2+1])+0.333*float(anno[66*2+1]))) + # right eye + annos_new[-1].append(anno[68*2]) + annos_new[-1].append(anno[68*2+1]) + annos_new[-1].append(str(0.666*float(anno[69*2])+0.333*float(anno[70*2]))) + annos_new[-1].append(str(0.666*float(anno[69*2+1])+0.333*float(anno[70*2+1]))) + annos_new[-1].append(str(0.666*float(anno[71*2])+0.333*float(anno[70*2]))) + annos_new[-1].append(str(0.666*float(anno[71*2+1])+0.333*float(anno[70*2+1]))) + annos_new[-1].append(anno[72*2]) + annos_new[-1].append(anno[72*2+1]) + annos_new[-1].append(str(0.666*float(anno[73*2])+0.333*float(anno[74*2]))) + annos_new[-1].append(str(0.666*float(anno[73*2+1])+0.333*float(anno[74*2+1]))) + annos_new[-1].append(str(0.666*float(anno[75*2])+0.333*float(anno[74*2]))) + annos_new[-1].append(str(0.666*float(anno[75*2+1])+0.333*float(anno[74*2+1]))) + # mouth + for i in range(76, 96): + annos_new[-1].append(anno[i*2]) + annos_new[-1].append(anno[i*2+1]) + + with open(os.path.join(root_folder, data_name, 'test.txt'), 'w') as f: + for anno in annos_new: + f.write(' '.join(anno)+'\n') + + +def gen_data(root_folder, data_name, target_size): + if not os.path.exists(os.path.join(root_folder, data_name, 'images_train')): + os.mkdir(os.path.join(root_folder, data_name, 'images_train')) + if not os.path.exists(os.path.join(root_folder, data_name, 'images_test')): + os.mkdir(os.path.join(root_folder, data_name, 'images_test')) + + ################################################################################################################ + if data_name == 'data_300W': + folders_train = ['afw', 'helen/trainset', 'lfpw/trainset'] + annos_train = {} + for folder_train in folders_train: + all_files = sorted(os.listdir(os.path.join(root_folder, data_name, folder_train))) + image_files = [x for x in all_files if '.pts' not in x] + label_files = [x for x in all_files if '.pts' in x] + assert len(image_files) == len(label_files) + for image_name, label_name in zip(image_files, label_files): + print(image_name) + image_crop, anno = process_300w(os.path.join(root_folder, 'data_300W'), folder_train, image_name, label_name, target_size) + image_crop_name = folder_train.replace('/', '_')+'_'+image_name + cv2.imwrite(os.path.join(root_folder, data_name, 'images_train', image_crop_name), image_crop) + annos_train[image_crop_name] = anno + with open(os.path.join(root_folder, data_name, 'train.txt'), 'w') as f: + for image_crop_name, anno in annos_train.items(): + f.write(image_crop_name+' ') + for x,y in anno: + f.write(str(x)+' '+str(y)+' ') + f.write('\n') + + + folders_test = ['helen/testset', 'lfpw/testset', 'ibug'] + annos_test = {} + for folder_test in folders_test: + all_files = sorted(os.listdir(os.path.join(root_folder, data_name, folder_test))) + image_files = [x for x in all_files if '.pts' not in x] + label_files = [x for x in all_files if '.pts' in x] + assert len(image_files) == len(label_files) + for image_name, label_name in zip(image_files, label_files): + print(image_name) + image_crop, anno = process_300w(os.path.join(root_folder, 'data_300W'), folder_test, image_name, label_name, target_size) + image_crop_name = folder_test.replace('/', '_')+'_'+image_name + cv2.imwrite(os.path.join(root_folder, data_name, 'images_test', image_crop_name), image_crop) + annos_test[image_crop_name] = anno + with open(os.path.join(root_folder, data_name, 'test.txt'), 'w') as f: + for image_crop_name, anno in annos_test.items(): + f.write(image_crop_name+' ') + for x,y in anno: + f.write(str(x)+' '+str(y)+' ') + f.write('\n') + + annos = None + with open(os.path.join(root_folder, data_name, 'test.txt'), 'r') as f: + annos = f.readlines() + with open(os.path.join(root_folder, data_name, 'test_common.txt'), 'w') as f: + for anno in annos: + if not 'ibug' in anno: + f.write(anno) + with open(os.path.join(root_folder, data_name, 'test_challenge.txt'), 'w') as f: + for anno in annos: + if 'ibug' in anno: + f.write(anno) + + gen_meanface(root_folder, data_name) + ################################################################################################################ + elif data_name == 'COFW': + train_file = 'COFW_train_color.mat' + train_mat = hdf5storage.loadmat(os.path.join(root_folder, 'COFW', train_file)) + images = train_mat['IsTr'] + bboxes = train_mat['bboxesTr'] + annos = train_mat['phisTr'] + + count = 1 + with open(os.path.join(root_folder, 'COFW', 'train.txt'), 'w') as f: + for i in range(images.shape[0]): + image = images[i, 0] + # grayscale + if len(image.shape) == 2: + image = cv2.cvtColor(image, cv2.COLOR_GRAY2BGR) + # swap rgb channel to bgr + else: + image = image[:,:,::-1] + bbox = bboxes[i, :] + anno = annos[i, :] + image_crop, anno = process_cofw(image, bbox, anno, target_size) + pad_num = 4-len(str(count)) + image_crop_name = 'cofw_train_' + '0' * pad_num + str(count) + '.jpg' + print(image_crop_name) + cv2.imwrite(os.path.join(root_folder, 'COFW', 'images_train', image_crop_name), image_crop) + f.write(image_crop_name+' ') + for x,y in anno: + f.write(str(x)+' '+str(y)+' ') + f.write('\n') + count += 1 + + test_file = 'COFW_test_color.mat' + test_mat = hdf5storage.loadmat(os.path.join(root_folder, 'COFW', test_file)) + images = test_mat['IsT'] + bboxes = test_mat['bboxesT'] + annos = test_mat['phisT'] + + count = 1 + with open(os.path.join(root_folder, 'COFW', 'test.txt'), 'w') as f: + for i in range(images.shape[0]): + image = images[i, 0] + # grayscale + if len(image.shape) == 2: + image = cv2.cvtColor(image, cv2.COLOR_GRAY2BGR) + # swap rgb channel to bgr + else: + image = image[:,:,::-1] + bbox = bboxes[i, :] + anno = annos[i, :] + image_crop, anno = process_cofw(image, bbox, anno, target_size) + pad_num = 4-len(str(count)) + image_crop_name = 'cofw_test_' + '0' * pad_num + str(count) + '.jpg' + print(image_crop_name) + cv2.imwrite(os.path.join(root_folder, 'COFW', 'images_test', image_crop_name), image_crop) + f.write(image_crop_name+' ') + for x,y in anno: + f.write(str(x)+' '+str(y)+' ') + f.write('\n') + count += 1 + gen_meanface(root_folder, data_name) + ################################################################################################################ + elif data_name == 'WFLW': + train_file = 'list_98pt_rect_attr_train.txt' + with open(os.path.join(root_folder, 'WFLW', 'WFLW_annotations', 'list_98pt_rect_attr_train_test', train_file), 'r') as f: + annos_train = f.readlines() + annos_train = [x.strip().split() for x in annos_train] + count = 1 + with open(os.path.join(root_folder, 'WFLW', 'train.txt'), 'w') as f: + for anno_train in annos_train: + image_crop, anno = process_wflw(anno_train, target_size) + pad_num = 4-len(str(count)) + image_crop_name = 'wflw_train_' + '0' * pad_num + str(count) + '.jpg' + print(image_crop_name) + cv2.imwrite(os.path.join(root_folder, 'WFLW', 'images_train', image_crop_name), image_crop) + f.write(image_crop_name+' ') + for x,y in anno: + f.write(str(x)+' '+str(y)+' ') + f.write('\n') + count += 1 + + test_file = 'list_98pt_rect_attr_test.txt' + with open(os.path.join(root_folder, 'WFLW', 'WFLW_annotations', 'list_98pt_rect_attr_train_test', test_file), 'r') as f: + annos_test = f.readlines() + annos_test = [x.strip().split() for x in annos_test] + names_mapping = {} + count = 1 + with open(os.path.join(root_folder, 'WFLW', 'test.txt'), 'w') as f: + for anno_test in annos_test: + image_crop, anno = process_wflw(anno_test, target_size) + pad_num = 4-len(str(count)) + image_crop_name = 'wflw_test_' + '0' * pad_num + str(count) + '.jpg' + print(image_crop_name) + names_mapping[anno_test[0]+'_'+anno_test[-1]] = [image_crop_name, anno] + cv2.imwrite(os.path.join(root_folder, 'WFLW', 'images_test', image_crop_name), image_crop) + f.write(image_crop_name+' ') + for x,y in list(anno): + f.write(str(x)+' '+str(y)+' ') + f.write('\n') + count += 1 + + test_pose_file = 'list_98pt_test_largepose.txt' + with open(os.path.join(root_folder, 'WFLW', 'WFLW_annotations', 'list_98pt_test', test_pose_file), 'r') as f: + annos_pose_test = f.readlines() + names_pose = [x.strip().split() for x in annos_pose_test] + names_pose = [x[0]+'_'+x[-1] for x in names_pose] + with open(os.path.join(root_folder, 'WFLW', 'test_pose.txt'), 'w') as f: + for name_pose in names_pose: + if name_pose in names_mapping: + image_crop_name, anno = names_mapping[name_pose] + f.write(image_crop_name+' ') + for x,y in anno: + f.write(str(x)+' '+str(y)+' ') + f.write('\n') + else: + print('error!') + exit(0) + + test_expr_file = 'list_98pt_test_expression.txt' + with open(os.path.join(root_folder, 'WFLW', 'WFLW_annotations', 'list_98pt_test', test_expr_file), 'r') as f: + annos_expr_test = f.readlines() + names_expr = [x.strip().split() for x in annos_expr_test] + names_expr = [x[0]+'_'+x[-1] for x in names_expr] + with open(os.path.join(root_folder, 'WFLW', 'test_expr.txt'), 'w') as f: + for name_expr in names_expr: + if name_expr in names_mapping: + image_crop_name, anno = names_mapping[name_expr] + f.write(image_crop_name+' ') + for x,y in anno: + f.write(str(x)+' '+str(y)+' ') + f.write('\n') + else: + print('error!') + exit(0) + + test_illu_file = 'list_98pt_test_illumination.txt' + with open(os.path.join(root_folder, 'WFLW', 'WFLW_annotations', 'list_98pt_test', test_illu_file), 'r') as f: + annos_illu_test = f.readlines() + names_illu = [x.strip().split() for x in annos_illu_test] + names_illu = [x[0]+'_'+x[-1] for x in names_illu] + with open(os.path.join(root_folder, 'WFLW', 'test_illu.txt'), 'w') as f: + for name_illu in names_illu: + if name_illu in names_mapping: + image_crop_name, anno = names_mapping[name_illu] + f.write(image_crop_name+' ') + for x,y in anno: + f.write(str(x)+' '+str(y)+' ') + f.write('\n') + else: + print('error!') + exit(0) + + test_mu_file = 'list_98pt_test_makeup.txt' + with open(os.path.join(root_folder, 'WFLW', 'WFLW_annotations', 'list_98pt_test', test_mu_file), 'r') as f: + annos_mu_test = f.readlines() + names_mu = [x.strip().split() for x in annos_mu_test] + names_mu = [x[0]+'_'+x[-1] for x in names_mu] + with open(os.path.join(root_folder, 'WFLW', 'test_mu.txt'), 'w') as f: + for name_mu in names_mu: + if name_mu in names_mapping: + image_crop_name, anno = names_mapping[name_mu] + f.write(image_crop_name+' ') + for x,y in anno: + f.write(str(x)+' '+str(y)+' ') + f.write('\n') + else: + print('error!') + exit(0) + + test_occu_file = 'list_98pt_test_occlusion.txt' + with open(os.path.join(root_folder, 'WFLW', 'WFLW_annotations', 'list_98pt_test', test_occu_file), 'r') as f: + annos_occu_test = f.readlines() + names_occu = [x.strip().split() for x in annos_occu_test] + names_occu = [x[0]+'_'+x[-1] for x in names_occu] + with open(os.path.join(root_folder, 'WFLW', 'test_occu.txt'), 'w') as f: + for name_occu in names_occu: + if name_occu in names_mapping: + image_crop_name, anno = names_mapping[name_occu] + f.write(image_crop_name+' ') + for x,y in anno: + f.write(str(x)+' '+str(y)+' ') + f.write('\n') + else: + print('error!') + exit(0) + + + test_blur_file = 'list_98pt_test_blur.txt' + with open(os.path.join(root_folder, 'WFLW', 'WFLW_annotations', 'list_98pt_test', test_blur_file), 'r') as f: + annos_blur_test = f.readlines() + names_blur = [x.strip().split() for x in annos_blur_test] + names_blur = [x[0]+'_'+x[-1] for x in names_blur] + with open(os.path.join(root_folder, 'WFLW', 'test_blur.txt'), 'w') as f: + for name_blur in names_blur: + if name_blur in names_mapping: + image_crop_name, anno = names_mapping[name_blur] + f.write(image_crop_name+' ') + for x,y in anno: + f.write(str(x)+' '+str(y)+' ') + f.write('\n') + else: + print('error!') + exit(0) + gen_meanface(root_folder, data_name) + ################################################################################################################ + elif data_name == 'AFLW': + mat = hdf5storage.loadmat('../data/AFLW/AFLWinfo_release.mat') + bboxes = mat['bbox'] + annos = mat['data'] + mask_new = mat['mask_new'] + nameList = mat['nameList'] + ra = mat['ra'][0] + train_indices = ra[:20000] + test_indices = ra[20000:] + + with open(os.path.join(root_folder, 'AFLW', 'train.txt'), 'w') as f: + for index in train_indices: + # from matlab index + image_name = nameList[index-1][0][0] + bbox = bboxes[index-1] + anno = annos[index-1] + image_crop, anno = process_aflw(root_folder, image_name, bbox, anno, target_size) + pad_num = 5-len(str(index)) + image_crop_name = 'aflw_train_' + '0' * pad_num + str(index) + '.jpg' + print(image_crop_name) + cv2.imwrite(os.path.join(root_folder, 'AFLW', 'images_train', image_crop_name), image_crop) + f.write(image_crop_name+' ') + for x,y in anno: + f.write(str(x)+' '+str(y)+' ') + f.write('\n') + + with open(os.path.join(root_folder, 'AFLW', 'test.txt'), 'w') as f: + for index in test_indices: + # from matlab index + image_name = nameList[index-1][0][0] + bbox = bboxes[index-1] + anno = annos[index-1] + image_crop, anno = process_aflw(root_folder, image_name, bbox, anno, target_size) + pad_num = 5-len(str(index)) + image_crop_name = 'aflw_test_' + '0' * pad_num + str(index) + '.jpg' + print(image_crop_name) + cv2.imwrite(os.path.join(root_folder, 'AFLW', 'images_test', image_crop_name), image_crop) + f.write(image_crop_name+' ') + for x,y in anno: + f.write(str(x)+' '+str(y)+' ') + f.write('\n') + gen_meanface(root_folder, data_name) + ################################################################################################################ + elif data_name == 'LaPa': + pass + # TODO + else: + print('Wrong data!') + +if __name__ == '__main__': + if len(sys.argv) < 2: + print('please input the data name.') + print('1. data_300W') + print('2. COFW') + print('3. WFLW') + print('4. AFLW') + print('5. LaPa') + exit(0) + else: + data_name = sys.argv[1] + gen_data('../data', data_name, 256) + + diff --git a/src/pixel3dmm/preprocessing/PIPNet/lib/preprocess_gssl.py b/src/pixel3dmm/preprocessing/PIPNet/lib/preprocess_gssl.py new file mode 100644 index 0000000000000000000000000000000000000000..ea804e6874f0ac49ba53bac27db83c8f3285e43f --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/lib/preprocess_gssl.py @@ -0,0 +1,544 @@ +import os, cv2 +import hdf5storage +import numpy as np +import sys + +def process_300w(root_folder, folder_name, image_name, label_name, target_size): + image_path = os.path.join(root_folder, folder_name, image_name) + label_path = os.path.join(root_folder, folder_name, label_name) + + with open(label_path, 'r') as ff: + anno = ff.readlines()[3:-1] + anno = [x.strip().split() for x in anno] + anno = [[int(float(x[0])), int(float(x[1]))] for x in anno] + image = cv2.imread(image_path) + image_height, image_width, _ = image.shape + anno_x = [x[0] for x in anno] + anno_y = [x[1] for x in anno] + bbox_xmin = min(anno_x) + bbox_ymin = min(anno_y) + bbox_xmax = max(anno_x) + bbox_ymax = max(anno_y) + bbox_width = bbox_xmax - bbox_xmin + bbox_height = bbox_ymax - bbox_ymin + scale = 1.3 + bbox_xmin -= int((scale-1)/2*bbox_width) + bbox_ymin -= int((scale-1)/2*bbox_height) + bbox_width *= scale + bbox_height *= scale + bbox_width = int(bbox_width) + bbox_height = int(bbox_height) + bbox_xmin = max(bbox_xmin, 0) + bbox_ymin = max(bbox_ymin, 0) + bbox_width = min(bbox_width, image_width-bbox_xmin-1) + bbox_height = min(bbox_height, image_height-bbox_ymin-1) + anno = [[(x-bbox_xmin)/bbox_width, (y-bbox_ymin)/bbox_height] for x,y in anno] + + bbox_xmax = bbox_xmin + bbox_width + bbox_ymax = bbox_ymin + bbox_height + image_crop = image[bbox_ymin:bbox_ymax, bbox_xmin:bbox_xmax, :] + image_crop = cv2.resize(image_crop, (target_size, target_size)) + return image_crop, anno + +def process_wflw(anno, target_size): + image_name = anno[-1] + image_path = os.path.join('..', 'data', 'WFLW', 'WFLW_images', image_name) + image = cv2.imread(image_path) + image_height, image_width, _ = image.shape + lms = anno[:196] + lms = [float(x) for x in lms] + lms_x = lms[0::2] + lms_y = lms[1::2] + lms_x = [x if x >=0 else 0 for x in lms_x] + lms_x = [x if x <=image_width else image_width for x in lms_x] + lms_y = [y if y >=0 else 0 for y in lms_y] + lms_y = [y if y <=image_height else image_height for y in lms_y] + lms = [[x,y] for x,y in zip(lms_x, lms_y)] + lms = [x for z in lms for x in z] + bbox = anno[196:200] + bbox = [float(x) for x in bbox] + attrs = anno[200:206] + attrs = np.array([int(x) for x in attrs]) + bbox_xmin, bbox_ymin, bbox_xmax, bbox_ymax = bbox + + width = bbox_xmax - bbox_xmin + height = bbox_ymax - bbox_ymin + scale = 1.2 + bbox_xmin -= width * (scale-1)/2 + # remove a part of top area for alignment, see details in paper + bbox_ymin += height * (scale-1)/2 + bbox_xmax += width * (scale-1)/2 + bbox_ymax += height * (scale-1)/2 + bbox_xmin = max(bbox_xmin, 0) + bbox_ymin = max(bbox_ymin, 0) + bbox_xmax = min(bbox_xmax, image_width-1) + bbox_ymax = min(bbox_ymax, image_height-1) + width = bbox_xmax - bbox_xmin + height = bbox_ymax - bbox_ymin + image_crop = image[int(bbox_ymin):int(bbox_ymax), int(bbox_xmin):int(bbox_xmax), :] + image_crop = cv2.resize(image_crop, (target_size, target_size)) + + tmp1 = [bbox_xmin, bbox_ymin]*98 + tmp1 = np.array(tmp1) + tmp2 = [width, height]*98 + tmp2 = np.array(tmp2) + lms = np.array(lms) - tmp1 + lms = lms / tmp2 + lms = lms.tolist() + lms = zip(lms[0::2], lms[1::2]) + return image_crop, list(lms) + +def process_celeba(root_folder, image_name, bbox, target_size): + image = cv2.imread(os.path.join(root_folder, 'CELEBA', 'img_celeba', image_name)) + image_height, image_width, _ = image.shape + xmin, ymin, xmax, ymax = bbox + width = xmax - xmin + 1 + height = ymax - ymin + 1 + scale = 1.2 + xmin -= width * (scale-1)/2 + # remove a part of top area for alignment, see details in paper + ymin += height * (scale+0.1-1)/2 + xmax += width * (scale-1)/2 + ymax += height * (scale-1)/2 + xmin = max(xmin, 0) + ymin = max(ymin, 0) + xmax = min(xmax, image_width-1) + ymax = min(ymax, image_height-1) + image_crop = image[int(ymin):int(ymax), int(xmin):int(xmax), :] + image_crop = cv2.resize(image_crop, (target_size, target_size)) + return image_crop + +def process_cofw_68_train(image, bbox, anno, target_size): + image_height, image_width, _ = image.shape + anno_x = anno[:29] + anno_y = anno[29:58] + xmin, ymin, width, height = bbox + xmax = xmin + width -1 + ymax = ymin + height -1 + scale = 1.3 + xmin -= width * (scale-1)/2 + ymin -= height * (scale-1)/2 + xmax += width * (scale-1)/2 + ymax += height * (scale-1)/2 + xmin = max(xmin, 0) + ymin = max(ymin, 0) + xmax = min(xmax, image_width-1) + ymax = min(ymax, image_height-1) + anno_x = (anno_x - xmin) / (xmax - xmin) + anno_y = (anno_y - ymin) / (ymax - ymin) + anno = np.concatenate([anno_x.reshape(-1,1), anno_y.reshape(-1,1)], axis=1) + anno = list(anno) + anno = [list(x) for x in anno] + image_crop = image[int(ymin):int(ymax), int(xmin):int(xmax), :] + image_crop = cv2.resize(image_crop, (target_size, target_size)) + return image_crop, anno + +def process_cofw_68_test(image, bbox, anno, target_size): + image_height, image_width, _ = image.shape + anno_x = anno[:,0].flatten() + anno_y = anno[:,1].flatten() + + xmin, ymin, width, height = bbox + xmax = xmin + width -1 + ymax = ymin + height -1 + + scale = 1.3 + xmin -= width * (scale-1)/2 + ymin -= height * (scale-1)/2 + xmax += width * (scale-1)/2 + ymax += height * (scale-1)/2 + xmin = max(xmin, 0) + ymin = max(ymin, 0) + xmax = min(xmax, image_width-1) + ymax = min(ymax, image_height-1) + anno_x = (anno_x - xmin) / (xmax - xmin) + anno_y = (anno_y - ymin) / (ymax - ymin) + anno = np.concatenate([anno_x.reshape(-1,1), anno_y.reshape(-1,1)], axis=1) + anno = list(anno) + anno = [list(x) for x in anno] + image_crop = image[int(ymin):int(ymax), int(xmin):int(xmax), :] + image_crop = cv2.resize(image_crop, (target_size, target_size)) + return image_crop, anno + +def gen_meanface(root_folder, data_name): + with open(os.path.join(root_folder, data_name, 'train_300W.txt'), 'r') as f: + annos = f.readlines() + annos = [x.strip().split()[1:] for x in annos] + annos = [[float(x) for x in anno] for anno in annos] + annos = np.array(annos) + meanface = np.mean(annos, axis=0) + meanface = meanface.tolist() + meanface = [str(x) for x in meanface] + + with open(os.path.join(root_folder, data_name, 'meanface.txt'), 'w') as f: + f.write(' '.join(meanface)) + +def convert_wflw(root_folder, data_name): + with open(os.path.join(root_folder, data_name, 'test_WFLW_98.txt'), 'r') as f: + annos = f.readlines() + annos = [x.strip().split() for x in annos] + annos_new = [] + for anno in annos: + annos_new.append([]) + # name + annos_new[-1].append(anno[0]) + anno = anno[1:] + # jaw + for i in range(17): + annos_new[-1].append(anno[i*2*2]) + annos_new[-1].append(anno[i*2*2+1]) + # left eyebrow + annos_new[-1].append(anno[33*2]) + annos_new[-1].append(anno[33*2+1]) + annos_new[-1].append(anno[34*2]) + annos_new[-1].append(str((float(anno[34*2+1])+float(anno[41*2+1]))/2)) + annos_new[-1].append(anno[35*2]) + annos_new[-1].append(str((float(anno[35*2+1])+float(anno[40*2+1]))/2)) + annos_new[-1].append(anno[36*2]) + annos_new[-1].append(str((float(anno[36*2+1])+float(anno[39*2+1]))/2)) + annos_new[-1].append(anno[37*2]) + annos_new[-1].append(str((float(anno[37*2+1])+float(anno[38*2+1]))/2)) + # right eyebrow + annos_new[-1].append(anno[42*2]) + annos_new[-1].append(str((float(anno[42*2+1])+float(anno[50*2+1]))/2)) + annos_new[-1].append(anno[43*2]) + annos_new[-1].append(str((float(anno[43*2+1])+float(anno[49*2+1]))/2)) + annos_new[-1].append(anno[44*2]) + annos_new[-1].append(str((float(anno[44*2+1])+float(anno[48*2+1]))/2)) + annos_new[-1].append(anno[45*2]) + annos_new[-1].append(str((float(anno[45*2+1])+float(anno[47*2+1]))/2)) + annos_new[-1].append(anno[46*2]) + annos_new[-1].append(anno[46*2+1]) + # nose + for i in range(51, 60): + annos_new[-1].append(anno[i*2]) + annos_new[-1].append(anno[i*2+1]) + # left eye + annos_new[-1].append(anno[60*2]) + annos_new[-1].append(anno[60*2+1]) + annos_new[-1].append(str(0.666*float(anno[61*2])+0.333*float(anno[62*2]))) + annos_new[-1].append(str(0.666*float(anno[61*2+1])+0.333*float(anno[62*2+1]))) + annos_new[-1].append(str(0.666*float(anno[63*2])+0.333*float(anno[62*2]))) + annos_new[-1].append(str(0.666*float(anno[63*2+1])+0.333*float(anno[62*2+1]))) + annos_new[-1].append(anno[64*2]) + annos_new[-1].append(anno[64*2+1]) + annos_new[-1].append(str(0.666*float(anno[65*2])+0.333*float(anno[66*2]))) + annos_new[-1].append(str(0.666*float(anno[65*2+1])+0.333*float(anno[66*2+1]))) + annos_new[-1].append(str(0.666*float(anno[67*2])+0.333*float(anno[66*2]))) + annos_new[-1].append(str(0.666*float(anno[67*2+1])+0.333*float(anno[66*2+1]))) + # right eye + annos_new[-1].append(anno[68*2]) + annos_new[-1].append(anno[68*2+1]) + annos_new[-1].append(str(0.666*float(anno[69*2])+0.333*float(anno[70*2]))) + annos_new[-1].append(str(0.666*float(anno[69*2+1])+0.333*float(anno[70*2+1]))) + annos_new[-1].append(str(0.666*float(anno[71*2])+0.333*float(anno[70*2]))) + annos_new[-1].append(str(0.666*float(anno[71*2+1])+0.333*float(anno[70*2+1]))) + annos_new[-1].append(anno[72*2]) + annos_new[-1].append(anno[72*2+1]) + annos_new[-1].append(str(0.666*float(anno[73*2])+0.333*float(anno[74*2]))) + annos_new[-1].append(str(0.666*float(anno[73*2+1])+0.333*float(anno[74*2+1]))) + annos_new[-1].append(str(0.666*float(anno[75*2])+0.333*float(anno[74*2]))) + annos_new[-1].append(str(0.666*float(anno[75*2+1])+0.333*float(anno[74*2+1]))) + # mouth + for i in range(76, 96): + annos_new[-1].append(anno[i*2]) + annos_new[-1].append(anno[i*2+1]) + + with open(os.path.join(root_folder, data_name, 'test_WFLW.txt'), 'w') as f: + for anno in annos_new: + f.write(' '.join(anno)+'\n') + +def gen_data(root_folder, data_name, target_size): + if not os.path.exists(os.path.join(root_folder, data_name, 'images_train')): + os.mkdir(os.path.join(root_folder, data_name, 'images_train')) + if not os.path.exists(os.path.join(root_folder, data_name, 'images_test')): + os.mkdir(os.path.join(root_folder, data_name, 'images_test')) + ################################################################################################################ + if data_name == 'CELEBA': + os.system('rmdir ../data/CELEBA/images_test') + with open(os.path.join(root_folder, data_name, 'celeba_bboxes.txt'), 'r') as f: + bboxes = f.readlines() + + bboxes = [x.strip().split() for x in bboxes] + with open(os.path.join(root_folder, data_name, 'train.txt'), 'w') as f: + for bbox in bboxes: + image_name = bbox[0] + print(image_name) + f.write(image_name+'\n') + bbox = bbox[1:] + bbox = [int(x) for x in bbox] + image_crop = process_celeba(root_folder, image_name, bbox, target_size) + cv2.imwrite(os.path.join(root_folder, data_name, 'images_train', image_name), image_crop) + ################################################################################################################ + elif data_name == 'data_300W_CELEBA': + os.system('cp -r ../data/CELEBA/images_train ../data/data_300W_CELEBA/.') + os.system('cp ../data/CELEBA/train.txt ../data/data_300W_CELEBA/train_CELEBA.txt') + + os.system('rmdir ../data/data_300W_CELEBA/images_test') + if not os.path.exists(os.path.join(root_folder, data_name, 'images_test_300W')): + os.mkdir(os.path.join(root_folder, data_name, 'images_test_300W')) + if not os.path.exists(os.path.join(root_folder, data_name, 'images_test_COFW')): + os.mkdir(os.path.join(root_folder, data_name, 'images_test_COFW')) + if not os.path.exists(os.path.join(root_folder, data_name, 'images_test_WFLW')): + os.mkdir(os.path.join(root_folder, data_name, 'images_test_WFLW')) + + # train for data_300W + folders_train = ['afw', 'helen/trainset', 'lfpw/trainset'] + annos_train = {} + for folder_train in folders_train: + all_files = sorted(os.listdir(os.path.join(root_folder, 'data_300W', folder_train))) + image_files = [x for x in all_files if '.pts' not in x] + label_files = [x for x in all_files if '.pts' in x] + assert len(image_files) == len(label_files) + for image_name, label_name in zip(image_files, label_files): + print(image_name) + image_crop, anno = process_300w(os.path.join(root_folder, 'data_300W'), folder_train, image_name, label_name, target_size) + image_crop_name = folder_train.replace('/', '_')+'_'+image_name + cv2.imwrite(os.path.join(root_folder, data_name, 'images_train', image_crop_name), image_crop) + annos_train[image_crop_name] = anno + with open(os.path.join(root_folder, data_name, 'train_300W.txt'), 'w') as f: + for image_crop_name, anno in annos_train.items(): + f.write(image_crop_name+' ') + for x,y in anno: + f.write(str(x)+' '+str(y)+' ') + f.write('\n') + + # test for data_300W + folders_test = ['helen/testset', 'lfpw/testset', 'ibug'] + annos_test = {} + for folder_test in folders_test: + all_files = sorted(os.listdir(os.path.join(root_folder, 'data_300W', folder_test))) + image_files = [x for x in all_files if '.pts' not in x] + label_files = [x for x in all_files if '.pts' in x] + assert len(image_files) == len(label_files) + for image_name, label_name in zip(image_files, label_files): + print(image_name) + image_crop, anno = process_300w(os.path.join(root_folder, 'data_300W'), folder_test, image_name, label_name, target_size) + image_crop_name = folder_test.replace('/', '_')+'_'+image_name + cv2.imwrite(os.path.join(root_folder, data_name, 'images_test_300W', image_crop_name), image_crop) + annos_test[image_crop_name] = anno + with open(os.path.join(root_folder, data_name, 'test_300W.txt'), 'w') as f: + for image_crop_name, anno in annos_test.items(): + f.write(image_crop_name+' ') + for x,y in anno: + f.write(str(x)+' '+str(y)+' ') + f.write('\n') + + # test for COFW_68 + test_mat = hdf5storage.loadmat(os.path.join('../data/COFW', 'COFW_test_color.mat')) + images = test_mat['IsT'] + + bboxes_mat = hdf5storage.loadmat(os.path.join('../data/data_300W_CELEBA', 'cofw68_test_bboxes.mat')) + bboxes = bboxes_mat['bboxes'] + image_num = images.shape[0] + with open('../data/data_300W_CELEBA/test_COFW.txt', 'w') as f: + for i in range(image_num): + image = images[i,0] + # grayscale + if len(image.shape) == 2: + image = cv2.cvtColor(image, cv2.COLOR_GRAY2BGR) + # swap rgb channel to bgr + else: + image = image[:,:,::-1] + + bbox = bboxes[i,:] + anno_mat = hdf5storage.loadmat(os.path.join('../data/data_300W_CELEBA/cofw68_test_annotations', str(i+1)+'_points.mat')) + anno = anno_mat['Points'] + image_crop, anno = process_cofw_68_test(image, bbox, anno, target_size) + pad_num = 4-len(str(i+1)) + image_crop_name = 'cofw_test_' + '0' * pad_num + str(i+1) + '.jpg' + cv2.imwrite(os.path.join('../data/data_300W_CELEBA/images_test_COFW', image_crop_name), image_crop) + f.write(image_crop_name+' ') + for x,y in anno: + f.write(str(x)+' '+str(y)+' ') + f.write('\n') + + # test for WFLW_68 + test_file = 'list_98pt_rect_attr_test.txt' + with open(os.path.join(root_folder, 'WFLW', 'WFLW_annotations', 'list_98pt_rect_attr_train_test', test_file), 'r') as f: + annos_test = f.readlines() + annos_test = [x.strip().split() for x in annos_test] + names_mapping = {} + count = 1 + with open(os.path.join(root_folder, 'data_300W_CELEBA', 'test_WFLW_98.txt'), 'w') as f: + for anno_test in annos_test: + image_crop, anno = process_wflw(anno_test, target_size) + pad_num = 4-len(str(count)) + image_crop_name = 'wflw_test_' + '0' * pad_num + str(count) + '.jpg' + print(image_crop_name) + names_mapping[anno_test[0]+'_'+anno_test[-1]] = [image_crop_name, anno] + cv2.imwrite(os.path.join(root_folder, data_name, 'images_test_WFLW', image_crop_name), image_crop) + f.write(image_crop_name+' ') + for x,y in list(anno): + f.write(str(x)+' '+str(y)+' ') + f.write('\n') + count += 1 + + convert_wflw(root_folder, data_name) + + gen_meanface(root_folder, data_name) + ################################################################################################################ + elif data_name == 'data_300W_COFW_WFLW': + + os.system('rmdir ../data/data_300W_COFW_WFLW/images_test') + if not os.path.exists(os.path.join(root_folder, data_name, 'images_test_300W')): + os.mkdir(os.path.join(root_folder, data_name, 'images_test_300W')) + if not os.path.exists(os.path.join(root_folder, data_name, 'images_test_COFW')): + os.mkdir(os.path.join(root_folder, data_name, 'images_test_COFW')) + if not os.path.exists(os.path.join(root_folder, data_name, 'images_test_WFLW')): + os.mkdir(os.path.join(root_folder, data_name, 'images_test_WFLW')) + + # train for data_300W + folders_train = ['afw', 'helen/trainset', 'lfpw/trainset'] + annos_train = {} + for folder_train in folders_train: + all_files = sorted(os.listdir(os.path.join(root_folder, 'data_300W', folder_train))) + image_files = [x for x in all_files if '.pts' not in x] + label_files = [x for x in all_files if '.pts' in x] + assert len(image_files) == len(label_files) + for image_name, label_name in zip(image_files, label_files): + print(image_name) + image_crop, anno = process_300w(os.path.join(root_folder, 'data_300W'), folder_train, image_name, label_name, target_size) + image_crop_name = folder_train.replace('/', '_')+'_'+image_name + cv2.imwrite(os.path.join(root_folder, data_name, 'images_train', image_crop_name), image_crop) + annos_train[image_crop_name] = anno + with open(os.path.join(root_folder, data_name, 'train_300W.txt'), 'w') as f: + for image_crop_name, anno in annos_train.items(): + f.write(image_crop_name+' ') + for x,y in anno: + f.write(str(x)+' '+str(y)+' ') + f.write('\n') + + # test for data_300W + folders_test = ['helen/testset', 'lfpw/testset', 'ibug'] + annos_test = {} + for folder_test in folders_test: + all_files = sorted(os.listdir(os.path.join(root_folder, 'data_300W', folder_test))) + image_files = [x for x in all_files if '.pts' not in x] + label_files = [x for x in all_files if '.pts' in x] + assert len(image_files) == len(label_files) + for image_name, label_name in zip(image_files, label_files): + print(image_name) + image_crop, anno = process_300w(os.path.join(root_folder, 'data_300W'), folder_test, image_name, label_name, target_size) + image_crop_name = folder_test.replace('/', '_')+'_'+image_name + cv2.imwrite(os.path.join(root_folder, data_name, 'images_test_300W', image_crop_name), image_crop) + annos_test[image_crop_name] = anno + with open(os.path.join(root_folder, data_name, 'test_300W.txt'), 'w') as f: + for image_crop_name, anno in annos_test.items(): + f.write(image_crop_name+' ') + for x,y in anno: + f.write(str(x)+' '+str(y)+' ') + f.write('\n') + + # train for COFW_68 + ################### + train_file = 'COFW_train_color.mat' + train_mat = hdf5storage.loadmat(os.path.join(root_folder, 'COFW', train_file)) + images = train_mat['IsTr'] + bboxes = train_mat['bboxesTr'] + annos = train_mat['phisTr'] + + count = 1 + with open('../data/data_300W_COFW_WFLW/train_COFW.txt', 'w') as f: + for i in range(images.shape[0]): + image = images[i, 0] + # grayscale + if len(image.shape) == 2: + image = cv2.cvtColor(image, cv2.COLOR_GRAY2BGR) + # swap rgb channel to bgr + else: + image = image[:,:,::-1] + bbox = bboxes[i, :] + anno = annos[i, :] + image_crop, anno = process_cofw_68_train(image, bbox, anno, target_size) + pad_num = 4-len(str(count)) + image_crop_name = 'cofw_train_' + '0' * pad_num + str(count) + '.jpg' + f.write(image_crop_name+'\n') + cv2.imwrite(os.path.join(root_folder, 'data_300W_COFW_WFLW', 'images_train', image_crop_name), image_crop) + count += 1 + ################### + + # test for COFW_68 + test_mat = hdf5storage.loadmat(os.path.join('../data/COFW', 'COFW_test_color.mat')) + images = test_mat['IsT'] + + bboxes_mat = hdf5storage.loadmat(os.path.join('../data/data_300W_COFW_WFLW', 'cofw68_test_bboxes.mat')) + bboxes = bboxes_mat['bboxes'] + image_num = images.shape[0] + with open('../data/data_300W_COFW_WFLW/test_COFW.txt', 'w') as f: + for i in range(image_num): + image = images[i,0] + # grayscale + if len(image.shape) == 2: + image = cv2.cvtColor(image, cv2.COLOR_GRAY2BGR) + # swap rgb channel to bgr + else: + image = image[:,:,::-1] + + bbox = bboxes[i,:] + anno_mat = hdf5storage.loadmat(os.path.join('../data/data_300W_COFW_WFLW/cofw68_test_annotations', str(i+1)+'_points.mat')) + anno = anno_mat['Points'] + image_crop, anno = process_cofw_68_test(image, bbox, anno, target_size) + pad_num = 4-len(str(i+1)) + image_crop_name = 'cofw_test_' + '0' * pad_num + str(i+1) + '.jpg' + cv2.imwrite(os.path.join('../data/data_300W_COFW_WFLW/images_test_COFW', image_crop_name), image_crop) + f.write(image_crop_name+' ') + for x,y in anno: + f.write(str(x)+' '+str(y)+' ') + f.write('\n') + + # train for WFLW_68 + train_file = 'list_98pt_rect_attr_train.txt' + with open(os.path.join('../data', 'WFLW', 'WFLW_annotations', 'list_98pt_rect_attr_train_test', train_file), 'r') as f: + annos_train = f.readlines() + annos_train = [x.strip().split() for x in annos_train] + count = 1 + with open('../data/data_300W_COFW_WFLW/train_WFLW.txt', 'w') as f: + for anno_train in annos_train: + image_crop, anno = process_wflw(anno_train, target_size) + pad_num = 4-len(str(count)) + image_crop_name = 'wflw_train_' + '0' * pad_num + str(count) + '.jpg' + print(image_crop_name) + f.write(image_crop_name+'\n') + cv2.imwrite(os.path.join(root_folder, 'data_300W_COFW_WFLW', 'images_train', image_crop_name), image_crop) + count += 1 + + # test for WFLW_68 + test_file = 'list_98pt_rect_attr_test.txt' + with open(os.path.join(root_folder, 'WFLW', 'WFLW_annotations', 'list_98pt_rect_attr_train_test', test_file), 'r') as f: + annos_test = f.readlines() + annos_test = [x.strip().split() for x in annos_test] + names_mapping = {} + count = 1 + with open(os.path.join(root_folder, 'data_300W_COFW_WFLW', 'test_WFLW_98.txt'), 'w') as f: + for anno_test in annos_test: + image_crop, anno = process_wflw(anno_test, target_size) + pad_num = 4-len(str(count)) + image_crop_name = 'wflw_test_' + '0' * pad_num + str(count) + '.jpg' + print(image_crop_name) + names_mapping[anno_test[0]+'_'+anno_test[-1]] = [image_crop_name, anno] + cv2.imwrite(os.path.join(root_folder, data_name, 'images_test_WFLW', image_crop_name), image_crop) + f.write(image_crop_name+' ') + for x,y in list(anno): + f.write(str(x)+' '+str(y)+' ') + f.write('\n') + count += 1 + + convert_wflw(root_folder, data_name) + + gen_meanface(root_folder, data_name) + else: + print('Wrong data!') + +if __name__ == '__main__': + if len(sys.argv) < 2: + print('please input the data name.') + print('1. CELEBA') + print('2. data_300W_CELEBA') + print('3. data_300W_COFW_WFLW') + exit(0) + else: + data_name = sys.argv[1] + gen_data('../data', data_name, 256) + + diff --git a/src/pixel3dmm/preprocessing/PIPNet/lib/test.py b/src/pixel3dmm/preprocessing/PIPNet/lib/test.py new file mode 100644 index 0000000000000000000000000000000000000000..66687348f6a5a5dc6c89634acc3bd9b42ca7d9ca --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/lib/test.py @@ -0,0 +1,171 @@ +import cv2, os +import sys +sys.path.insert(0, '..') +import numpy as np +from PIL import Image +import logging +import pickle +import importlib +from math import floor +import time + +import torch +import torch.nn as nn +import torch.optim as optim +import torch.utils.data +import torch.nn.functional as F +import torchvision.transforms as transforms +import torchvision.datasets as datasets +import torchvision.models as models + +from networks import * +import data_utils +from functions import * +from mobilenetv3 import mobilenetv3_large + +if not len(sys.argv) == 4: + print('Format:') + print('python lib/test.py config_file test_labels test_images') + exit(0) +experiment_name = sys.argv[1].split('/')[-1][:-3] +data_name = sys.argv[1].split('/')[-2] +test_labels = sys.argv[2] +test_images = sys.argv[3] +config_path = '.experiments.{}.{}'.format(data_name, experiment_name) + +my_config = importlib.import_module(config_path, package='PIPNet') +Config = getattr(my_config, 'Config') +cfg = Config() +cfg.experiment_name = experiment_name +cfg.data_name = data_name + +os.environ['CUDA_VISIBLE_DEVICES'] = str(cfg.gpu_id) + +if not os.path.exists(os.path.join('./logs', cfg.data_name)): + os.mkdir(os.path.join('./logs', cfg.data_name)) +log_dir = os.path.join('./logs', cfg.data_name, cfg.experiment_name) +if not os.path.exists(log_dir): + os.mkdir(log_dir) + +logging.basicConfig(filename=os.path.join(log_dir, 'train.log'), level=logging.INFO) + +save_dir = os.path.join('./snapshots', cfg.data_name, cfg.experiment_name) +if not os.path.exists(save_dir): + os.mkdir(save_dir) + +if cfg.det_head == 'pip': + meanface_indices, reverse_index1, reverse_index2, max_len = get_meanface(os.path.join('data', cfg.data_name, 'meanface.txt'), cfg.num_nb) + +if cfg.det_head == 'pip': + if cfg.backbone == 'resnet18': + resnet18 = models.resnet18(pretrained=cfg.pretrained) + net = Pip_resnet18(resnet18, cfg.num_nb, num_lms=cfg.num_lms, input_size=cfg.input_size, net_stride=cfg.net_stride) + elif cfg.backbone == 'resnet50': + resnet50 = models.resnet50(pretrained=cfg.pretrained) + net = Pip_resnet50(resnet50, cfg.num_nb, num_lms=cfg.num_lms, input_size=cfg.input_size, net_stride=cfg.net_stride) + elif cfg.backbone == 'resnet101': + resnet101 = models.resnet101(pretrained=cfg.pretrained) + net = Pip_resnet101(resnet101, cfg.num_nb, num_lms=cfg.num_lms, input_size=cfg.input_size, net_stride=cfg.net_stride) + elif cfg.backbone == 'mobilenet_v2': + mbnet = models.mobilenet_v2(pretrained=cfg.pretrained) + net = Pip_mbnetv2(mbnet, cfg.num_nb, num_lms=cfg.num_lms, input_size=cfg.input_size, net_stride=cfg.net_stride) + elif cfg.backbone == 'mobilenet_v3': + mbnet = mobilenetv3_large() + if cfg.pretrained: + mbnet.load_state_dict(torch.load('lib/mobilenetv3-large-1cd25616.pth')) + net = Pip_mbnetv3(mbnet, cfg.num_nb, num_lms=cfg.num_lms, input_size=cfg.input_size, net_stride=cfg.net_stride) + else: + print('No such backbone!') + exit(0) +else: + print('No such head:', cfg.det_head) + exit(0) + +if cfg.use_gpu: + device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") +else: + device = torch.device("cpu") +net = net.to(device) + +weight_file = os.path.join(save_dir, 'epoch%d.pth' % (cfg.num_epochs-1)) +state_dict = torch.load(weight_file) +net.load_state_dict(state_dict) + +normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406], + std=[0.229, 0.224, 0.225]) +preprocess = transforms.Compose([transforms.Resize((cfg.input_size, cfg.input_size)), transforms.ToTensor(), normalize]) + +norm_indices = None +if cfg.data_name == 'data_300W' or cfg.data_name == 'data_300W_COFW_WFLW' or cfg.data_name == 'data_300W_CELEBA': + norm_indices = [36, 45] +elif cfg.data_name == 'COFW': + norm_indices = [8, 9] +elif cfg.data_name == 'WFLW': + norm_indices = [60, 72] +elif cfg.data_name == 'AFLW': + pass +elif cfg.data_name == 'LaPa': + norm_indices = [66, 79] +else: + print('No such data!') + exit(0) + +labels = get_label(cfg.data_name, test_labels) + +nmes_std = [] +nmes_merge = [] +norm = None +time_all = 0 +for label in labels: + image_name = label[0] + lms_gt = label[1] + if cfg.data_name == 'data_300W' or cfg.data_name == 'COFW' or cfg.data_name == 'WFLW' or cfg.data_name == 'data_300W_COFW_WFLW' or cfg.data_name == 'data_300W_CELEBA': + norm = np.linalg.norm(lms_gt.reshape(-1, 2)[norm_indices[0]] - lms_gt.reshape(-1, 2)[norm_indices[1]]) + elif cfg.data_name == 'AFLW': + norm = 1 + image_path = os.path.join('data', cfg.data_name, test_images, image_name) + image = cv2.imread(image_path) + image = cv2.resize(image, (cfg.input_size, cfg.input_size)) + inputs = Image.fromarray(image[:,:,::-1].astype('uint8'), 'RGB') + inputs = preprocess(inputs).unsqueeze(0) + inputs = inputs.to(device) + t1 = time.time() + if cfg.det_head == 'pip': + lms_pred_x, lms_pred_y, lms_pred_nb_x, lms_pred_nb_y, outputs_cls, max_cls = forward_pip(net, inputs, preprocess, cfg.input_size, cfg.net_stride, cfg.num_nb) + else: + print('No such head!') + if cfg.det_head == 'pip': + # merge neighbor predictions + lms_pred = torch.cat((lms_pred_x, lms_pred_y), dim=1).flatten() + tmp_nb_x = lms_pred_nb_x[reverse_index1, reverse_index2].view(cfg.num_lms, max_len) + tmp_nb_y = lms_pred_nb_y[reverse_index1, reverse_index2].view(cfg.num_lms, max_len) + tmp_x = torch.mean(torch.cat((lms_pred_x, tmp_nb_x), dim=1), dim=1).view(-1,1) + tmp_y = torch.mean(torch.cat((lms_pred_y, tmp_nb_y), dim=1), dim=1).view(-1,1) + lms_pred_merge = torch.cat((tmp_x, tmp_y), dim=1).flatten() + t2 = time.time() + time_all += (t2-t1) + + if cfg.det_head == 'pip': + lms_pred = lms_pred.cpu().numpy() + lms_pred_merge = lms_pred_merge.cpu().numpy() + + nme_std = compute_nme(lms_pred, lms_gt, norm) + nmes_std.append(nme_std) + if cfg.det_head == 'pip': + nme_merge = compute_nme(lms_pred_merge, lms_gt, norm) + nmes_merge.append(nme_merge) + + +print('Total inference time:', time_all) +print('Image num:', len(labels)) +print('Average inference time:', time_all/len(labels)) + +if cfg.det_head == 'pip': + print('nme: {}'.format(np.mean(nmes_merge))) + logging.info('nme: {}'.format(np.mean(nmes_merge))) + + fr, auc = compute_fr_and_auc(nmes_merge) + print('fr : {}'.format(fr)) + logging.info('fr : {}'.format(fr)) + print('auc: {}'.format(auc)) + logging.info('auc: {}'.format(auc)) diff --git a/src/pixel3dmm/preprocessing/PIPNet/lib/train.py b/src/pixel3dmm/preprocessing/PIPNet/lib/train.py new file mode 100644 index 0000000000000000000000000000000000000000..64451aa1de94425117eac92964519c041e6cf1b6 --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/lib/train.py @@ -0,0 +1,200 @@ +import cv2, os +import sys +sys.path.insert(0, '..') +import numpy as np +from PIL import Image +import logging +import copy +import importlib + +import torch +import torch.nn as nn +import torch.optim as optim +import torch.utils.data +import torch.nn.functional as F +import torchvision.transforms as transforms +import torchvision.datasets as datasets +import torchvision.models as models + +from networks import * +import data_utils +from functions import * +from mobilenetv3 import mobilenetv3_large + +if not len(sys.argv) == 2: + print('Format:') + print('python lib/train.py config_file') + exit(0) +experiment_name = sys.argv[1].split('/')[-1][:-3] +data_name = sys.argv[1].split('/')[-2] +config_path = '.experiments.{}.{}'.format(data_name, experiment_name) + +my_config = importlib.import_module(config_path, package='PIPNet') +Config = getattr(my_config, 'Config') +cfg = Config() +cfg.experiment_name = experiment_name +cfg.data_name = data_name + +os.environ['CUDA_VISIBLE_DEVICES'] = str(cfg.gpu_id) + +if not os.path.exists(os.path.join('./snapshots', cfg.data_name)): + os.mkdir(os.path.join('./snapshots', cfg.data_name)) +save_dir = os.path.join('./snapshots', cfg.data_name, cfg.experiment_name) +if not os.path.exists(save_dir): + os.mkdir(save_dir) + +if not os.path.exists(os.path.join('./logs', cfg.data_name)): + os.mkdir(os.path.join('./logs', cfg.data_name)) +log_dir = os.path.join('./logs', cfg.data_name, cfg.experiment_name) +if not os.path.exists(log_dir): + os.mkdir(log_dir) + +logging.basicConfig(filename=os.path.join(log_dir, 'train.log'), level=logging.INFO) + +print('###########################################') +print('experiment_name:', cfg.experiment_name) +print('data_name:', cfg.data_name) +print('det_head:', cfg.det_head) +print('net_stride:', cfg.net_stride) +print('batch_size:', cfg.batch_size) +print('init_lr:', cfg.init_lr) +print('num_epochs:', cfg.num_epochs) +print('decay_steps:', cfg.decay_steps) +print('input_size:', cfg.input_size) +print('backbone:', cfg.backbone) +print('pretrained:', cfg.pretrained) +print('criterion_cls:', cfg.criterion_cls) +print('criterion_reg:', cfg.criterion_reg) +print('cls_loss_weight:', cfg.cls_loss_weight) +print('reg_loss_weight:', cfg.reg_loss_weight) +print('num_lms:', cfg.num_lms) +print('save_interval:', cfg.save_interval) +print('num_nb:', cfg.num_nb) +print('use_gpu:', cfg.use_gpu) +print('gpu_id:', cfg.gpu_id) +print('###########################################') +logging.info('###########################################') +logging.info('experiment_name: {}'.format(cfg.experiment_name)) +logging.info('data_name: {}'.format(cfg.data_name)) +logging.info('det_head: {}'.format(cfg.det_head)) +logging.info('net_stride: {}'.format(cfg.net_stride)) +logging.info('batch_size: {}'.format(cfg.batch_size)) +logging.info('init_lr: {}'.format(cfg.init_lr)) +logging.info('num_epochs: {}'.format(cfg.num_epochs)) +logging.info('decay_steps: {}'.format(cfg.decay_steps)) +logging.info('input_size: {}'.format(cfg.input_size)) +logging.info('backbone: {}'.format(cfg.backbone)) +logging.info('pretrained: {}'.format(cfg.pretrained)) +logging.info('criterion_cls: {}'.format(cfg.criterion_cls)) +logging.info('criterion_reg: {}'.format(cfg.criterion_reg)) +logging.info('cls_loss_weight: {}'.format(cfg.cls_loss_weight)) +logging.info('reg_loss_weight: {}'.format(cfg.reg_loss_weight)) +logging.info('num_lms: {}'.format(cfg.num_lms)) +logging.info('save_interval: {}'.format(cfg.save_interval)) +logging.info('num_nb: {}'.format(cfg.num_nb)) +logging.info('use_gpu: {}'.format(cfg.use_gpu)) +logging.info('gpu_id: {}'.format(cfg.gpu_id)) +logging.info('###########################################') + +if cfg.det_head == 'pip': + meanface_indices, _, _, _ = get_meanface(os.path.join('data', cfg.data_name, 'meanface.txt'), cfg.num_nb) + + +if cfg.det_head == 'pip': + if cfg.backbone == 'resnet18': + resnet18 = models.resnet18(pretrained=cfg.pretrained) + net = Pip_resnet18(resnet18, cfg.num_nb, num_lms=cfg.num_lms, input_size=cfg.input_size, net_stride=cfg.net_stride) + elif cfg.backbone == 'resnet50': + resnet50 = models.resnet50(pretrained=cfg.pretrained) + net = Pip_resnet50(resnet50, cfg.num_nb, num_lms=cfg.num_lms, input_size=cfg.input_size, net_stride=cfg.net_stride) + elif cfg.backbone == 'resnet101': + resnet101 = models.resnet101(pretrained=cfg.pretrained) + net = Pip_resnet101(resnet101, cfg.num_nb, num_lms=cfg.num_lms, input_size=cfg.input_size, net_stride=cfg.net_stride) + elif cfg.backbone == 'mobilenet_v2': + mbnet = models.mobilenet_v2(pretrained=cfg.pretrained) + net = Pip_mbnetv2(mbnet, cfg.num_nb, num_lms=cfg.num_lms, input_size=cfg.input_size, net_stride=cfg.net_stride) + elif cfg.backbone == 'mobilenet_v3': + mbnet = mobilenetv3_large() + if cfg.pretrained: + mbnet.load_state_dict(torch.load('lib/mobilenetv3-large-1cd25616.pth')) + net = Pip_mbnetv3(mbnet, cfg.num_nb, num_lms=cfg.num_lms, input_size=cfg.input_size, net_stride=cfg.net_stride) + else: + print('No such backbone!') + exit(0) +else: + print('No such head:', cfg.det_head) + exit(0) + +if cfg.use_gpu: + device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") +else: + device = torch.device("cpu") +net = net.to(device) + +criterion_cls = None +if cfg.criterion_cls == 'l2': + criterion_cls = nn.MSELoss() +elif cfg.criterion_cls == 'l1': + criterion_cls = nn.L1Loss() +else: + print('No such cls criterion:', cfg.criterion_cls) + +criterion_reg = None +if cfg.criterion_reg == 'l1': + criterion_reg = nn.L1Loss() +elif cfg.criterion_reg == 'l2': + criterion_reg = nn.MSELoss() +else: + print('No such reg criterion:', cfg.criterion_reg) + +points_flip = None +if cfg.data_name == 'data_300W': + points_flip = [17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 28, 29, 30, 31, 36, 35, 34, 33, 32, 46, 45, 44, 43, 48, 47, 40, 39, 38, 37, 42, 41, 55, 54, 53, 52, 51, 50, 49, 60, 59, 58, 57, 56, 65, 64, 63, 62, 61, 68, 67, 66] + points_flip = (np.array(points_flip)-1).tolist() + assert len(points_flip) == 68 +elif cfg.data_name == 'WFLW': + points_flip = [32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 46, 45, 44, 43, 42, 50, 49, 48, 47, 37, 36, 35, 34, 33, 41, 40, 39, 38, 51, 52, 53, 54, 59, 58, 57, 56, 55, 72, 71, 70, 69, 68, 75, 74, 73, 64, 63, 62, 61, 60, 67, 66, 65, 82, 81, 80, 79, 78, 77, 76, 87, 86, 85, 84, 83, 92, 91, 90, 89, 88, 95, 94, 93, 97, 96] + assert len(points_flip) == 98 +elif cfg.data_name == 'COFW': + points_flip = [2, 1, 4, 3, 7, 8, 5, 6, 10, 9, 12, 11, 15, 16, 13, 14, 18, 17, 20, 19, 21, 22, 24, 23, 25, 26, 27, 28, 29] + points_flip = (np.array(points_flip)-1).tolist() + assert len(points_flip) == 29 +elif cfg.data_name == 'AFLW': + points_flip = [6, 5, 4, 3, 2, 1, 12, 11, 10, 9, 8, 7, 15, 14, 13, 18, 17, 16, 19] + points_flip = (np.array(points_flip)-1).tolist() + assert len(points_flip) == 19 +elif cfg.data_name == 'LaPa': + points_flip = [33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 47, 46, 45, 44, 43, 51, 50, 49, 48, 38, 37, 36, 35, 34, 42, 41, 40, 39, 52, 53, 54, 55, 66, 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 80, 79, 78, 77, 76, 83, 82, 81, 84, 71, 70, 69, 68, 67, 74, 73, 72, 75, 91, 90, 89, 88, 87, 86, 85, 96, 95, 94, 93, 92, 101, 100, 99, 98, 97, 104, 103, 102, 106, 105] + points_flip = (np.array(points_flip)-1).tolist() + assert len(points_flip) == 106 +else: + print('No such data!') + exit(0) + +normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406], + std=[0.229, 0.224, 0.225]) + +if cfg.pretrained: + optimizer = optim.Adam(net.parameters(), lr=cfg.init_lr) +else: + optimizer = optim.Adam(net.parameters(), lr=cfg.init_lr, weight_decay=5e-4) +scheduler = optim.lr_scheduler.MultiStepLR(optimizer, milestones=cfg.decay_steps, gamma=0.1) + +labels = get_label(cfg.data_name, 'train.txt') + +if cfg.det_head == 'pip': + train_data = data_utils.ImageFolder_pip(os.path.join('data', cfg.data_name, 'images_train'), + labels, cfg.input_size, cfg.num_lms, + cfg.net_stride, points_flip, meanface_indices, + transforms.Compose([ + transforms.RandomGrayscale(0.2), + transforms.ToTensor(), + normalize])) +else: + print('No such head:', cfg.det_head) + exit(0) + +train_loader = torch.utils.data.DataLoader(train_data, batch_size=cfg.batch_size, shuffle=True, num_workers=8, pin_memory=True, drop_last=True) + +train_model(cfg.det_head, net, train_loader, criterion_cls, criterion_reg, cfg.cls_loss_weight, cfg.reg_loss_weight, cfg.num_nb, optimizer, cfg.num_epochs, scheduler, save_dir, cfg.save_interval, device) + diff --git a/src/pixel3dmm/preprocessing/PIPNet/lib/train_gssl.py b/src/pixel3dmm/preprocessing/PIPNet/lib/train_gssl.py new file mode 100644 index 0000000000000000000000000000000000000000..94ea69ab7be3f1ad04152f98e5fadcb9a7e465f7 --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/lib/train_gssl.py @@ -0,0 +1,303 @@ +import cv2, os +import sys +sys.path.insert(0, '..') +import numpy as np +from PIL import Image +import logging +import importlib + +import torch +import torch.nn as nn +import torch.optim as optim +import torch.utils.data +import torch.nn.functional as F +import torchvision.transforms as transforms +import torchvision.datasets as datasets +import torchvision.models as models + +from networks_gssl import * +import data_utils_gssl +from functions_gssl import * + +if not len(sys.argv) == 2: + print('Format:') + print('python lib/train_gssl.py config_file') + exit(0) +experiment_name = sys.argv[1].split('/')[-1][:-3] +data_name = sys.argv[1].split('/')[-2] +config_path = '.experiments.{}.{}'.format(data_name, experiment_name) + +my_config = importlib.import_module(config_path, package='PIPNet') +Config = getattr(my_config, 'Config') +cfg = Config() +cfg.experiment_name = experiment_name +cfg.data_name = data_name + +os.environ['CUDA_VISIBLE_DEVICES'] = str(cfg.gpu_id) + +if not os.path.exists(os.path.join('./snapshots', cfg.data_name)): + os.mkdir(os.path.join('./snapshots', cfg.data_name)) +save_dir = os.path.join('./snapshots', cfg.data_name, cfg.experiment_name) +if not os.path.exists(save_dir): + os.mkdir(save_dir) + +if not os.path.exists(os.path.join('./logs', cfg.data_name)): + os.mkdir(os.path.join('./logs', cfg.data_name)) +log_dir = os.path.join('./logs', cfg.data_name, cfg.experiment_name) +if not os.path.exists(log_dir): + os.mkdir(log_dir) + +logging.basicConfig(filename=os.path.join(log_dir, 'train.log'), level=logging.INFO) + +print('###########################################') +print('experiment_name:', cfg.experiment_name) +print('data_name:', cfg.data_name) +print('det_head:', cfg.det_head) +print('net_stride:', cfg.net_stride) +print('batch_size:', cfg.batch_size) +print('init_lr:', cfg.init_lr) +print('num_epochs:', cfg.num_epochs) +print('decay_steps:', cfg.decay_steps) +print('input_size:', cfg.input_size) +print('backbone:', cfg.backbone) +print('pretrained:', cfg.pretrained) +print('criterion_cls:', cfg.criterion_cls) +print('criterion_reg:', cfg.criterion_reg) +print('cls_loss_weight:', cfg.cls_loss_weight) +print('reg_loss_weight:', cfg.reg_loss_weight) +print('num_lms:', cfg.num_lms) +print('save_interval:', cfg.save_interval) +print('num_nb:', cfg.num_nb) +print('use_gpu:', cfg.use_gpu) +print('gpu_id:', cfg.gpu_id) +print('curriculum:', cfg.curriculum) +print('###########################################') +logging.info('###########################################') +logging.info('experiment_name: {}'.format(cfg.experiment_name)) +logging.info('data_name: {}'.format(cfg.data_name)) +logging.info('det_head: {}'.format(cfg.det_head)) +logging.info('net_stride: {}'.format(cfg.net_stride)) +logging.info('batch_size: {}'.format(cfg.batch_size)) +logging.info('init_lr: {}'.format(cfg.init_lr)) +logging.info('num_epochs: {}'.format(cfg.num_epochs)) +logging.info('decay_steps: {}'.format(cfg.decay_steps)) +logging.info('input_size: {}'.format(cfg.input_size)) +logging.info('backbone: {}'.format(cfg.backbone)) +logging.info('pretrained: {}'.format(cfg.pretrained)) +logging.info('criterion_cls: {}'.format(cfg.criterion_cls)) +logging.info('criterion_reg: {}'.format(cfg.criterion_reg)) +logging.info('cls_loss_weight: {}'.format(cfg.cls_loss_weight)) +logging.info('reg_loss_weight: {}'.format(cfg.reg_loss_weight)) +logging.info('num_lms: {}'.format(cfg.num_lms)) +logging.info('save_interval: {}'.format(cfg.save_interval)) +logging.info('num_nb: {}'.format(cfg.num_nb)) +logging.info('use_gpu: {}'.format(cfg.use_gpu)) +logging.info('gpu_id: {}'.format(cfg.gpu_id)) +logging.info('###########################################') + +if cfg.curriculum: + # self-training with curriculum + task_type_list = ['cls3', 'cls2', 'std', 'std', 'std'] +else: + # standard self-training + task_type_list = ['std']*3 + +meanface_indices, reverse_index1, reverse_index2, max_len = get_meanface(os.path.join('data', cfg.data_name, 'meanface.txt'), cfg.num_nb) + +if cfg.det_head == 'pip': + if cfg.backbone == 'resnet18': + resnet18 = models.resnet18(pretrained=cfg.pretrained) + net = Pip_resnet18(resnet18, cfg.num_nb, num_lms=cfg.num_lms, input_size=cfg.input_size, net_stride=cfg.net_stride) + else: + print('No such backbone!') + exit(0) +else: + print('No such head:', cfg.det_head) + exit(0) + +if cfg.use_gpu: + device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") +else: + device = torch.device("cpu") +net = net.to(device) + +criterion_cls = None +if cfg.criterion_cls == 'l2': + criterion_cls = nn.MSELoss(reduction='sum') +elif cfg.criterion_cls == 'l1': + criterion_cls = nn.L1Loss() +else: + print('No such cls criterion:', cfg.criterion_cls) + +criterion_reg = None +if cfg.criterion_reg == 'l1': + criterion_reg = nn.L1Loss(reduction='sum') +elif cfg.criterion_reg == 'l2': + criterion_reg = nn.MSELoss() +else: + print('No such reg criterion:', cfg.criterion_reg) + +points_flip = [17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 28, 29, 30, 31, 36, 35, 34, 33, 32, 46, 45, 44, 43, 48, 47, 40, 39, 38, 37, 42, 41, 55, 54, 53, 52, 51, 50, 49, 60, 59, 58, 57, 56, 65, 64, 63, 62, 61, 68, 67, 66] +points_flip = (np.array(points_flip)-1).tolist() +assert len(points_flip) == 68 + +normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406], + std=[0.229, 0.224, 0.225]) + +optimizer = optim.Adam(net.parameters(), lr=cfg.init_lr) +scheduler = optim.lr_scheduler.MultiStepLR(optimizer, milestones=cfg.decay_steps, gamma=0.1) + +labels = get_label(cfg.data_name, 'train_300W.txt', 'std') + +train_data = data_utils_gssl.ImageFolder_pip(os.path.join('data', cfg.data_name, 'images_train'), + labels, cfg.input_size, cfg.num_lms, + cfg.net_stride, points_flip, meanface_indices, + transforms.Compose([ + transforms.RandomGrayscale(0.2), + transforms.ToTensor(), + normalize])) + +train_loader = torch.utils.data.DataLoader(train_data, batch_size=cfg.batch_size, shuffle=True, num_workers=8, pin_memory=True, drop_last=True) + +train_model(cfg.det_head, net, train_loader, criterion_cls, criterion_reg, cfg.cls_loss_weight, cfg.reg_loss_weight, cfg.num_nb, optimizer, cfg.num_epochs, scheduler, save_dir, cfg.save_interval, device) + +############### +# test +norm_indices = [36, 45] + +preprocess = transforms.Compose([transforms.Resize((cfg.input_size, cfg.input_size)), transforms.ToTensor(), normalize]) +test_data_list = ['300W', 'COFW', 'WFLW'] +for test_data in test_data_list: + labels = get_label(cfg.data_name, 'test_'+test_data+'.txt') + nmes = [] + norm = None + for label in labels: + image_name = label[0] + lms_gt = label[1] + image_path = os.path.join('data', cfg.data_name, 'images_test_'+test_data, image_name) + image = cv2.imread(image_path) + image = cv2.resize(image, (cfg.input_size, cfg.input_size)) + inputs = Image.fromarray(image[:,:,::-1].astype('uint8'), 'RGB') + inputs = preprocess(inputs).unsqueeze(0) + inputs = inputs.to(device) + lms_pred_x, lms_pred_y, lms_pred_nb_x, lms_pred_nb_y, outputs_cls, max_cls = forward_pip(net, inputs, preprocess, cfg.input_size, cfg.net_stride, cfg.num_nb) + # inter-ocular + norm = np.linalg.norm(lms_gt.reshape(-1, 2)[norm_indices[0]] - lms_gt.reshape(-1, 2)[norm_indices[1]]) + ############################# + # merge neighbor predictions + lms_pred = torch.cat((lms_pred_x, lms_pred_y), dim=1).flatten().cpu().numpy() + tmp_nb_x = lms_pred_nb_x[reverse_index1, reverse_index2].view(cfg.num_lms, max_len) + tmp_nb_y = lms_pred_nb_y[reverse_index1, reverse_index2].view(cfg.num_lms, max_len) + tmp_x = torch.mean(torch.cat((lms_pred_x, tmp_nb_x), dim=1), dim=1).view(-1,1) + tmp_y = torch.mean(torch.cat((lms_pred_y, tmp_nb_y), dim=1), dim=1).view(-1,1) + lms_pred_merge = torch.cat((tmp_x, tmp_y), dim=1).flatten().cpu().numpy() + ############################# + nme = compute_nme(lms_pred_merge, lms_gt, norm) + nmes.append(nme) + + print('{} nme: {}'.format(test_data, np.mean(nmes))) + logging.info('{} nme: {}'.format(test_data, np.mean(nmes))) + +for ti, task_type in enumerate(task_type_list): + print('###################################################') + print('Iter:', ti, 'task_type:', task_type) + ############### + # estimate + if cfg.data_name == 'data_300W_COFW_WFLW': + est_data_list = ['COFW', 'WFLW'] + elif cfg.data_name == 'data_300W_CELEBA': + est_data_list = ['CELEBA'] + else: + print('No such data!') + exit(0) + est_preds = [] + for est_data in est_data_list: + labels = get_label(cfg.data_name, 'train_'+est_data+'.txt') + for label in labels: + image_name = label[0] + #print(image_name) + image_path = os.path.join('data', cfg.data_name, 'images_train', image_name) + image = cv2.imread(image_path) + image = cv2.resize(image, (cfg.input_size, cfg.input_size)) + inputs = Image.fromarray(image[:,:,::-1].astype('uint8'), 'RGB') + inputs = preprocess(inputs).unsqueeze(0) + inputs = inputs.to(device) + lms_pred_x, lms_pred_y, lms_pred_nb_x, lms_pred_nb_y, outputs_cls, max_cls = forward_pip(net, inputs, preprocess, cfg.input_size, cfg.net_stride, cfg.num_nb) + ############################# + # merge neighbor predictions + lms_pred = torch.cat((lms_pred_x, lms_pred_y), dim=1).flatten().cpu().numpy() + tmp_nb_x = lms_pred_nb_x[reverse_index1, reverse_index2].view(cfg.num_lms, max_len) + tmp_nb_y = lms_pred_nb_y[reverse_index1, reverse_index2].view(cfg.num_lms, max_len) + tmp_x = torch.mean(torch.cat((lms_pred_x, tmp_nb_x), dim=1), dim=1).view(-1,1) + tmp_y = torch.mean(torch.cat((lms_pred_y, tmp_nb_y), dim=1), dim=1).view(-1,1) + lms_pred_merge = torch.cat((tmp_x, tmp_y), dim=1).flatten().cpu().numpy() + ############################# + est_preds.append([image_name, task_type, lms_pred_merge]) + + ################ + # GSSL + if cfg.det_head == 'pip': + if cfg.backbone == 'resnet18': + resnet18 = models.resnet18(pretrained=cfg.pretrained) + net = Pip_resnet18(resnet18, cfg.num_nb, num_lms=cfg.num_lms, input_size=cfg.input_size, net_stride=cfg.net_stride) + else: + print('No such backbone!') + exit(0) + else: + print('No such head:', cfg.det_head) + exit(0) + + net = net.to(device) + optimizer = optim.Adam(net.parameters(), lr=cfg.init_lr) + scheduler = optim.lr_scheduler.MultiStepLR(optimizer, milestones=cfg.decay_steps, gamma=0.1) + labels = get_label(cfg.data_name, 'train_300W.txt', 'std') + labels += est_preds + + train_data = data_utils_gssl.ImageFolder_pip(os.path.join('data', cfg.data_name, 'images_train'), + labels, cfg.input_size, cfg.num_lms, + cfg.net_stride, points_flip, meanface_indices, + transforms.Compose([ + transforms.RandomGrayscale(0.2), + transforms.ToTensor(), + normalize])) + + train_loader = torch.utils.data.DataLoader(train_data, batch_size=cfg.batch_size, shuffle=True, num_workers=8, pin_memory=True, drop_last=True) + + train_model(cfg.det_head, net, train_loader, criterion_cls, criterion_reg, cfg.cls_loss_weight, cfg.reg_loss_weight, cfg.num_nb, optimizer, cfg.num_epochs, scheduler, save_dir, cfg.save_interval, device) + + ############### + # test + preprocess = transforms.Compose([transforms.Resize((cfg.input_size, cfg.input_size)), transforms.ToTensor(), normalize]) + test_data_list = ['300W', 'COFW', 'WFLW'] + for test_data in test_data_list: + labels = get_label(cfg.data_name, 'test_'+test_data+'.txt') + nmes = [] + norm = None + for label in labels: + image_name = label[0] + lms_gt = label[1] + image_path = os.path.join('data', cfg.data_name, 'images_test_'+test_data, image_name) + image = cv2.imread(image_path) + image = cv2.resize(image, (cfg.input_size, cfg.input_size)) + inputs = Image.fromarray(image[:,:,::-1].astype('uint8'), 'RGB') + inputs = preprocess(inputs).unsqueeze(0) + inputs = inputs.to(device) + lms_pred_x, lms_pred_y, lms_pred_nb_x, lms_pred_nb_y, outputs_cls, max_cls = forward_pip(net, inputs, preprocess, cfg.input_size, cfg.net_stride, cfg.num_nb) + # inter-ocular + norm = np.linalg.norm(lms_gt.reshape(-1, 2)[norm_indices[0]] - lms_gt.reshape(-1, 2)[norm_indices[1]]) + ############################# + # merge neighbor predictions + lms_pred = torch.cat((lms_pred_x, lms_pred_y), dim=1).flatten().cpu().numpy() + tmp_nb_x = lms_pred_nb_x[reverse_index1, reverse_index2].view(cfg.num_lms, max_len) + tmp_nb_y = lms_pred_nb_y[reverse_index1, reverse_index2].view(cfg.num_lms, max_len) + tmp_x = torch.mean(torch.cat((lms_pred_x, tmp_nb_x), dim=1), dim=1).view(-1,1) + tmp_y = torch.mean(torch.cat((lms_pred_y, tmp_nb_y), dim=1), dim=1).view(-1,1) + lms_pred_merge = torch.cat((tmp_x, tmp_y), dim=1).flatten().cpu().numpy() + ############################# + nme = compute_nme(lms_pred_merge, lms_gt, norm) + nmes.append(nme) + + print('{} nme: {}'.format(test_data, np.mean(nmes))) + logging.info('{} nme: {}'.format(test_data, np.mean(nmes))) + + diff --git a/src/pixel3dmm/preprocessing/PIPNet/requirements.txt b/src/pixel3dmm/preprocessing/PIPNet/requirements.txt new file mode 100644 index 0000000000000000000000000000000000000000..22ddb050a36ae15e848c827d097fa2549c57f460 --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/requirements.txt @@ -0,0 +1,3 @@ +opencv-python +scipy +Cython diff --git a/src/pixel3dmm/preprocessing/PIPNet/run_demo.sh b/src/pixel3dmm/preprocessing/PIPNet/run_demo.sh new file mode 100644 index 0000000000000000000000000000000000000000..c45d630a56d3c117227da5a7c41b51a90d3f9144 --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/run_demo.sh @@ -0,0 +1,11 @@ +# image +python lib/demo.py experiments/WFLW/pip_32_16_60_r18_l2_l1_10_1_nb10.py images/1.jpg +#python lib/demo.py experiments/data_300W_CELEBA/pip_32_16_60_r18_l2_l1_10_1_nb10_wcc.py images/2.jpg + +# video +#python lib/demo_video.py experiments/WFLW/pip_32_16_60_r18_l2_l1_10_1_nb10.py videos/002.avi +#python lib/demo_video.py experiments/data_300W_CELEBA/pip_32_16_60_r18_l2_l1_10_1_nb10_wcc.py videos/007.avi + +# camera +#python lib/demo_video.py experiments/WFLW/pip_32_16_60_r18_l2_l1_10_1_nb10.py camera + diff --git a/src/pixel3dmm/preprocessing/PIPNet/run_test.sh b/src/pixel3dmm/preprocessing/PIPNet/run_test.sh new file mode 100644 index 0000000000000000000000000000000000000000..c81b0a03155df79d38b149a86956ca82a3f339d4 --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/run_test.sh @@ -0,0 +1,34 @@ +# supervised learning + +# 300W, resnet18 +#python lib/test.py experiments/data_300W/pip_32_16_60_r18_l2_l1_10_1_nb10.py test.txt images_test +# 300W, resnet101 +#python lib/test.py experiments/data_300W/pip_32_16_60_r101_l2_l1_10_1_nb10.py test.txt images_test + +# COFW, resnet18 +#python lib/test.py experiments/COFW/pip_32_16_60_r18_l2_l1_10_1_nb10.py test.txt images_test +# COFW, resnet101 +#python lib/test.py experiments/COFW/pip_32_16_60_r101_l2_l1_10_1_nb10.py test.txt images_test + +# WFLW, resnet18 +#python lib/test.py experiments/WFLW/pip_32_16_60_r18_l2_l1_10_1_nb10.py test.txt images_test +# WFLW, resnet101 +#python lib/test.py experiments/WFLW/pip_32_16_60_r101_l2_l1_10_1_nb10.py test.txt images_test + +# AFLW, resnet18 +#python lib/test.py experiments/AFLW/pip_32_16_60_r18_l2_l1_10_1_nb10.py test.txt images_test +# AFLW, resnet101 +#python lib/test.py experiments/AFLW/pip_32_16_60_r101_l2_l1_10_1_nb10.py test.txt images_test + +###################################################################################### +# GSSL + +# 300W + COFW_68 (unlabeled) + WFLW_68 (unlabeled), resnet18, with curriculum +#python lib/test.py experiments/data_300W_COFW_WFLW/pip_32_16_60_r18_l2_l1_10_1_nb10_wcc.py test_300W.txt images_test_300W +#python lib/test.py experiments/data_300W_COFW_WFLW/pip_32_16_60_r18_l2_l1_10_1_nb10_wcc.py test_COFW.txt images_test_COFW +#python lib/test.py experiments/data_300W_COFW_WFLW/pip_32_16_60_r18_l2_l1_10_1_nb10_wcc.py test_WFLW.txt images_test_WFLW + +# 300W + CelebA (unlabeled), resnet18, with curriculum +#python lib/test.py experiments/data_300W_CELEBA/pip_32_16_60_r18_l2_l1_10_1_nb10_wcc.py test_300W.txt images_test_300W +#python lib/test.py experiments/data_300W_CELEBA/pip_32_16_60_r18_l2_l1_10_1_nb10_wcc.py test_COFW.txt images_test_COFW +#python lib/test.py experiments/data_300W_CELEBA/pip_32_16_60_r18_l2_l1_10_1_nb10_wcc.py test_WFLW.txt images_test_WFLW diff --git a/src/pixel3dmm/preprocessing/PIPNet/run_train.sh b/src/pixel3dmm/preprocessing/PIPNet/run_train.sh new file mode 100644 index 0000000000000000000000000000000000000000..7fce31dad1055e1a05503ebcf3b8538493ff0899 --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/run_train.sh @@ -0,0 +1,33 @@ +###################################################################################### +# supervised learning + +# 300W, resnet18 +#python lib/train.py experiments/data_300W/pip_32_16_60_r18_l2_l1_10_1_nb10.py +# 300W, resnet101 +#python lib/train.py experiments/data_300W/pip_32_16_60_r101_l2_l1_10_1_nb10.py + +# COFW, resnet18 +#python lib/train.py experiments/COFW/pip_32_16_60_r18_l2_l1_10_1_nb10.py +# COFW, resnet101 +#python lib/train.py experiments/COFW/pip_32_16_60_r101_l2_l1_10_1_nb10.py + +# WFLW, resnet18 +#python lib/train.py experiments/WFLW/pip_32_16_60_r18_l2_l1_10_1_nb10.py +# WFLW, resnet101 +#python lib/train.py experiments/WFLW/pip_32_16_60_r101_l2_l1_10_1_nb10.py + +# AFLW, resnet18 +#python lib/train.py experiments/AFLW/pip_32_16_60_r18_l2_l1_10_1_nb10.py +# AFLW, resnet101 +#python lib/train.py experiments/AFLW/pip_32_16_60_r101_l2_l1_10_1_nb10.py + +###################################################################################### +# GSSL + +# 300W + COFW_68 (unlabeled) + WFLW_68 (unlabeled), resnet18, with curriculum +#python lib/train_gssl.py experiments/data_300W_COFW_WFLW/pip_32_16_60_r18_l2_l1_10_1_nb10_wcc.py + +# 300W + CelebA (unlabeled), resnet18, with curriculum +#nohup python lib/train_gssl.py experiments/data_300W_CELEBA/pip_32_16_60_r18_l2_l1_10_1_nb10_wcc.py & + + diff --git a/src/pixel3dmm/preprocessing/PIPNet/videos/002.avi b/src/pixel3dmm/preprocessing/PIPNet/videos/002.avi new file mode 100644 index 0000000000000000000000000000000000000000..41b734ea5a564c68aca417133bb2bdc5f9020c0d --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/videos/002.avi @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:680f59aaacc3099f49aead21b3bc7a4a3233dcaea03a8cf495169ce02c4482be +size 17998608 diff --git a/src/pixel3dmm/preprocessing/PIPNet/videos/002_out_WFLW_model.gif b/src/pixel3dmm/preprocessing/PIPNet/videos/002_out_WFLW_model.gif new file mode 100644 index 0000000000000000000000000000000000000000..d5142e424ed1bc2ff8f6951fdd33ee6b7a4299f0 --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/videos/002_out_WFLW_model.gif @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:77893e13d90aa5e8c8d188030f9e9f7a7f6d6c594d3d244cf9dfaf17db6f8451 +size 20191453 diff --git a/src/pixel3dmm/preprocessing/PIPNet/videos/007.avi b/src/pixel3dmm/preprocessing/PIPNet/videos/007.avi new file mode 100644 index 0000000000000000000000000000000000000000..f6a4bf2ab97fd5000bfdc0ed13c47807edd5beec --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/videos/007.avi @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d1ae6da9e0fda8132e538c31ca22423da41a16c896eb007bff921719a2da66f5 +size 20941516 diff --git a/src/pixel3dmm/preprocessing/PIPNet/videos/007_out_300W_CELEBA_model.gif b/src/pixel3dmm/preprocessing/PIPNet/videos/007_out_300W_CELEBA_model.gif new file mode 100644 index 0000000000000000000000000000000000000000..9f220a66b6995496be8d2c55fb50ded2d402d60c --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/videos/007_out_300W_CELEBA_model.gif @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8549d4d312cc16497ef33b94ae00738ec018257bdca89f195e11c973b8f71e4b +size 19706169 diff --git a/src/pixel3dmm/preprocessing/PIPNet/videos/shaolin_soccer.gif b/src/pixel3dmm/preprocessing/PIPNet/videos/shaolin_soccer.gif new file mode 100644 index 0000000000000000000000000000000000000000..d6b5ccc53a949f13019f7675ceb2926ca6765e56 --- /dev/null +++ b/src/pixel3dmm/preprocessing/PIPNet/videos/shaolin_soccer.gif @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3bfbbb9cceb8afceb4b56d1c18d011749f20b0fad3867c0e16c9ca8d78529a85 +size 14740557