"vscode:/vscode.git/clone" did not exist on "3c75113e37cc2b5d9ad8cb5c21841437aab482cc"
test_image.py 13.5 KB
Newer Older
1
2
3
4
import os
import os.path as osp
import tempfile

5
import cv2
6
7
import numpy as np
import pytest
Kai Chen's avatar
Kai Chen committed
8
9
10
from numpy.testing import assert_array_almost_equal, assert_array_equal

import mmcv
11
12
13
14
15
16
17
18
19
20


class TestImage(object):

    @classmethod
    def setup_class(cls):
        # the test img resolution is 400x300
        cls.img_path = osp.join(osp.dirname(__file__), 'data/color.jpg')
        cls.gray_img_path = osp.join(
            osp.dirname(__file__), 'data/grayscale.jpg')
21
        cls.img = cv2.imread(cls.img_path)
22
23
24
25
26
27
28
29

    def assert_img_equal(self, img, ref_img, ratio_thr=0.999):
        assert img.shape == ref_img.shape
        assert img.dtype == ref_img.dtype
        area = ref_img.shape[0] * ref_img.shape[1]
        diff = np.abs(img.astype('int32') - ref_img.astype('int32'))
        assert np.sum(diff <= 1) / float(area) > ratio_thr

30
31
    def test_imread(self):
        img = mmcv.imread(self.img_path)
32
        assert img.shape == (300, 400, 3)
33
        img = mmcv.imread(self.img_path, 'grayscale')
34
        assert img.shape == (300, 400)
35
        img = mmcv.imread(self.gray_img_path)
36
        assert img.shape == (300, 400, 3)
37
        img = mmcv.imread(self.gray_img_path, 'unchanged')
38
        assert img.shape == (300, 400)
39
40
        img = mmcv.imread(img)
        assert_array_equal(img, mmcv.imread(img))
41
        with pytest.raises(TypeError):
42
            mmcv.imread(1)
43

44
    def test_imfrombytes(self):
45
46
        with open(self.img_path, 'rb') as f:
            img_bytes = f.read()
47
        img = mmcv.imfrombytes(img_bytes)
48
49
        assert img.shape == (300, 400, 3)

50
51
    def test_imwrite(self):
        img = mmcv.imread(self.img_path)
52
        out_file = osp.join(tempfile.gettempdir(), 'mmcv_test.jpg')
53
54
        mmcv.imwrite(img, out_file)
        rewrite_img = mmcv.imread(out_file)
55
56
57
58
59
60
        os.remove(out_file)
        self.assert_img_equal(img, rewrite_img)

    def test_bgr2gray(self):
        in_img = np.random.rand(10, 10, 3).astype(np.float32)
        out_img = mmcv.bgr2gray(in_img)
Kai Chen's avatar
Kai Chen committed
61
62
63
        computed_gray = (
            in_img[:, :, 0] * 0.114 + in_img[:, :, 1] * 0.587 +
            in_img[:, :, 2] * 0.299)
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
        assert_array_almost_equal(out_img, computed_gray, decimal=4)
        out_img_3d = mmcv.bgr2gray(in_img, True)
        assert out_img_3d.shape == (10, 10, 1)
        assert_array_almost_equal(out_img_3d[..., 0], out_img, decimal=4)

    def test_gray2bgr(self):
        in_img = np.random.rand(10, 10).astype(np.float32)
        out_img = mmcv.gray2bgr(in_img)
        assert out_img.shape == (10, 10, 3)
        for i in range(3):
            assert_array_almost_equal(out_img[..., i], in_img, decimal=4)

    def test_bgr2rgb(self):
        in_img = np.random.rand(10, 10, 3).astype(np.float32)
        out_img = mmcv.bgr2rgb(in_img)
        assert out_img.shape == in_img.shape
        assert_array_equal(out_img[..., 0], in_img[..., 2])
        assert_array_equal(out_img[..., 1], in_img[..., 1])
        assert_array_equal(out_img[..., 2], in_img[..., 0])

    def test_rgb2bgr(self):
        in_img = np.random.rand(10, 10, 3).astype(np.float32)
        out_img = mmcv.rgb2bgr(in_img)
        assert out_img.shape == in_img.shape
        assert_array_equal(out_img[..., 0], in_img[..., 2])
        assert_array_equal(out_img[..., 1], in_img[..., 1])
        assert_array_equal(out_img[..., 2], in_img[..., 0])

    def test_bgr2hsv(self):
        in_img = np.random.rand(10, 10, 3).astype(np.float32)
        out_img = mmcv.bgr2hsv(in_img)
        argmax = in_img.argmax(axis=2)
        computed_hsv = np.empty_like(in_img, dtype=in_img.dtype)
        for i in range(in_img.shape[0]):
            for j in range(in_img.shape[1]):
                b = in_img[i, j, 0]
                g = in_img[i, j, 1]
                r = in_img[i, j, 2]
                v = max(r, g, b)
                s = (v - min(r, g, b)) / v if v != 0 else 0
                if argmax[i, j] == 0:
                    h = 240 + 60 * (r - g) / (v - min(r, g, b))
                elif argmax[i, j] == 1:
                    h = 120 + 60 * (b - r) / (v - min(r, g, b))
                else:
                    h = 60 * (g - b) / (v - min(r, g, b))
                if h < 0:
                    h += 360
                computed_hsv[i, j, :] = [h, s, v]
        assert_array_almost_equal(out_img, computed_hsv, decimal=2)

