From 6b41ed4f1c01ca8d1c20857a4b5ed52de19358d7 Mon Sep 17 00:00:00 2001 From: yamengxi <854341266@qq.com> Date: Wed, 4 Nov 2020 22:02:12 +0800 Subject: [PATCH 01/15] add CLAHE transform --- .pre-commit-config.yaml | 10 +++--- mmseg/datasets/pipelines/transforms.py | 45 ++++++++++++++++++++++++++ tests/test_data/test_transform.py | 41 +++++++++++++++++++++++ 3 files changed, 91 insertions(+), 5 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d3395dc284..2b274aa277 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -28,11 +28,11 @@ repos: args: ["--remove"] - id: mixed-line-ending args: ["--fix=lf"] - - repo: https://github.com/jumanjihouse/pre-commit-hooks - rev: 2.1.4 - hooks: - - id: markdownlint - args: ["-r", "~MD002,~MD013,~MD029,~MD033,~MD034,~MD036"] + # - repo: https://github.com/jumanjihouse/pre-commit-hooks + # rev: 2.1.4 + # hooks: + # - id: markdownlint + # args: ["-r", "~MD002,~MD013,~MD029,~MD033,~MD034,~MD036"] - repo: https://github.com/myint/docformatter rev: v1.3.1 hooks: diff --git a/mmseg/datasets/pipelines/transforms.py b/mmseg/datasets/pipelines/transforms.py index 2b314a810f..5ee6557bce 100644 --- a/mmseg/datasets/pipelines/transforms.py +++ b/mmseg/datasets/pipelines/transforms.py @@ -1,3 +1,4 @@ +import cv2 import mmcv import numpy as np from numpy import random @@ -390,6 +391,50 @@ def __repr__(self): return repr_str +@PIPELINES.register_module() +class CLAHE(object): + """Use CLAHE method to process the image. + + Args: + clip_limit (float): Threshold for contrast limiting. Default: 40.0. + tile_grid_size (tuple[int]): Size of grid for histogram equalization. + Input image will be divided into equally sized rectangular tiles. + It defines the number of tiles in row and column. Default: (8, 8). + """ + + def __init__(self, clip_limit=40.0, tile_grid_size=(8, 8)): + assert isinstance(clip_limit, float) or isinstance(clip_limit, int) + self.clip_limit = clip_limit + assert isinstance(tile_grid_size, tuple) + assert len(tile_grid_size) == 2 + for item in tile_grid_size: + assert isinstance(item, int) + self.tile_grid_size = tile_grid_size + self.clahe = cv2.createCLAHE(clip_limit, tile_grid_size) + + def __call__(self, results): + """Call function to Use CLAHE method process images. + + Args: + results (dict): Result dict from loading pipeline. + + Returns: + dict: Processed results. + """ + + for i in range(results['img'].shape[2]): + results['img'][:,:,i] = self.clahe.apply( + np.array(results['img'][:,:,i], dtype = np.uint8)) + + return results + + def __repr__(self): + repr_str = self.__class__.__name__ + repr_str += f'(clip_limit={self.clip_limit}, '\ + f'tile_grid_size={self.tile_grid_size})' + return repr_str + + @PIPELINES.register_module() class RandomCrop(object): """Random crop the image & seg. diff --git a/tests/test_data/test_transform.py b/tests/test_data/test_transform.py index 7a1ca0dde3..7c0788ce9a 100644 --- a/tests/test_data/test_transform.py +++ b/tests/test_data/test_transform.py @@ -1,6 +1,7 @@ import copy import os.path as osp +import cv2 import mmcv import numpy as np import pytest @@ -223,6 +224,46 @@ def test_normalize(): assert np.allclose(results['img'], converted_img) +def test_CLAHE(): + # test assertion if clip_limit is None + with pytest.raises(AssertionError): + transform = dict(type='CLAHE', clip_limit=None) + build_from_cfg(transform, PIPELINES) + + # test assertion if tile_grid_size is illegal + with pytest.raises(AssertionError): + transform = dict(type='CLAHE', tile_grid_size=(8.0, 8.0)) + build_from_cfg(transform, PIPELINES) + + # test assertion if tile_grid_size is illegal + with pytest.raises(AssertionError): + transform = dict(type='CLAHE', tile_grid_size=(9, 9, 9)) + build_from_cfg(transform, PIPELINES) + + transform = dict(type='CLAHE', clip_limit=2) + transform = build_from_cfg(transform, PIPELINES) + results = dict() + img = mmcv.imread( + osp.join(osp.dirname(__file__), '../data/color.jpg'), 'color') + original_img = copy.deepcopy(img) + results['img'] = img + results['img_shape'] = img.shape + results['ori_shape'] = img.shape + # Set initial values for default meta_keys + results['pad_shape'] = img.shape + results['scale_factor'] = 1.0 + + results = transform(results) + + clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8)) + converted_img = np.empty(original_img.shape) + for i in range(original_img.shape[2]): + converted_img[:,:,i] = clahe.apply( + np.array(original_img[:,:,i], dtype = np.uint8)) + + assert np.allclose(results['img'], converted_img) + + def test_seg_rescale(): results = dict() seg = np.array( From 83eb21aac1587b8c8235abff98e46cd3429c72fc Mon Sep 17 00:00:00 2001 From: yamengxi <854341266@qq.com> Date: Wed, 4 Nov 2020 22:06:41 +0800 Subject: [PATCH 02/15] fix syntax error --- mmseg/datasets/pipelines/transforms.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mmseg/datasets/pipelines/transforms.py b/mmseg/datasets/pipelines/transforms.py index 5ee6557bce..8244b39a51 100644 --- a/mmseg/datasets/pipelines/transforms.py +++ b/mmseg/datasets/pipelines/transforms.py @@ -423,8 +423,8 @@ def __call__(self, results): """ for i in range(results['img'].shape[2]): - results['img'][:,:,i] = self.clahe.apply( - np.array(results['img'][:,:,i], dtype = np.uint8)) + results['img'][:, :, i] = self.clahe.apply( + np.array(results['img'][:, :, i], dtype=np.uint8)) return results From f42635712174799e2266ee88ca1a9e1e1ec1933f Mon Sep 17 00:00:00 2001 From: yamengxi <854341266@qq.com> Date: Wed, 4 Nov 2020 22:07:20 +0800 Subject: [PATCH 03/15] fix syntax error --- tests/test_data/test_transform.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/test_data/test_transform.py b/tests/test_data/test_transform.py index 7c0788ce9a..93e6ce151a 100644 --- a/tests/test_data/test_transform.py +++ b/tests/test_data/test_transform.py @@ -255,12 +255,12 @@ def test_CLAHE(): results = transform(results) - clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8)) + clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8)) converted_img = np.empty(original_img.shape) for i in range(original_img.shape[2]): - converted_img[:,:,i] = clahe.apply( - np.array(original_img[:,:,i], dtype = np.uint8)) - + converted_img[:, :, i] = clahe.apply( + np.array(original_img[:, :, i], dtype=np.uint8)) + assert np.allclose(results['img'], converted_img) From f614ea7999913459563208f129206ae5e428d032 Mon Sep 17 00:00:00 2001 From: yamengxi <854341266@qq.com> Date: Wed, 4 Nov 2020 22:08:16 +0800 Subject: [PATCH 04/15] restore --- .pre-commit-config.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 2b274aa277..d3395dc284 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -28,11 +28,11 @@ repos: args: ["--remove"] - id: mixed-line-ending args: ["--fix=lf"] - # - repo: https://github.com/jumanjihouse/pre-commit-hooks - # rev: 2.1.4 - # hooks: - # - id: markdownlint - # args: ["-r", "~MD002,~MD013,~MD029,~MD033,~MD034,~MD036"] + - repo: https://github.com/jumanjihouse/pre-commit-hooks + rev: 2.1.4 + hooks: + - id: markdownlint + args: ["-r", "~MD002,~MD013,~MD029,~MD033,~MD034,~MD036"] - repo: https://github.com/myint/docformatter rev: v1.3.1 hooks: From bc1d571fc7a1f5fcc99b858dc5ab115695a189ff Mon Sep 17 00:00:00 2001 From: yamengxi <854341266@qq.com> Date: Thu, 5 Nov 2020 14:52:11 +0800 Subject: [PATCH 05/15] add a test --- tests/test_data/test_transform.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_data/test_transform.py b/tests/test_data/test_transform.py index 93e6ce151a..decb4b12ae 100644 --- a/tests/test_data/test_transform.py +++ b/tests/test_data/test_transform.py @@ -262,6 +262,7 @@ def test_CLAHE(): np.array(original_img[:, :, i], dtype=np.uint8)) assert np.allclose(results['img'], converted_img) + assert str(transform) == f'CLAHE(clip_limit={2}, tile_grid_size={(8, 8)})' def test_seg_rescale(): From 9a3d216d947a13c5011de243da5db06f356ff483 Mon Sep 17 00:00:00 2001 From: yamengxi <854341266@qq.com> Date: Wed, 11 Nov 2020 23:50:45 +0800 Subject: [PATCH 06/15] modify cv2 to mmcv --- mmseg/datasets/pipelines/transforms.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/mmseg/datasets/pipelines/transforms.py b/mmseg/datasets/pipelines/transforms.py index 8244b39a51..b36e7c2177 100644 --- a/mmseg/datasets/pipelines/transforms.py +++ b/mmseg/datasets/pipelines/transforms.py @@ -1,4 +1,3 @@ -import cv2 import mmcv import numpy as np from numpy import random @@ -410,7 +409,6 @@ def __init__(self, clip_limit=40.0, tile_grid_size=(8, 8)): for item in tile_grid_size: assert isinstance(item, int) self.tile_grid_size = tile_grid_size - self.clahe = cv2.createCLAHE(clip_limit, tile_grid_size) def __call__(self, results): """Call function to Use CLAHE method process images. @@ -423,7 +421,7 @@ def __call__(self, results): """ for i in range(results['img'].shape[2]): - results['img'][:, :, i] = self.clahe.apply( + results['img'][:, :, i] = mmcv.clahe.apply( np.array(results['img'][:, :, i], dtype=np.uint8)) return results From 8ee4040617087a3d3c44e558d1259ac5bd1fa1ec Mon Sep 17 00:00:00 2001 From: yamengxi <854341266@qq.com> Date: Thu, 12 Nov 2020 00:53:19 +0800 Subject: [PATCH 07/15] add docstring --- mmseg/datasets/pipelines/transforms.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mmseg/datasets/pipelines/transforms.py b/mmseg/datasets/pipelines/transforms.py index 65ed6901be..9d936ef724 100644 --- a/mmseg/datasets/pipelines/transforms.py +++ b/mmseg/datasets/pipelines/transforms.py @@ -442,6 +442,9 @@ def __repr__(self): class CLAHE(object): """Use CLAHE method to process the image. + See `ZUIDERVELD,K. Contrast Limited Adaptive Histogram Equalization[J]. + Graphics Gems, 1994:474-485.` for more information. + Args: clip_limit (float): Threshold for contrast limiting. Default: 40.0. tile_grid_size (tuple[int]): Size of grid for histogram equalization. From f5cc0435ad03f04d7bad807c10c369e1963c585e Mon Sep 17 00:00:00 2001 From: yamengxi <854341266@qq.com> Date: Thu, 26 Nov 2020 19:28:06 +0800 Subject: [PATCH 08/15] modify --- .pre-commit-config.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d3395dc284..2b274aa277 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -28,11 +28,11 @@ repos: args: ["--remove"] - id: mixed-line-ending args: ["--fix=lf"] - - repo: https://github.com/jumanjihouse/pre-commit-hooks - rev: 2.1.4 - hooks: - - id: markdownlint - args: ["-r", "~MD002,~MD013,~MD029,~MD033,~MD034,~MD036"] + # - repo: https://github.com/jumanjihouse/pre-commit-hooks + # rev: 2.1.4 + # hooks: + # - id: markdownlint + # args: ["-r", "~MD002,~MD013,~MD029,~MD033,~MD034,~MD036"] - repo: https://github.com/myint/docformatter rev: v1.3.1 hooks: From f46454e3be06fa174c80e25860176ba4dacf799b Mon Sep 17 00:00:00 2001 From: yamengxi <854341266@qq.com> Date: Thu, 26 Nov 2020 19:28:31 +0800 Subject: [PATCH 09/15] restore --- .pre-commit-config.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 2b274aa277..d3395dc284 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -28,11 +28,11 @@ repos: args: ["--remove"] - id: mixed-line-ending args: ["--fix=lf"] - # - repo: https://github.com/jumanjihouse/pre-commit-hooks - # rev: 2.1.4 - # hooks: - # - id: markdownlint - # args: ["-r", "~MD002,~MD013,~MD029,~MD033,~MD034,~MD036"] + - repo: https://github.com/jumanjihouse/pre-commit-hooks + rev: 2.1.4 + hooks: + - id: markdownlint + args: ["-r", "~MD002,~MD013,~MD029,~MD033,~MD034,~MD036"] - repo: https://github.com/myint/docformatter rev: v1.3.1 hooks: From cfa9acf5b2587f3795e4006e7e8b49b008f6bfef Mon Sep 17 00:00:00 2001 From: yamengxi <854341266@qq.com> Date: Wed, 2 Dec 2020 11:18:01 +0800 Subject: [PATCH 10/15] fix mmcv.clahe error --- mmseg/datasets/pipelines/transforms.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mmseg/datasets/pipelines/transforms.py b/mmseg/datasets/pipelines/transforms.py index 9d936ef724..f0da99e51c 100644 --- a/mmseg/datasets/pipelines/transforms.py +++ b/mmseg/datasets/pipelines/transforms.py @@ -472,7 +472,7 @@ def __call__(self, results): """ for i in range(results['img'].shape[2]): - results['img'][:, :, i] = mmcv.clahe.apply( + results['img'][:, :, i] = mmcv.clahe( np.array(results['img'][:, :, i], dtype=np.uint8)) return results From 891e135ffcbb6dd9aef8dd2c3a7f6c978a08a693 Mon Sep 17 00:00:00 2001 From: yamengxi <854341266@qq.com> Date: Wed, 2 Dec 2020 11:28:42 +0800 Subject: [PATCH 11/15] change mmcv version to 1.3.0 --- mmseg/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mmseg/__init__.py b/mmseg/__init__.py index ffc848a934..f301a5dc34 100644 --- a/mmseg/__init__.py +++ b/mmseg/__init__.py @@ -3,7 +3,7 @@ from .version import __version__, version_info MMCV_MIN = '1.1.4' -MMCV_MAX = '1.2.0' +MMCV_MAX = '1.3.0' def digit_version(version_str): From f3b2a304a81fee5927432f7fafe9affe41dc58a2 Mon Sep 17 00:00:00 2001 From: yamengxi <854341266@qq.com> Date: Wed, 2 Dec 2020 12:25:50 +0800 Subject: [PATCH 12/15] fix bugs --- mmseg/datasets/pipelines/transforms.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/mmseg/datasets/pipelines/transforms.py b/mmseg/datasets/pipelines/transforms.py index f0da99e51c..e8f7982e2e 100644 --- a/mmseg/datasets/pipelines/transforms.py +++ b/mmseg/datasets/pipelines/transforms.py @@ -1,6 +1,6 @@ import mmcv import numpy as np -from mmcv.utils import deprecated_api_warning +from mmcv.utils import deprecated_api_warning, is_tuple_of from numpy import random from ..builder import PIPELINES @@ -453,12 +453,10 @@ class CLAHE(object): """ def __init__(self, clip_limit=40.0, tile_grid_size=(8, 8)): - assert isinstance(clip_limit, float) or isinstance(clip_limit, int) + assert isinstance(clip_limit, (float, int)) self.clip_limit = clip_limit - assert isinstance(tile_grid_size, tuple) + assert is_tuple_of(tile_grid_size, int) assert len(tile_grid_size) == 2 - for item in tile_grid_size: - assert isinstance(item, int) self.tile_grid_size = tile_grid_size def __call__(self, results): @@ -473,7 +471,8 @@ def __call__(self, results): for i in range(results['img'].shape[2]): results['img'][:, :, i] = mmcv.clahe( - np.array(results['img'][:, :, i], dtype=np.uint8)) + np.array(results['img'][:, :, i], dtype=np.uint8), + self.clip_limit, self.tile_grid_size) return results From 7f7e995417e6bca7091cfcd177ea7397033c1749 Mon Sep 17 00:00:00 2001 From: yamengxi <854341266@qq.com> Date: Wed, 2 Dec 2020 12:33:51 +0800 Subject: [PATCH 13/15] add all data transformers to __init__ --- mmseg/datasets/pipelines/__init__.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/mmseg/datasets/pipelines/__init__.py b/mmseg/datasets/pipelines/__init__.py index e45f495070..8515e0eac0 100644 --- a/mmseg/datasets/pipelines/__init__.py +++ b/mmseg/datasets/pipelines/__init__.py @@ -3,12 +3,14 @@ Transpose, to_tensor) from .loading import LoadAnnotations, LoadImageFromFile from .test_time_aug import MultiScaleFlipAug -from .transforms import (Normalize, Pad, PhotoMetricDistortion, RandomCrop, - RandomFlip, Resize, SegRescale) +from .transforms import (CLAHE, AdjustGamma, Normalize, Pad, + PhotoMetricDistortion, RandomCrop, RandomFlip, + Rerange, Resize, Rgb2Gray, SegRescale) __all__ = [ 'Compose', 'to_tensor', 'ToTensor', 'ImageToTensor', 'ToDataContainer', 'Transpose', 'Collect', 'LoadAnnotations', 'LoadImageFromFile', 'MultiScaleFlipAug', 'Resize', 'RandomFlip', 'Pad', 'RandomCrop', - 'Normalize', 'SegRescale', 'PhotoMetricDistortion' + 'Normalize', 'SegRescale', 'PhotoMetricDistortion', 'AdjustGamma', 'CLAHE', + 'Rerange', 'Rgb2Gray' ] From 90785e3f4d04df6ac1696cb883e7645af71ef6ae Mon Sep 17 00:00:00 2001 From: yamengxi <854341266@qq.com> Date: Wed, 2 Dec 2020 12:40:09 +0800 Subject: [PATCH 14/15] fix __init__ --- mmseg/datasets/pipelines/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mmseg/datasets/pipelines/__init__.py b/mmseg/datasets/pipelines/__init__.py index 69f56616ff..8b9046b07b 100644 --- a/mmseg/datasets/pipelines/__init__.py +++ b/mmseg/datasets/pipelines/__init__.py @@ -5,12 +5,12 @@ from .test_time_aug import MultiScaleFlipAug from .transforms import (CLAHE, AdjustGamma, Normalize, Pad, PhotoMetricDistortion, RandomCrop, RandomFlip, - RandomRotate, Rerange, Resize, Rgb2Gray, SegRescale) + RandomRotate, Rerange, Resize, RGB2Gray, SegRescale) __all__ = [ 'Compose', 'to_tensor', 'ToTensor', 'ImageToTensor', 'ToDataContainer', 'Transpose', 'Collect', 'LoadAnnotations', 'LoadImageFromFile', 'MultiScaleFlipAug', 'Resize', 'RandomFlip', 'Pad', 'RandomCrop', 'Normalize', 'SegRescale', 'PhotoMetricDistortion', 'RandomRotate', - 'AdjustGamma', 'CLAHE', 'Rerange', 'Rgb2Gray' + 'AdjustGamma', 'CLAHE', 'Rerange', 'RGB2Gray' ] From 3db63efefa2ad9fb845214353bfac1b3797cf20e Mon Sep 17 00:00:00 2001 From: yamengxi <854341266@qq.com> Date: Wed, 2 Dec 2020 12:53:50 +0800 Subject: [PATCH 15/15] fix test_transform --- tests/test_data/test_transform.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tests/test_data/test_transform.py b/tests/test_data/test_transform.py index ee21839536..1833d791e8 100644 --- a/tests/test_data/test_transform.py +++ b/tests/test_data/test_transform.py @@ -1,7 +1,6 @@ import copy import os.path as osp -import cv2 import mmcv import numpy as np import pytest @@ -441,11 +440,10 @@ def test_CLAHE(): results = transform(results) - clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8)) converted_img = np.empty(original_img.shape) for i in range(original_img.shape[2]): - converted_img[:, :, i] = clahe.apply( - np.array(original_img[:, :, i], dtype=np.uint8)) + converted_img[:, :, i] = mmcv.clahe( + np.array(original_img[:, :, i], dtype=np.uint8), 2, (8, 8)) assert np.allclose(results['img'], converted_img) assert str(transform) == f'CLAHE(clip_limit={2}, tile_grid_size={(8, 8)})'