2 Copyright (c) 2019 Intel Corporation
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
8 http://www.apache.org/licenses/LICENSE-2.0
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
21 from accuracy_checker.config import ConfigError
22 from accuracy_checker.preprocessor import (
33 from accuracy_checker.preprocessor.preprocessing_executor import PreprocessingExecutor
34 from accuracy_checker.dataset import DataRepresentation
38 def test_default_resize(self, mocker):
39 cv2_resize_mock = mocker.patch('accuracy_checker.preprocessor.preprocessors.cv2.resize')
40 resize = Preprocessor.provide('resize', {'type': 'resize', 'size': 200})
42 input_mock = mocker.Mock()
43 resize(DataRepresentation(input_mock))
45 assert not resize.use_pil
46 assert resize.dst_width == 200
47 assert resize.dst_height == 200
48 cv2_resize_mock.assert_called_once_with(
49 input_mock, (200, 200), interpolation=Resize.OPENCV_INTERPOLATION['LINEAR']
52 def test_custom_resize(self, mocker):
53 cv2_resize_mock = mocker.patch('accuracy_checker.preprocessor.preprocessors.cv2.resize')
55 resize = Preprocessor.provide(
56 'resize', {'type': 'resize', 'dst_width': 126, 'dst_height': 128, 'interpolation': 'CUBIC'}
59 input_mock = mocker.Mock()
60 resize(DataRepresentation(input_mock))
62 assert not resize.use_pil
63 assert resize.dst_width == 126
64 assert resize.dst_height == 128
65 cv2_resize_mock.assert_called_once_with(
66 input_mock, (126, 128),
67 interpolation=Resize.OPENCV_INTERPOLATION['CUBIC']
70 def test_resize_without_save_aspect_ratio(self):
71 name = 'mock_preprocessor'
72 config = {'type': 'resize', 'dst_width': 150, 'dst_height': 150}
73 input_image = np.ones((100, 50, 3))
74 resize = Preprocessor.provide('resize', config, name)
76 result = resize(DataRepresentation(input_image)).data
78 assert result.shape == (150, 150, 3)
80 def test_resize_save_aspect_ratio_unknown_raise_config_error(self):
81 with pytest.raises(ConfigError):
83 'resize', {'type': 'resize', 'dst_width': 100, 'dst_height': 150, 'aspect_ratio_scale': 'unknown'}
86 def test_resize_save_aspect_ratio_height(self):
87 input_image = np.ones((100, 50, 3))
88 resize = Preprocessor.provide('resize', {
89 'type': 'resize', 'dst_width': 100, 'dst_height': 150,
90 'interpolation': 'CUBIC', 'aspect_ratio_scale': 'height'
92 result = resize(DataRepresentation(input_image)).data
94 assert result.shape == (300, 100, 3)
96 def test_resize_save_aspect_ratio_width(self):
97 input_image = np.ones((100, 50, 3))
98 resize = Preprocessor.provide('resize', {
99 'type': 'resize', 'dst_width': 150, 'dst_height': 150, 'aspect_ratio_scale': 'width'
101 result = resize(DataRepresentation(input_image)).data
103 assert result.shape == (150, 75, 3)
105 def test_resize_save_aspect_ratio_for_greater_dim(self):
106 input_image = np.ones((100, 50, 3))
107 resize = Preprocessor.provide('resize', {
111 'aspect_ratio_scale': 'greater'
113 result = resize(DataRepresentation(input_image)).data
115 assert result.shape == (300, 100, 3)
117 def test_resize_to_negative_size_raise_config_error(self):
118 with pytest.raises(ConfigError):
119 Preprocessor.provide('resize', {'type': 'resize', 'size': -100})
121 def test_resize_to_negative_destination_width_raise_config_error(self):
122 with pytest.raises(ConfigError):
123 Preprocessor.provide('resize', {'type': 'resize', 'dst_width': -100, 'dst_height': 100})
125 def test_resize_to_negative_destination_height_raise_config_error(self):
126 with pytest.raises(ConfigError):
127 Preprocessor.provide('resize', {'type': 'resize', 'dst_width': 100, 'dst_height': -100})
129 def test_resize_with_both_provided_size_and_dst_height_dst_width_warn(self):
130 input_image = np.ones((100, 50, 3))
132 with pytest.warns(None) as warnings:
133 resize = Preprocessor.provide(
134 'resize', {'type': 'resize', 'dst_width': 100, 'dst_height': 100, 'size': 200}
136 assert len(warnings) == 1
137 result = resize(DataRepresentation(input_image)).data
138 assert result.shape == (200, 200, 3)
140 def test_resize_provided_only_dst_height_raise_config_error(self):
141 with pytest.raises(ValueError):
142 Preprocessor.provide('resize', {'type': 'resize', 'dst_height': 100})
144 def test_resize_provided_only_dst_width_raise_config_error(self):
145 with pytest.raises(ValueError):
146 Preprocessor.provide('resize', {'type': 'resize', 'dst_width': 100})
149 class TestNormalization:
150 def test_normalization_without_mean_and_std_raise_config_error(self):
151 with pytest.raises(ConfigError):
152 Preprocessor.provide('normalization', {'type': 'normalization'})
154 def test_custom_normalization_with_mean(self):
155 normalization = Preprocessor.provide('normalization', {'type': 'normalization', 'mean': '(1, 2, 3)'})
156 source = np.full_like((3, 300, 300), 100)
157 input_ref = source.copy() - (1, 2, 3)
158 result = normalization(DataRepresentation(source))
160 assert normalization.mean == (1, 2, 3)
161 assert normalization.std is None
162 assert np.all(input_ref == result.data)
163 assert result.metadata == {'image_size': (3,)}
165 def test_custom_normalization_with_precomputed_mean(self):
166 normalization = Preprocessor.provide('normalization', {'type': 'normalization', 'mean': 'cifar10'})
168 source = np.full_like((3, 300, 300), 100)
169 input_ref = source.copy() - normalization.PRECOMPUTED_MEANS['cifar10']
170 result = normalization(DataRepresentation(source))
172 assert normalization.mean == normalization.PRECOMPUTED_MEANS['cifar10']
173 assert normalization.std is None
174 assert np.all(input_ref == result.data)
175 assert result.metadata == {'image_size': (3,)}
177 def test_custom_normalization_with_mean_as_scalar(self):
178 normalization = Preprocessor.provide('normalization', {'type': 'normalization', 'mean': '1'})
180 source = np.full_like((3, 300, 300), 100)
181 input_ref = source.copy() - 1
182 result = normalization(DataRepresentation(source))
184 assert normalization.mean == (1.0, )
185 assert normalization.std is None
186 assert np.all(input_ref == result.data)
187 assert result.metadata == {'image_size': (3,)}
189 def test_custom_normalization_with_std(self):
190 normalization = Preprocessor.provide('normalization', {'type': 'normalization', 'std': '(1, 2, 3)'})
192 source = np.full_like((3, 300, 300), 100)
193 input_ref = source.copy() / (1, 2, 3)
194 result = normalization(DataRepresentation(source))
196 assert normalization.mean is None
197 assert normalization.std == (1, 2, 3)
198 assert np.all(input_ref == result.data)
199 assert result.metadata == {'image_size': (3,)}
201 def test_custom_normalization_with_precomputed_std(self):
202 normalization = Preprocessor.provide('normalization', {'type': 'normalization', 'std': 'cifar10'})
204 source = np.full_like((3, 300, 300), 100)
205 input_ref = source.copy() / normalization.PRECOMPUTED_STDS['cifar10']
206 result = normalization(DataRepresentation(source))
208 assert normalization.mean is None
209 assert normalization.std == normalization.PRECOMPUTED_STDS['cifar10']
210 assert np.all(input_ref == result.data)
211 assert result.metadata == {'image_size': (3,)}
213 def test_custom_normalization_with_std_as_scalar(self):
214 normalization = Preprocessor.provide('normalization', {'type': 'normalization', 'std': '2'})
215 source = np.full_like((3, 300, 300), 100)
216 input_ref = source.copy() / 2
217 result = normalization(DataRepresentation(source))
219 assert normalization.mean is None
220 assert normalization.std == (2.0, )
221 assert np.all(input_ref == result.data)
222 assert result.metadata == {'image_size': (3,)}
224 def test_custom_normalization_with_mean_and_std(self):
225 normalization = Preprocessor.provide(
226 'normalization', {'type': 'normalization', 'mean': '(1, 2, 3)', 'std': '(4, 5, 6)'}
229 input_ = np.full_like((3, 300, 300), 100)
230 input_ref = (input_ - (1, 2, 3)) / (4, 5, 6)
231 result = normalization(DataRepresentation(input_))
233 assert normalization.mean == (1, 2, 3)
234 assert normalization.std == (4, 5, 6)
235 assert np.all(input_ref == result.data)
236 assert result.metadata == {'image_size': (3,)}
238 def test_custom_normalization_with_mean_and_std_as_scalars(self):
239 normalization = Preprocessor.provide('normalization', {'type': 'normalization', 'mean': '2', 'std': '5'})
241 input_ = np.full_like((3, 300, 300), 100)
242 input_ref = (input_ - (2, )) / (5, )
243 result = normalization(DataRepresentation(input_))
245 assert normalization.mean == (2, )
246 assert normalization.std == (5, )
247 assert np.all(input_ref == result.data)
248 assert result.metadata == {'image_size': (3,)}
250 def test_normalization_with_zero_in_std_values_raise_config_error(self):
251 with pytest.raises(ConfigError):
252 Preprocessor.provide('normalization', {'type': 'normalization', 'std': '(4, 0, 6)'})
254 def test_normalization_with_zero_as_std_value_raise_config_error(self):
255 with pytest.raises(ConfigError):
256 Preprocessor.provide('normalization', {'type': 'normalization', 'std': '0'})
258 def test_normalization_with_not_channel_wise_mean_list_raise_config_error(self):
259 with pytest.raises(ConfigError):
260 Preprocessor.provide('normalization', {'type': 'normalization', 'mean': '3, 2'})
262 def test_normalization_with_not_channel_wise_std_list_raise_config_error(self):
263 with pytest.raises(ConfigError):
264 Preprocessor.provide('normalization', {'type': 'normalization', 'std': '3, 2'})
266 def test_normalization_with_unknown_precomputed_mean_raise_config_error(self):
267 with pytest.raises(ValueError):
268 Preprocessor.provide('normalization', {'type': 'normalization', 'mean': 'unknown'})
270 def test_normalization_with_unknown_precomputed_std_raise_config_error(self):
271 with pytest.raises(ValueError):
272 Preprocessor.provide('normalization', {'type': 'normalization', 'std': 'unknown'})
275 class TestPreprocessingEvaluator:
276 def test_preprocessing_evaluator(self):
277 config = [{'type': 'normalization', 'mean': '(1, 2, 3)'}, {'type': 'resize', 'size': 200}]
278 preprocessor = PreprocessingExecutor(config)
280 assert 2 == len(preprocessor.processors)
281 assert isinstance(preprocessor.processors[0], Normalize)
282 assert isinstance(preprocessor.processors[1], Resize)
283 assert preprocessor.processors[0].mean == (1, 2, 3)
284 assert preprocessor.processors[1].dst_width == 200
288 def test_crop_higher(self):
289 crop = Crop({'dst_width': 50, 'dst_height': 33, 'type': 'crop'})
290 image = np.zeros((100, 100, 3))
291 image_rep = crop(DataRepresentation(image))
293 assert image_rep.data.shape == (33, 50, 3)
294 assert image_rep.metadata == {'image_size': (100, 100, 3)}
296 def test_crop_to_size(self):
297 crop = Crop({'size': 50, 'type': 'crop'})
298 image = np.zeros((100, 100, 3))
299 image_rep = crop(DataRepresentation(image))
301 assert image_rep.data.shape == (50, 50, 3)
302 assert image_rep.metadata == {'image_size': (100, 100, 3)}
304 def test_crop_higher_non_symmetric(self):
305 crop = Crop({'dst_width': 50, 'dst_height': 12, 'type': 'crop'})
306 image = np.zeros((70, 50, 3))
307 image_rep = crop(DataRepresentation(image))
309 assert image_rep.data.shape == (12, 50, 3)
310 assert image_rep.metadata == {'image_size': (70, 50, 3)}
312 def test_crop_less(self):
313 crop = Crop({'dst_width': 151, 'dst_height': 42, 'type': 'crop'})
314 image = np.zeros((30, 30, 3))
315 image_rep = crop(DataRepresentation(image))
317 assert image_rep.data.shape == (42, 151, 3)
318 assert image_rep.metadata == {'image_size': (30, 30, 3)}
320 def test_crop_less_non_symmetric(self):
321 crop = Crop({'dst_width': 42, 'dst_height': 151, 'type': 'crop'})
322 image = np.zeros((30, 40, 3))
323 image_rep = crop(DataRepresentation(image))
325 assert image_rep.data.shape == (151, 42, 3)
326 assert image_rep.metadata == {'image_size': (30, 40, 3)}
328 def test_crop_to_negative_size_raise_config_error(self):
329 with pytest.raises(ConfigError):
330 Crop({'size': -151, 'type': 'crop'})
332 def test_crop_to_negative_destination_width_raise_config_error(self):
333 with pytest.raises(ConfigError):
334 Crop({'dst_width': -100, 'dst_height': 100, 'type': 'crop'})
336 def test_crop_to_negative_destination_height_raise_config_error(self):
337 with pytest.raises(ConfigError):
338 Crop({'dst_width': 100, 'dst_height': -100, 'type': 'crop'})
340 def test_crop_with_both_provided_size_and_dst_height_dst_width_warn(self):
341 image = np.zeros((30, 40, 3))
342 with pytest.warns(None) as warnings:
343 crop = Crop({'dst_width': 100, 'dst_height': 100, 'size': 200, 'type': 'crop'})
344 assert len(warnings) == 1
345 result = crop.process(DataRepresentation(image))
346 assert result.data.shape == (200, 200, 3)
347 assert result.metadata == {'image_size': (30, 40, 3)}
351 def test_horizontal_flip(self):
352 image = np.random.randint(0, 255, (30, 40, 3))
353 expected_image = cv2.flip(image, 0)
354 flip = Flip({'type': 'flip', 'mode': 'horizontal'})
355 assert np.array_equal(expected_image, flip.process(DataRepresentation(image)).data)
357 def test_vertical_flip(self):
358 image = np.random.randint(0, 255, (30, 40, 3))
359 expected_image = cv2.flip(image, 1)
360 flip = Flip({'type': 'flip', 'mode': 'vertical'})
361 assert np.array_equal(expected_image, flip.process(DataRepresentation(image)).data)
363 def test_flip_raise_config_error_if_mode_not_provided(self):
364 with pytest.raises(ConfigError):
365 Flip({'type': 'flip'})
367 def test_flip_raise_config_error_if_mode_unknown(self):
368 with pytest.raises(ConfigError):
369 Flip({'type': 'flip', 'mode': 'unknown'})
373 def test_bgr_to_rgb(self):
374 image = np.random.randint(0, 255, (30, 40, 3)).astype(np.uint8)
375 expected_image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
376 bgr_to_rgb = BgrToRgb({'type': 'bgr_to_rgb'})
377 assert np.array_equal(expected_image, bgr_to_rgb.process(DataRepresentation(image)).data)
381 def test_crop_rect_if_rect_not_provided(self):
382 image = np.zeros((30, 40, 3))
383 crop_rect = CropRect({'type': 'crop_rect'})
384 assert np.array_equal(image, crop_rect(image, {}))
386 def test_crop_rect_if_rect_equal_image(self):
387 image = np.zeros((30, 40, 3))
388 crop_rect = CropRect({'type': 'crop_rect'})
389 assert np.array_equal(image, crop_rect(DataRepresentation(image), {'rect': [0, 0, 40, 30]}).data)
391 def test_crop_rect(self):
392 image = np.zeros((30, 40, 3))
394 expected_image = np.ones((30, 20, 3))
395 crop_rect = CropRect({'type': 'crop_rect'})
396 assert np.array_equal(expected_image, crop_rect(DataRepresentation(image), {'rect': [20, 0, 40, 30]}).data)
398 def test_crop_rect_negative_coordinates_of_rect(self):
399 image = np.zeros((30, 40, 3))
401 expected_image = image
402 crop_rect = CropRect({'type': 'crop_rect'})
403 assert np.array_equal(expected_image, crop_rect(DataRepresentation(image), {'rect': [-20, 0, 40, 30]}).data)
405 def test_crop_rect_more_image_size_coordinates_of_rect(self):
406 image = np.zeros((30, 40, 3))
408 expected_image = np.ones((30, 20, 3))
409 crop_rect = CropRect({'type': 'crop_rect'})
410 assert np.array_equal(expected_image, crop_rect(DataRepresentation(image), {'rect': [20, 0, 40, 50]}).data)
413 class TestExtendAroundRect:
414 def test_default_extend_around_rect_without_rect(self):
415 image = np.random.randint(0, 255, (30, 40, 3)).astype(np.uint8)
416 expected_image = image
417 extend_image_around_rect = ExtendAroundRect({'type': 'extend_around_rect'})
418 assert np.array_equal(expected_image, extend_image_around_rect(DataRepresentation(image), {}).data)
420 def test_default_extend_around_rect(self):
421 image = np.random.randint(0, 255, (30, 40, 3)).astype(np.uint8)
422 expected_image = image
423 extend_image_around_rect = ExtendAroundRect({'type': 'extend_around_rect'})
424 assert np.array_equal(
425 expected_image, extend_image_around_rect(DataRepresentation(image), {'rect': [20, 0, 40, 30]}).data
428 def test_extend_around_rect_with_positive_augmentation(self):
429 image = np.random.randint(0, 255, (30, 40, 3)).astype(np.uint8)
430 expected_image = cv2.copyMakeBorder(image, int(15.5), int(31), int(0), int(11), cv2.BORDER_REPLICATE)
431 extend_image_around_rect = ExtendAroundRect({'type': 'extend_around_rect', 'augmentation_param': 0.5})
432 assert np.array_equal(
433 expected_image, extend_image_around_rect(DataRepresentation(image), {'rect': [20, 0, 40, 30]}).data
436 def test_extend_around_rect_with_negative_augmentation(self):
437 image = np.random.randint(0, 255, (30, 40, 3)).astype(np.uint8)
438 expected_image = image
439 extend_image_around_rect = ExtendAroundRect({'type': 'extend_around_rect', 'augmentation_param': -0.5})
440 assert np.array_equal(
441 expected_image, extend_image_around_rect(DataRepresentation(image), {'rect': [20, 0, 40, 30]}).data
444 def test_extend_around_rect_with_rect_equal_image(self):
445 image = np.random.randint(0, 255, (30, 40, 3)).astype(np.uint8)
446 expected_image = cv2.copyMakeBorder(image, int(15.5), int(31), int(20.5), int(41), cv2.BORDER_REPLICATE)
447 extend_image_around_rect = ExtendAroundRect({'type': 'extend_around_rect', 'augmentation_param': 0.5})
448 assert np.array_equal(
449 expected_image, extend_image_around_rect(DataRepresentation(image), {'rect': [0, 0, 40, 30]}).data
452 def test_extend_around_rect_negative_coordinates_of_rect(self):
453 image = np.random.randint(0, 255, (30, 40, 3)).astype(np.uint8)
454 expected_image = cv2.copyMakeBorder(image, int(15.5), int(31), int(20.5), int(41), cv2.BORDER_REPLICATE)
455 extend_image_around_rect = ExtendAroundRect({'type': 'extend_around_rect', 'augmentation_param': 0.5})
456 assert np.array_equal(
457 expected_image, extend_image_around_rect(DataRepresentation(image), {'rect': [-20, 0, 40, 30]}).data
460 def test_extend_around_rect_more_image_size_coordinates_of_rect(self):
461 image = np.random.randint(0, 255, (30, 40, 3)).astype(np.uint8)
462 expected_image = cv2.copyMakeBorder(image, int(15.5), int(31), int(0), int(11), cv2.BORDER_REPLICATE)
463 extend_image_around_rect = ExtendAroundRect({'type': 'extend_around_rect', 'augmentation_param': 0.5})
464 assert np.array_equal(
465 expected_image, extend_image_around_rect(DataRepresentation(image), {'rect': [20, 0, 40, 50]}).data
469 class TestPointAlignment:
470 def test_point_alignment_width_negative_size_raise_config_error(self):
471 with pytest.raises(ConfigError):
472 PointAligner({'type': 'point_alignment', 'size': -100})
474 def test_point_alignment_negative_destination_width_raise_config_error(self):
475 with pytest.raises(ConfigError):
476 PointAligner({'type': 'point_alignment', 'dst_width': -100, 'dst_height': 100})
478 def test_point_alignment_to_negative_destination_height_raise_config_error(self):
479 with pytest.raises(ValueError):
480 PointAligner({'type': 'point_alignment', 'dst_width': 100, 'dst_height': -100})
482 def test_point_alignment_provided_only_dst_height_raise_config_error(self):
483 with pytest.raises(ValueError):
484 PointAligner({'type': 'point_alignment', 'dst_height': 100})
486 def test_point_alignment_provided_only_dst_width_raise_config_error(self):
487 with pytest.raises(ValueError):
488 PointAligner({'type': 'point_alignment', 'dst_width': 100})
490 def test_point_alignment_both_provided_size_and_dst_height_dst_width_warn(self):
491 input_image = np.ones((100, 50, 3))
493 with pytest.warns(None) as warnings:
494 point_aligner = PointAligner({'type': 'point_alignment', 'dst_width': 100, 'dst_height': 100, 'size': 200})
495 assert len(warnings) == 1
496 result = point_aligner(DataRepresentation(input_image), {}).data
497 assert result.shape == (100, 50, 3)
499 def test_point_alignment_not_provided_points_im_meta(self):
500 input_image = np.ones((100, 50, 3))
502 point_aligner = PointAligner({'type': 'point_alignment', 'dst_width': 100, 'dst_height': 100})
503 result = point_aligner(DataRepresentation(input_image), {}).data
504 assert result.shape == (100, 50, 3)
506 def test_point_alignment_default_use_normalization(self):
507 image = np.random.randint(0, 255, (40, 40, 3)).astype(np.uint8)
509 point_aligner = PointAligner({'type': 'point_alignment', 'dst_width': 40, 'dst_height': 40})
510 result = point_aligner(
511 DataRepresentation(image), {'keypoints': PointAligner.ref_landmarks.reshape(-1).tolist()}
513 transformation_matrix = point_aligner.transformation_from_points(
514 point_aligner.ref_landmarks * 40, point_aligner.ref_landmarks
516 expected_result = cv2.warpAffine(image, transformation_matrix, (40, 40), flags=cv2.WARP_INVERSE_MAP)
518 assert np.array_equal(result, expected_result)
520 def test_point_alignment_use_normalization(self):
521 image = np.random.randint(0, 255, (40, 40, 3)).astype(np.uint8)
523 point_aligner = PointAligner({'type': 'point_alignment', 'dst_width': 40, 'dst_height': 40, 'normalize': True})
524 result = point_aligner(
525 DataRepresentation(image), {'keypoints': PointAligner.ref_landmarks.reshape(-1).tolist()}
527 transformation_matrix = point_aligner.transformation_from_points(
528 point_aligner.ref_landmarks * 40, point_aligner.ref_landmarks
530 expected_result = cv2.warpAffine(image, transformation_matrix, (40, 40), flags=cv2.WARP_INVERSE_MAP)
532 assert np.array_equal(result, expected_result)
534 def test_point_alignment_without_normalization(self):
535 image = np.random.randint(0, 255, (40, 40, 3)).astype(np.uint8)
537 point_aligner = PointAligner({'type': 'point_alignment', 'dst_width': 40, 'dst_height': 40, 'normalize': False})
538 result = point_aligner(
539 DataRepresentation(image), {'keypoints': PointAligner.ref_landmarks.reshape(-1).tolist()}
541 transformation_matrix = point_aligner.transformation_from_points(
542 point_aligner.ref_landmarks * 40, point_aligner.ref_landmarks * 40
544 expected_result = cv2.warpAffine(image, transformation_matrix, (40, 40), flags=cv2.WARP_INVERSE_MAP)
546 assert np.array_equal(result, expected_result)
548 def test_point_alignment_with_drawing_points(self):
549 image = np.random.randint(0, 255, (40, 40, 3)).astype(np.uint8)
551 point_aligner = PointAligner({
552 'type': 'point_alignment', 'dst_width': 40, 'dst_height': 40, 'draw_points': True
554 result = point_aligner(
555 DataRepresentation(image), {'keypoints': PointAligner.ref_landmarks.reshape(-1).tolist()}
557 transformation_matrix = point_aligner.transformation_from_points(
558 point_aligner.ref_landmarks * 40, point_aligner.ref_landmarks
560 expected_result = image
561 for point in PointAligner.ref_landmarks:
562 cv2.circle(expected_result, (int(point[0]), int(point[1])), 5, (255, 0, 0), -1)
563 expected_result = cv2.warpAffine(expected_result, transformation_matrix, (40, 40), flags=cv2.WARP_INVERSE_MAP)
565 assert np.array_equal(result, expected_result)
567 def test_point_alignment_with_resizing(self):
568 image = np.random.randint(0, 255, (80, 80, 3)).astype(np.uint8)
570 point_aligner = PointAligner({'type': 'point_alignment', 'size': 40})
571 result = point_aligner(
572 DataRepresentation(image), {'keypoints': PointAligner.ref_landmarks.reshape(-1).tolist()}
574 transformation_matrix = point_aligner.transformation_from_points(
575 point_aligner.ref_landmarks * 40, point_aligner.ref_landmarks * 0.5
577 expected_result = cv2.resize(image, (40, 40))
578 expected_result = cv2.warpAffine(expected_result, transformation_matrix, (40, 40), flags=cv2.WARP_INVERSE_MAP)
580 assert np.array_equal(result, expected_result)
583 class TestPreprocessorExtraArgs:
584 def test_resize_raise_config_error_on_extra_args(self):
585 with pytest.raises(ConfigError):
586 Preprocessor.provide('resize', {'type': 'resize', 'size': 1, 'something_extra': 'extra'})
588 def test_normalization_raise_config_error_on_extra_args(self):
589 with pytest.raises(ConfigError):
590 Preprocessor.provide('normalization', {'type': 'normalization', 'mean': 0, 'something_extra': 'extra'})
592 def test_bgr_to_rgb_raise_config_error_on_extra_args(self):
593 with pytest.raises(ConfigError):
594 Preprocessor.provide('bgr_to_rgb', {'type': 'bgr_to_rgb', 'something_extra': 'extra'})
596 def test_flip_raise_config_error_on_extra_args(self):
597 with pytest.raises(ConfigError):
598 Preprocessor.provide('flip', {'type': 'flip', 'something_extra': 'extra'})
600 def test_crop_accuracy_raise_config_error_on_extra_args(self):
601 with pytest.raises(ConfigError):
602 Preprocessor.provide('crop', {'type': 'crop', 'size': 1, 'something_extra': 'extra'})
604 def test_extend_around_rect_raise_config_error_on_extra_args(self):
605 with pytest.raises(ConfigError):
606 Preprocessor.provide('extend_around_rect', {'type': 'extend_around_rect', 'something_extra': 'extra'})
608 def test_point_alignment_raise_config_error_on_extra_args(self):
609 with pytest.raises(ConfigError):
610 Preprocessor.provide('point_alignment', {'type': 'point_alignment', 'something_extra': 'extra'})