Gu Wang's avatar
Gu Wang committed
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
    def test_bgr2hls(self):
        in_img = np.random.rand(10, 10, 3).astype(np.float32)
        out_img = mmcv.bgr2hls(in_img)
        argmax = in_img.argmax(axis=2)
        computed_hls = np.empty_like(in_img, dtype=in_img.dtype)
        for i in range(in_img.shape[0]):
            for j in range(in_img.shape[1]):
                b = in_img[i, j, 0]
                g = in_img[i, j, 1]
                r = in_img[i, j, 2]
                maxc = max(r, g, b)
                minc = min(r, g, b)
                _l = (minc + maxc) / 2.0
                if minc == maxc:
                    h = 0.0
                    s = 0.0
                if _l <= 0.5:
                    s = (maxc - minc) / (maxc + minc)
                else:
                    s = (maxc - minc) / (2.0 - maxc - minc)
                if argmax[i, j] == 2:
                    h = 60 * (g - b) / (maxc - minc)
                elif argmax[i, j] == 1:
                    h = 60 * (2.0 + (b - r) / (maxc - minc))
                else:
                    h = 60 * (4.0 + (r - g) / (maxc - minc))
                if h < 0:
                    h += 360
                computed_hls[i, j, :] = [h, _l, s]
        assert_array_almost_equal(out_img, computed_hls, decimal=2)

146
147
    def test_imresize(self):
        resized_img = mmcv.imresize(self.img, (1000, 600))
148
        assert resized_img.shape == (600, 1000, 3)
149
150
        resized_img, w_scale, h_scale = mmcv.imresize(self.img, (1000, 600),
                                                      True)
151
152
153
        assert (resized_img.shape == (600, 1000, 3) and w_scale == 2.5
                and h_scale == 2.0)
        for mode in ['nearest', 'bilinear', 'bicubic', 'area', 'lanczos']:
154
155
            resized_img = mmcv.imresize(
                self.img, (1000, 600), interpolation=mode)
156
157
            assert resized_img.shape == (600, 1000, 3)

158
    def test_imresize_like(self):
159
        a = np.zeros((100, 200, 3))
160
        resized_img = mmcv.imresize_like(self.img, a)
161
162
        assert resized_img.shape == (100, 200, 3)

163
164
165
    def test_imrescale(self):
        # rescale by a certain factor
        resized_img = mmcv.imrescale(self.img, 1.5)
166
        assert resized_img.shape == (450, 600, 3)
167
        resized_img = mmcv.imrescale(self.img, 0.934)
168
169
        assert resized_img.shape == (280, 374, 3)

170
        # rescale by a certain max_size
171
        # resize (400, 300) to (max_1000, max_600)
172
        resized_img = mmcv.imrescale(self.img, (1000, 600))
173
        assert resized_img.shape == (600, 800, 3)
174
175
        resized_img, scale = mmcv.imrescale(
            self.img, (1000, 600), return_scale=True)
176
177
        assert resized_img.shape == (600, 800, 3) and scale == 2.0
        # resize (400, 300) to (max_200, max_180)
178
        resized_img = mmcv.imrescale(self.img, (180, 200))
