# Copyright (c) Open-MMLab. All rights reserved. import os.path as osp import cv2 import numpy as np from numpy.testing import assert_array_equal import mmcv class TestPhotometric: @classmethod def setup_class(cls): # the test img resolution is 400x300 cls.img_path = osp.join(osp.dirname(__file__), '../data/color.jpg') cls.img = cv2.imread(cls.img_path) cls.mean = np.array([123.675, 116.28, 103.53], dtype=np.float32) cls.std = np.array([58.395, 57.12, 57.375], dtype=np.float32) def test_imnormalize(self): rgb_img = self.img[:, :, ::-1] baseline = (rgb_img - self.mean) / self.std img = mmcv.imnormalize(self.img, self.mean, self.std) assert np.allclose(img, baseline) assert id(img) != id(self.img) img = mmcv.imnormalize(rgb_img, self.mean, self.std, to_rgb=False) assert np.allclose(img, baseline) assert id(img) != id(rgb_img) def test_imnormalize_(self): img_for_normalize = np.float32(self.img) rgb_img_for_normalize = np.float32(self.img[:, :, ::-1]) baseline = (rgb_img_for_normalize - self.mean) / self.std img = mmcv.imnormalize_(img_for_normalize, self.mean, self.std) assert np.allclose(img_for_normalize, baseline) assert id(img) == id(img_for_normalize) img = mmcv.imnormalize_( rgb_img_for_normalize, self.mean, self.std, to_rgb=False) assert np.allclose(img, baseline) assert id(img) == id(rgb_img_for_normalize) def test_imdenormalize(self): norm_img = (self.img[:, :, ::-1] - self.mean) / self.std rgb_baseline = (norm_img * self.std + self.mean) bgr_baseline = rgb_baseline[:, :, ::-1] img = mmcv.imdenormalize(norm_img, self.mean, self.std) assert np.allclose(img, bgr_baseline) img = mmcv.imdenormalize(norm_img, self.mean, self.std, to_bgr=False) assert np.allclose(img, rgb_baseline) def test_iminvert(self): img = np.array([[0, 128, 255], [1, 127, 254], [2, 129, 253]], dtype=np.uint8) img_r = np.array([[255, 127, 0], [254, 128, 1], [253, 126, 2]], dtype=np.uint8) assert_array_equal(mmcv.iminvert(img), img_r) def test_solarize(self): img = np.array([[0, 128, 255], [1, 127, 254], [2, 129, 253]], dtype=np.uint8) img_r = np.array([[0, 127, 0], [1, 127, 1], [2, 126, 2]], dtype=np.uint8) assert_array_equal(mmcv.solarize(img), img_r) img_r = np.array([[0, 127, 0], [1, 128, 1], [2, 126, 2]], dtype=np.uint8) assert_array_equal(mmcv.solarize(img, 100), img_r) def test_posterize(self): img = np.array([[0, 128, 255], [1, 127, 254], [2, 129, 253]], dtype=np.uint8) img_r = np.array([[0, 128, 128], [0, 0, 128], [0, 128, 128]], dtype=np.uint8) assert_array_equal(mmcv.posterize(img, 1), img_r) img_r = np.array([[0, 128, 224], [0, 96, 224], [0, 128, 224]], dtype=np.uint8) assert_array_equal(mmcv.posterize(img, 3), img_r) def test_adjust_color(self): img = np.array([[0, 128, 255], [1, 127, 254], [2, 129, 253]], dtype=np.uint8) img = np.stack([img, img, img], axis=-1) assert_array_equal(mmcv.adjust_color(img), img) img_gray = mmcv.bgr2gray(img) img_r = np.stack([img_gray, img_gray, img_gray], axis=-1) assert_array_equal(mmcv.adjust_color(img, 0), img_r) assert_array_equal(mmcv.adjust_color(img, 0, 1), img_r) assert_array_equal( mmcv.adjust_color(img, 0.5, 0.5), np.round(np.clip((img * 0.5 + img_r * 0.5), 0, 255)).astype(img.dtype)) assert_array_equal( mmcv.adjust_color(img, 1, 1.5), np.round(np.clip(img * 1 + img_r * 1.5, 0, 255)).astype(img.dtype)) assert_array_equal( mmcv.adjust_color(img, 0.8, -0.6, gamma=2), np.round(np.clip(img * 0.8 - 0.6 * img_r + 2, 0, 255)).astype(img.dtype)) assert_array_equal( mmcv.adjust_color(img, 0.8, -0.6, gamma=-0.6), np.round(np.clip(img * 0.8 - 0.6 * img_r - 0.6, 0, 255)).astype(img.dtype)) # test float type of image img = img.astype(np.float32) assert_array_equal( np.round(mmcv.adjust_color(img, 0.8, -0.6, gamma=-0.6)), np.round(np.clip(img * 0.8 - 0.6 * img_r - 0.6, 0, 255))) def test_imequalize(self, nb_rand_test=100): def _imequalize(img): # equalize the image using PIL.ImageOps.equalize from PIL import ImageOps, Image img = Image.fromarray(img) equalized_img = np.asarray(ImageOps.equalize(img)) return equalized_img img = np.array([[0, 128, 255], [1, 127, 254], [2, 129, 253]], dtype=np.uint8) img = np.stack([img, img, img], axis=-1) equalized_img = mmcv.imequalize(img) assert_array_equal(equalized_img, _imequalize(img)) # test equalize with case step=0 img = np.array([[0, 0, 0], [120, 120, 120], [255, 255, 255]], dtype=np.uint8) img = np.stack([img, img, img], axis=-1) assert_array_equal(mmcv.imequalize(img), img) # test equalize with randomly sampled image. for _ in range(nb_rand_test): img = np.clip( np.random.uniform(0, 1, (1000, 1200, 3)) * 260, 0, 255).astype(np.uint8) equalized_img = mmcv.imequalize(img) assert_array_equal(equalized_img, _imequalize(img)) def test_adjust_brightness(self, nb_rand_test=100): def _adjust_brightness(img, factor): # adjust the brightness of image using # PIL.ImageEnhance.Brightness from PIL.ImageEnhance import Brightness from PIL import Image img = Image.fromarray(img) brightened_img = Brightness(img).enhance(factor) return np.asarray(brightened_img) img = np.array([[0, 128, 255], [1, 127, 254], [2, 129, 253]], dtype=np.uint8) img = np.stack([img, img, img], axis=-1) # test case with factor 1.0 assert_array_equal(mmcv.adjust_brightness(img, 1.), img) # test case with factor 0.0 assert_array_equal(mmcv.adjust_brightness(img, 0.), np.zeros_like(img)) # test adjust_brightness with randomly sampled images and factors. for _ in range(nb_rand_test): img = np.clip( np.random.uniform(0, 1, (1000, 1200, 3)) * 260, 0, 255).astype(np.uint8) factor = np.random.uniform() np.testing.assert_allclose( mmcv.adjust_brightness(img, factor).astype(np.int32), _adjust_brightness(img, factor).astype(np.int32), rtol=0, atol=1) def test_adjust_contrast(self, nb_rand_test=100): def _adjust_contrast(img, factor): from PIL.ImageEnhance import Contrast from PIL import Image # Image.fromarray defaultly supports RGB, not BGR. # convert from BGR to RGB img = Image.fromarray(img[..., ::-1], mode='RGB') contrasted_img = Contrast(img).enhance(factor) # convert from RGB to BGR return np.asarray(contrasted_img)[..., ::-1] img = np.array([[0, 128, 255], [1, 127, 254], [2, 129, 253]], dtype=np.uint8) img = np.stack([img, img, img], axis=-1) # test case with factor 1.0 assert_array_equal(mmcv.adjust_contrast(img, 1.), img) # test case with factor 0.0 assert_array_equal( mmcv.adjust_contrast(img, 0.), _adjust_contrast(img, 0.)) # test adjust_contrast with randomly sampled images and factors. for _ in range(nb_rand_test): img = np.clip( np.random.uniform(0, 1, (1200, 1000, 3)) * 260, 0, 255).astype(np.uint8) factor = np.random.uniform() # Note the gap (less_equal 1) between PIL.ImageEnhance.Contrast # and mmcv.adjust_contrast comes from the gap that converts from # a color image to gray image using mmcv or PIL. np.testing.assert_allclose( mmcv.adjust_contrast(img, factor).astype(np.int32), _adjust_contrast(img, factor).astype(np.int32), rtol=0, atol=1)