From 446becbce02ef8c33f79e159a86b7e0287deb0ba Mon Sep 17 00:00:00 2001 From: Olegs NIKISINS <onikisins@italix03.idiap.ch> Date: Fri, 13 Oct 2017 16:18:09 +0200 Subject: [PATCH] Added unit tests for classes used in the IQM-GMM pad algorithm --- bob/pad/face/test/test.py | 120 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) diff --git a/bob/pad/face/test/test.py b/bob/pad/face/test/test.py index 160fbdc9..06dcf820 100644 --- a/bob/pad/face/test/test.py +++ b/bob/pad/face/test/test.py @@ -29,8 +29,12 @@ from ..extractor import FrameDiffFeatures from ..extractor import VideoLBPHistogram +from ..extractor import VideoQualityMeasure + from ..algorithm import VideoSvmPadAlgorithm +from ..algorithm import VideoGmmPadAlgorithm + import random #============================================================================== @@ -149,6 +153,43 @@ def test_video_face_crop(): assert np.sum(faces[0][1]) == 429158 assert np.sum(faces[-1][1]) == 429158 + #========================================================================== + # test another configuration of the VideoFaceCrop preprocessor: + + CROPPED_IMAGE_SIZE = (64, 64) # The size of the resulting face + CROPPED_POSITIONS = {'topleft' : (0,0) , 'bottomright' : CROPPED_IMAGE_SIZE} + FIXED_POSITIONS = None + MASK_SIGMA = None # The sigma for random values areas outside image + MASK_NEIGHBORS = 5 # The number of neighbors to consider while extrapolating + MASK_SEED = None # The seed for generating random values during extrapolation + CHECK_FACE_SIZE_FLAG = True # Check the size of the face + MIN_FACE_SIZE = 50 + USE_LOCAL_CROPPER_FLAG = True # Use the local face cropping class (identical to Ivana's paper) + RGB_OUTPUT_FLAG = True # Return RGB cropped face using local cropper + DETECT_FACES_FLAG = True # find annotations locally replacing the database annotations + + preprocessor = VideoFaceCrop(cropped_image_size = CROPPED_IMAGE_SIZE, + cropped_positions = CROPPED_POSITIONS, + fixed_positions = FIXED_POSITIONS, + mask_sigma = MASK_SIGMA, + mask_neighbors = MASK_NEIGHBORS, + mask_seed = None, + check_face_size_flag = CHECK_FACE_SIZE_FLAG, + min_face_size = MIN_FACE_SIZE, + use_local_cropper_flag = USE_LOCAL_CROPPER_FLAG, + rgb_output_flag = RGB_OUTPUT_FLAG, + detect_faces_flag = DETECT_FACES_FLAG) + + video, _ = convert_image_to_video_data(image, annotations, 3) + + faces = preprocessor(frames = video, annotations = annotations) + + assert len(faces) == 3 + assert faces[0][1].shape == (3, 64, 64) + assert faces[-1][1].shape == (3, 64, 64) + assert np.sum(faces[0][1]) == 1253048 + assert np.sum(faces[-1][1]) == 1253048 + #============================================================================== def test_frame_difference(): @@ -261,6 +302,34 @@ def test_video_lbp_histogram(): assert (lbp_histograms[0][1][-1] - 0.031737773152965658) < 0.000001 +#============================================================================== +def test_video_quality_measure(): + """ + Test VideoQualityMeasure extractor. + """ + + image = load(datafile('test_image.png', 'bob.pad.face.test')) + annotations = {'topleft': (95, 155), 'bottomright': (215, 265)} + + video, annotations = convert_image_to_video_data(image, annotations, 2) + + GALBALLY=True + MSU=True + DTYPE=None + + extractor = VideoQualityMeasure(galbally=GALBALLY, + msu=MSU, + dtype=DTYPE) + + features = extractor(video) + + assert len(features) == 2 + assert len(features[0][1]) == 139 + assert (features[0][1]==features[-1][1]).all() + assert (features[0][1][0] - 2.7748559659812599e-05) < 0.000001 + assert (features[0][1][-1] - 0.16410418866596271) < 0.000001 + + #============================================================================== def convert_array_to_list_of_frame_cont(data): """ @@ -350,6 +419,57 @@ def test_video_svm_pad_algorithm(): assert precision > 0.99 +#============================================================================== +def test_video_gmm_pad_algorithm(): + """ + Test the VideoGmmPadAlgorithm algorithm. + """ + + random.seed(7) + + N = 1000 + mu = 1 + sigma = 1 + real_array = np.transpose( np.vstack([[random.gauss(mu, sigma) for _ in range(N)], [random.gauss(mu, sigma) for _ in range(N)]]) ) + + mu = 5 + sigma = 1 + attack_array = np.transpose( np.vstack([[random.gauss(mu, sigma) for _ in range(N)], [random.gauss(mu, sigma) for _ in range(N)]]) ) + + real = convert_array_to_list_of_frame_cont(real_array) + + N_COMPONENTS = 1 + RANDOM_STATE = 3 + FRAME_LEVEL_SCORES_FLAG = True + + algorithm = VideoGmmPadAlgorithm(n_components = N_COMPONENTS, + random_state = RANDOM_STATE, + frame_level_scores_flag = FRAME_LEVEL_SCORES_FLAG) + + # training_features[0] - training features for the REAL class. + real_array_converted = algorithm.convert_list_of_frame_cont_to_array(real) # output is array + + assert (real_array == real_array_converted).all() + + # Train the GMM machine and get normalizers: + machine, features_mean, features_std = algorithm.train_gmm(real = real_array_converted, + n_components = algorithm.n_components, + random_state = algorithm.random_state) + + algorithm.machine = machine + + algorithm.features_mean = features_mean + + algorithm.features_std = features_std + + scores_real = algorithm.project(real_array_converted) + + scores_attack = algorithm.project(attack_array) + + assert (np.min(scores_real) + 7.9423798970985917) < 0.000001 + assert (np.max(scores_real) + 1.8380480068281055) < 0.000001 + assert (np.min(scores_attack) + 38.831260843070098) < 0.000001 + assert (np.max(scores_attack) + 5.3633030621521272) < 0.000001 -- GitLab