179
        assert resized_img.shape == (150, 200, 3)
180
181
        resized_img, scale = mmcv.imrescale(
            self.img, (180, 200), return_scale=True)
182
        assert resized_img.shape == (150, 200, 3) and scale == 0.5
183
184

        # test exceptions
185
        with pytest.raises(ValueError):
186
187
188
            mmcv.imrescale(self.img, -0.5)
        with pytest.raises(TypeError):
            mmcv.imrescale(self.img, [100, 100])
189

Kai Chen's avatar
Kai Chen committed
190
    def test_imflip(self):
Kai Chen's avatar
Kai Chen committed
191
        # test horizontal flip (color image)
Kai Chen's avatar
Kai Chen committed
192
193
        img = np.random.rand(80, 60, 3)
        h, w, c = img.shape
Kai Chen's avatar
Kai Chen committed
194
195
        flipped_img = mmcv.imflip(img)
        assert flipped_img.shape == img.shape
Kai Chen's avatar
Kai Chen committed
196
197
198
        for i in range(h):
            for j in range(w):
                for k in range(c):
Kai Chen's avatar
Kai Chen committed
199
200
201
202
                    assert flipped_img[i, j, k] == img[i, w - 1 - j, k]
        # test vertical flip (color image)
        flipped_img = mmcv.imflip(img, direction='vertical')
        assert flipped_img.shape == img.shape
Kai Chen's avatar
Kai Chen committed
203
204
205
        for i in range(h):
            for j in range(w):
                for k in range(c):
Kai Chen's avatar
Kai Chen committed
206
207
                    assert flipped_img[i, j, k] == img[h - 1 - i, j, k]
        # test horizontal flip (grayscale image)
Kai Chen's avatar
Kai Chen committed
208
        img = np.random.rand(80, 60)
Kai Chen's avatar
Kai Chen committed
209
210
211
        h, w = img.shape
        flipped_img = mmcv.imflip(img)
        assert flipped_img.shape == img.shape
Kai Chen's avatar
Kai Chen committed
212
213
        for i in range(h):
            for j in range(w):
Kai Chen's avatar
Kai Chen committed
214
215
216
217
                assert flipped_img[i, j] == img[i, w - 1 - j]
        # test vertical flip (grayscale image)
        flipped_img = mmcv.imflip(img, direction='vertical')
        assert flipped_img.shape == img.shape
Kai Chen's avatar
Kai Chen committed
218
219
        for i in range(h):
            for j in range(w):
Kai Chen's avatar
Kai Chen committed
220
                assert flipped_img[i, j] == img[h - 1 - i, j]
Kai Chen's avatar
Kai Chen committed
221

222
    def test_imcrop(self):
223
224
225
226
227
228
229
        # yapf: disable
        bboxes = np.array([[100, 100, 199, 199],  # center
                           [0, 0, 150, 100],  # left-top corner
                           [250, 200, 399, 299],  # right-bottom corner
                           [0, 100, 399, 199],  # wide
                           [150, 0, 299, 299]])  # tall
        # yapf: enable
230

231
        # crop one bbox
232
233
        patch = mmcv.imcrop(self.img, bboxes[0, :])
        patches = mmcv.imcrop(self.img, bboxes[[0], :])
234
235
236
237
238
239
        assert patch.shape == (100, 100, 3)
        patch_path = osp.join(osp.dirname(__file__), 'data/patches')
        ref_patch = np.load(patch_path + '/0.npy')
        self.assert_img_equal(patch, ref_patch)
        assert isinstance(patches, list) and len(patches) == 1
        self.assert_img_equal(patches[0], ref_patch)
240

241
        # crop with no scaling and padding
242
        patches = mmcv.imcrop(self.img, bboxes)
243
244
245
246
        assert len(patches) == bboxes.shape[0]
        for i in range(len(patches)):
            ref_patch = np.load(patch_path + '/{}.npy'.format(i))
            self.assert_img_equal(patches[i], ref_patch)
247

248
        # crop with scaling and no padding
249
        patches = mmcv.imcrop(self.img, bboxes, 1.2)
250
251
252
        for i in range(len(patches)):
            ref_patch = np.load(patch_path + '/scale_{}.npy'.format(i))
            self.assert_img_equal(patches[i], ref_patch)
253

254
        # crop with scaling and padding
