diff --git a/bob/paper/nir_patch_pooling/config/patch_pooling_lr.py b/bob/paper/nir_patch_pooling/config/patch_pooling_lr.py index eba399526c8e57afcc0885eaeee144665a65644d..d8f89b861231b3ef9ec9762f29834d074e015f2e 100644 --- a/bob/paper/nir_patch_pooling/config/patch_pooling_lr.py +++ b/bob/paper/nir_patch_pooling/config/patch_pooling_lr.py @@ -22,15 +22,13 @@ FACE_SIZE = 128 RGB_OUTPUT_FLAG = False USE_FACE_ALIGNMENT = True ALIGNMENT_TYPE = "lightcnn" -MIN_FACE_SIZE = 50 NORMALIZATION_FUNCTION = _norm_func -NORMALIZATION_FUNCTION_KWARGS = {'n_sigma':3.0, 'norm_method':'MAD'} +NORMALIZATION_FUNCTION_KWARGS = {'n_sigma':4.0, 'norm_method':'MAD'} _image_preprocessor = FaceCropAlign(face_size=FACE_SIZE, rgb_output_flag=RGB_OUTPUT_FLAG, use_face_alignment=USE_FACE_ALIGNMENT, alignment_type=ALIGNMENT_TYPE, - min_face_size=MIN_FACE_SIZE, normalization_function = NORMALIZATION_FUNCTION, normalization_function_kwargs = NORMALIZATION_FUNCTION_KWARGS) diff --git a/bob/paper/nir_patch_pooling/config/run.sh b/bob/paper/nir_patch_pooling/config/run.sh index 38606a48d3e46ef63cfb247ccb3de12498e02f7d..9659f6c7ce32068e7a5e85a45c4f29ce6f8bc45a 100755 --- a/bob/paper/nir_patch_pooling/config/run.sh +++ b/bob/paper/nir_patch_pooling/config/run.sh @@ -7,7 +7,7 @@ echo "-----------------------------------" expt="wmca" -base_directory="/idiap/temp/kkotwal/icip20/expt" +base_directory="/idiap/temp/kkotwal/test_icip/expt" # expt: WMCA if [[ "${expt}" == "wmca" ]]; then diff --git a/bob/paper/nir_patch_pooling/extractor/__init__.py b/bob/paper/nir_patch_pooling/extractor/__init__.py index bb19ad5c71fc252538fbb58e5f10acc6510c56bf..c4fb95e0731ee4634b4c4823c7e7491f6b6cbc32 100644 --- a/bob/paper/nir_patch_pooling/extractor/__init__.py +++ b/bob/paper/nir_patch_pooling/extractor/__init__.py @@ -1,2 +1,2 @@ +from .lightcnn9 import LightCNN9 from .patch_pooling_cnn import PatchPoolingCNN - diff --git a/bob/paper/nir_patch_pooling/extractor/lightcnn9.py b/bob/paper/nir_patch_pooling/extractor/lightcnn9.py new file mode 100644 index 0000000000000000000000000000000000000000..4038727f22d2cc4c318634b60bc8343baaa484f6 --- /dev/null +++ b/bob/paper/nir_patch_pooling/extractor/lightcnn9.py @@ -0,0 +1,78 @@ +''' + implement Light CNN + @author: Alfred Xiang Wu + @date: 2017.07.04 +''' + +import math +import torch +import torch.nn as nn +import torch.nn.functional as F + +#------------------------------------------------------------------------------ + +class mfm(nn.Module): + def __init__(self, in_channels, out_channels, kernel_size=3, stride=1, padding=1, type=1): + super(mfm, self).__init__() + self.out_channels = out_channels + if type == 1: + self.filter = nn.Conv2d(in_channels, 2*out_channels, kernel_size=kernel_size, stride=stride, padding=padding) + else: + self.filter = nn.Linear(in_channels, 2*out_channels) + + def forward(self, x): + x = self.filter(x) + out = torch.split(x, self.out_channels, 1) + return torch.max(out[0], out[1]) + +#------------------------------------------------------------------------------ + +class group(nn.Module): + def __init__(self, in_channels, out_channels, kernel_size, stride, padding): + super(group, self).__init__() + self.conv_a = mfm(in_channels, in_channels, 1, 1, 0) + self.conv = mfm(in_channels, out_channels, kernel_size, stride, padding) + + def forward(self, x): + x = self.conv_a(x) + x = self.conv(x) + return x + +#------------------------------------------------------------------------------ + +class LightCNN9(nn.Module): + + def __init__(self, num_classes=79077): + + super(LightCNN9, self).__init__() + self.features = nn.Sequential( + mfm(1, 48, 5, 1, 2), + nn.MaxPool2d(kernel_size=2, stride=2, ceil_mode=True), + group(48, 96, 3, 1, 1), + nn.MaxPool2d(kernel_size=2, stride=2, ceil_mode=True), + group(96, 192, 3, 1, 1), + nn.MaxPool2d(kernel_size=2, stride=2, ceil_mode=True), + group(192, 128, 3, 1, 1), + group(128, 128, 3, 1, 1), + nn.MaxPool2d(kernel_size=2, stride=2, ceil_mode=True), + ) + self.fc1 = mfm(8*8*128, 256, type=0) + self.fc2 = nn.Linear(256, num_classes) + self.sigmoid = nn.Sigmoid() + + def forward(self, x): + + x = self.features(x) + x = x.view(x.size(0), -1) + + x = self.fc1(x) + x = F.dropout(x, p=0.5, training=self.training) + scores = self.fc2(x) + scores = self.sigmoid(scores) + + # scores, features + return scores, x + +#------------------------------------------------------------------------------ + + diff --git a/bob/paper/nir_patch_pooling/extractor/patch_pooling_cnn.py b/bob/paper/nir_patch_pooling/extractor/patch_pooling_cnn.py index 0cc37dde0c416b18da5f5247d6303845957c9b49..33e807d19c227ca4ddcf0e7e8e5eccb7aba2ec5b 100644 --- a/bob/paper/nir_patch_pooling/extractor/patch_pooling_cnn.py +++ b/bob/paper/nir_patch_pooling/extractor/patch_pooling_cnn.py @@ -12,7 +12,7 @@ from PIL import Image import torch.nn.functional as F from torch.autograd import Variable import torchvision.transforms as transforms -from bob.learn.pytorch.architectures import LightCNN9 +from bob.paper.nir_patch_pooling.extractor import LightCNN9 from bob.bio.base.extractor import Extractor import logging diff --git a/bob/paper/nir_patch_pooling/script/annotate_database.py b/bob/paper/nir_patch_pooling/script/annotate_database.py index 5ab78009fdf1d1d8a9698a73b79e9c1728b0a6d8..013d3be8d8932206ef8a334e16259be9c14145e6 100755 --- a/bob/paper/nir_patch_pooling/script/annotate_database.py +++ b/bob/paper/nir_patch_pooling/script/annotate_database.py @@ -12,7 +12,7 @@ from bob.io.base import create_directories_safe import numpy as np import json import os, sys - +from bob.paper.nir_patch_pooling.config.wmca_mask import database as d1 #------------------------------------------------------------------------------ class Annotator: @@ -32,18 +32,18 @@ class Annotator: # find annotations using MTCNN frame_annotations = detect_face_landmarks_in_image(image, method="mtcnn") if frame_annotations: - logger.debug(" --> Found using MTCNN") + #print(" --> Found using MTCNN") return frame_annotations # else, find annotations using dlib frame_annotations = detect_face_landmarks_in_image(image, method="dlib") if frame_annotations: - logger.debug(" --> Found using dlib") + print(" --> Found using dlib") return frame_annotations # else, return empty dictionary with warning - logger.warning(" --> Could not find annotations") - return {} + print(" --> Could not find annotations") + return None #------------------------------------------------------------------------------ @@ -85,21 +85,22 @@ class Annotator: frame_annotations = self.find_annotations(image) except Exception as e: - logger.error("\tException: {}".format(e)) + print("\tException: {}".format(e)) # copy annotations of previous frame if (prev_valid_index is not None): frame_annotations = annotations[prev_valid_index] - logger.warning("\tCopying annotations of valid previous frame") + print("\tCopying annotations of valid previous frame") else: - frame_annotations = {} - logger.warning("\tSetting empty annotations") + frame_annotations = None + print("\tSetting empty annotations") - annotations[str(index)] = frame_annotations - prev_valid_index = str(index) + if frame_annotations is not None: + annotations[str(index)] = frame_annotations + prev_valid_index = str(index) return annotations @@ -117,7 +118,7 @@ class AnnotationGenerator: if not os.path.exists(self.annotation_directory): os.makedirs(self.annotation_directory) - logger.warning("Annotation directory created at: {}"\ + print("Annotation directory created at: {}"\ .format(self.annotation_directory)) self.annotator = Annotator() @@ -166,14 +167,14 @@ class AnnotationGenerator: # process each video in the given range for idx, f in enumerate(self.filelist[start_index:end_index]): - logger.info("[{:03d}/{:03d}] Sample: {}".format(idx+1, total, f.path)) + print("[{:03d}/{:03d}] Sample: {}".format(idx+1, total, f.path)) json_filepath = os.path.join(self.annotation_directory, f.path + ".json") if not os.path.exists(json_filepath): self.process_video(f) else: - logger.info("Annotations exist: {}. Skipping".format(f.path)) + print("Annotations exist: {}. Skipping".format(f.path)) return @@ -187,7 +188,7 @@ def main(): .format(__name__)) exit(0) - database = sys.argv[1] + database = d1 # sys.argv[1] annotation_directory = sys.argv[2] print("Database: {}. Annotation directory: {}".format(database,\ annotation_directory)) diff --git a/bob/paper/nir_patch_pooling/script/convert_mlfp_database.py b/bob/paper/nir_patch_pooling/script/convert_mlfp_database.py index c6d4f80279cf8041e5904e167c18c8b182912d9f..d451f5fce41a910e0b3a5f3f197ae852db3e1447 100755 --- a/bob/paper/nir_patch_pooling/script/convert_mlfp_database.py +++ b/bob/paper/nir_patch_pooling/script/convert_mlfp_database.py @@ -13,10 +13,6 @@ import numpy as np from bob.pad.face.preprocessor.FaceCropAlign import detect_face_landmarks_in_image import json -import logging -logger = logging.getLogger(__name__) -logger.setLevel(logging.INFO) - frames_per_video = 20 #------------------------------------------------------------------------------ @@ -99,20 +95,20 @@ class MLFPConvertor: frame_annotations = self.find_annotations(image) except Exception as e: - logger.error("\tException: {}".format(e)) + print(" --> Exception: {}".format(e)) # copy annotations of previous frame if (prev_index is not None): frame_annotations = annotations[prev_index] - logger.warning("\tCopying annotations of previous frame") - print("\tCopying annotations of previous frame") + print(" --> Copying annotations of previous frame") else: - frame_annotations = {} - logger.warning("\tSetting empty annotations") + frame_annotations = None + print(" --> No annotations") - annotations[str(index)] = frame_annotations - prev_index = str(index) + if frame_annotations is not None: + annotations[str(index)] = frame_annotations + prev_index = str(index) return annotations @@ -128,18 +124,18 @@ class MLFPConvertor: # find annotations using MTCNN frame_annotations = detect_face_landmarks_in_image(image, method="mtcnn") if frame_annotations: - logger.debug(" --> Found using MTCNN") + #print(" --> Found using MTCNN") return frame_annotations # else, find annotations using dlib frame_annotations = detect_face_landmarks_in_image(image, method="dlib") if frame_annotations: - logger.debug(" --> Found using dlib") + #print(" --> Found using dlib") return frame_annotations # else, return empty dictionary with warning - logger.warning(" --> Could not find annotations") - return {} + print(" --> Could not find annotations") + return None #------------------------------------------------------------------------------ diff --git a/buildout.cfg b/buildout.cfg index 5f27ead5ccda76a715165bec58ddeaf03047bbe6..b0fb5963ba739d7575a655ba018d260c8b4e97d5 100644 --- a/buildout.cfg +++ b/buildout.cfg @@ -13,8 +13,9 @@ verbose = true develop = . -eggs = bob.paper.nir_patch_pooling +eggs = bob.pad.base bob.db.batl + bob.paper.nir_patch_pooling [sources] bob.db.batl = git git@gitlab.idiap.ch:bob/bob.db.batl rev=5fecee9158832516c560d000a71ae7272d640506 diff --git a/setup.py b/setup.py index 28f823c182600a89d4d89acf48e16b37fa667b5c..f2b9b4f96a2673d3bce70d48ad4453c0f27d83be 100644 --- a/setup.py +++ b/setup.py @@ -34,7 +34,12 @@ setup( install_requires=install_requires, entry_points={ - # mlfp, wmca-mask, expt-patch-pooling + 'bob.bio.config': [ + 'wmca-mask = bob.paper.nir_patch_pooling.config.wmca_mask', + 'mlfp = bob.paper.nir_patch_pooling.config.mlfp', + 'patch-pooling-lr = bob.paper.nir_patch_pooling.config.patch_pooling_lr', + ], + }, # check classifiers, add and remove as you see fit