255
        patches = mmcv.imcrop(self.img, bboxes, 1.2, pad_fill=[255, 255, 0])
256
257
258
        for i in range(len(patches)):
            ref_patch = np.load(patch_path + '/pad_{}.npy'.format(i))
            self.assert_img_equal(patches[i], ref_patch)
259
        patches = mmcv.imcrop(self.img, bboxes, 1.2, pad_fill=0)
260
261
262
263
        for i in range(len(patches)):
            ref_patch = np.load(patch_path + '/pad0_{}.npy'.format(i))
            self.assert_img_equal(patches[i], ref_patch)

264
    def test_impad(self):
265
        img = np.random.rand(10, 10, 3).astype(np.float32)
266
        padded_img = mmcv.impad(img, (15, 12), 0)
267
268
269
270
271
        assert_array_equal(img, padded_img[:10, :10, :])
        assert_array_equal(
            np.zeros((5, 12, 3), dtype='float32'), padded_img[10:, :, :])
        assert_array_equal(
            np.zeros((15, 2, 3), dtype='float32'), padded_img[:, 10:, :])
272

273
        img = np.random.randint(256, size=(10, 10, 3)).astype('uint8')
274
        padded_img = mmcv.impad(img, (15, 12, 3), [100, 110, 120])
275
276
277
278
279
280
281
        assert_array_equal(img, padded_img[:10, :10, :])
        assert_array_equal(
            np.array([100, 110, 120], dtype='uint8') * np.ones(
                (5, 12, 3), dtype='uint8'), padded_img[10:, :, :])
        assert_array_equal(
            np.array([100, 110, 120], dtype='uint8') * np.ones(
                (15, 2, 3), dtype='uint8'), padded_img[:, 10:, :])
282

283
        with pytest.raises(AssertionError):
284
            mmcv.impad(img, (15, ), 0)
285
        with pytest.raises(AssertionError):
286
            mmcv.impad(img, (5, 5), 0)
287
        with pytest.raises(AssertionError):
288
            mmcv.impad(img, (5, 5), [0, 1])
289

Kai Chen's avatar
Kai Chen committed
290
291
292
293
294
295
296
297
298
299
300
    def test_impad_to_multiple(self):
        img = np.random.rand(11, 14, 3).astype(np.float32)
        padded_img = mmcv.impad_to_multiple(img, 4)
        assert padded_img.shape == (12, 16, 3)
        img = np.random.rand(20, 12).astype(np.float32)
        padded_img = mmcv.impad_to_multiple(img, 5)
        assert padded_img.shape == (20, 15)
        img = np.random.rand(20, 12).astype(np.float32)
        padded_img = mmcv.impad_to_multiple(img, 2)
        assert padded_img.shape == (20, 12)

301
    def test_imrotate(self):
302
        img = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]).astype(np.uint8)
303
        assert_array_equal(mmcv.imrotate(img, 0), img)
304
        img_r = np.array([[7, 4, 1], [8, 5, 2], [9, 6, 3]])
305
        assert_array_equal(mmcv.imrotate(img, 90), img_r)
306
        img_r = np.array([[3, 6, 9], [2, 5, 8], [1, 4, 7]])
307
        assert_array_equal(mmcv.imrotate(img, -90), img_r)
308
309
310

        img = np.array([[1, 2, 3, 4], [5, 6, 7, 8]]).astype(np.uint8)
        img_r = np.array([[0, 6, 2, 0], [0, 7, 3, 0]])
311
        assert_array_equal(mmcv.imrotate(img, 90), img_r)
312
        img_r = np.array([[1, 0, 0, 0], [2, 0, 0, 0]])
313
        assert_array_equal(mmcv.imrotate(img, 90, center=(0, 0)), img_r)
314
        img_r = np.array([[255, 6, 2, 255], [255, 7, 3, 255]])
315
        assert_array_equal(mmcv.imrotate(img, 90, border_value=255), img_r)
316
        img_r = np.array([[5, 1], [6, 2], [7, 3], [8, 4]])
317
318
319
320
        assert_array_equal(mmcv.imrotate(img, 90, auto_bound=True), img_r)

        with pytest.raises(ValueError):
            mmcv.imrotate(img, 90, center=(0, 0), auto_bound=True)
Yue Zhao's avatar
Yue Zhao committed
321
322
323
324
325
326
327

    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)