test_reader.py 6.41 KB
Newer Older
Kai Chen's avatar
Kai Chen committed
1
# Copyright (c) Open-MMLab. All rights reserved.
2
3
import os
import os.path as osp
4
import shutil
5
6
7
8
9
import tempfile
from collections import OrderedDict

import pytest

Kai Chen's avatar
Kai Chen committed
10
11
import mmcv

12

Kai Chen's avatar
Kai Chen committed
13
class TestCache:
14
15
16
17
18
19
20
21
22
23
24

    def test_init(self):
        with pytest.raises(ValueError):
            mmcv.Cache(0)
        cache = mmcv.Cache(100)
        assert cache.capacity == 100
        assert cache.size == 0

    def test_put(self):
        cache = mmcv.Cache(3)
        for i in range(1, 4):
Cao Yuhang's avatar
Cao Yuhang committed
25
            cache.put(f'k{i}', i)
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
            assert cache.size == i
        assert cache._cache == OrderedDict([('k1', 1), ('k2', 2), ('k3', 3)])
        cache.put('k4', 4)
        assert cache.size == 3
        assert cache._cache == OrderedDict([('k2', 2), ('k3', 3), ('k4', 4)])
        cache.put('k2', 2)
        assert cache._cache == OrderedDict([('k2', 2), ('k3', 3), ('k4', 4)])

    def test_get(self):
        cache = mmcv.Cache(3)
        assert cache.get('key_none') is None
        assert cache.get('key_none', 0) == 0
        cache.put('k1', 1)
        assert cache.get('k1') == 1


Kai Chen's avatar
Kai Chen committed
42
class TestVideoReader:
43
44
45

    @classmethod
    def setup_class(cls):
Kai Chen's avatar
Kai Chen committed
46
        cls.video_path = osp.join(osp.dirname(__file__), '../data/test.mp4')
47
        cls.num_frames = 168
48
        cls.video_url = 'https://www.learningcontainer.com/wp-content/uploads/2020/05/sample-mp4-file.mp4'  # noqa: E501
49
50

    def test_load(self):
51
        # read from video file
52
53
54
55
56
57
58
59
60
61
        v = mmcv.VideoReader(self.video_path)
        assert v.width == 294
        assert v.height == 240
        assert v.fps == 25
        assert v.frame_cnt == self.num_frames
        assert len(v) == self.num_frames
        assert v.opened
        import cv2
        assert isinstance(v.vcap, type(cv2.VideoCapture()))

62
63
64
65
66
67
68
69
70
71
        # read from video url
        v = mmcv.VideoReader(self.video_url)
        assert v.width == 320
        assert v.height == 240
        assert v.fps == 15
        assert v.frame_cnt == 1889
        assert len(v) == 1889
        assert v.opened
        assert isinstance(v.vcap, type(cv2.VideoCapture()))

72
73
74
75
    def test_read(self):
        v = mmcv.VideoReader(self.video_path)
        img = v.read()
        assert int(round(img.mean())) == 94
xiongyu's avatar
xiongyu committed
76
        img = v.get_frame(63)
77
78
        assert int(round(img.mean())) == 94
        img = v[64]
xiongyu's avatar
xiongyu committed
79
        assert int(round(img.mean())) == 205
xiongyu's avatar
xiongyu committed
80
81
        img = v[-104]
        assert int(round(img.mean())) == 205
xiongyu's avatar
xiongyu committed
82
        img = v[63]
83
        assert int(round(img.mean())) == 94
xiongyu's avatar
xiongyu committed
84
85
        img = v[-105]
        assert int(round(img.mean())) == 94
86
87
        img = v.read()
        assert int(round(img.mean())) == 205
88
        with pytest.raises(IndexError):
89
            v.get_frame(self.num_frames + 1)
xiongyu's avatar
xiongyu committed
90
91
        with pytest.raises(IndexError):
            v[-self.num_frames - 1]
92

xiongyu's avatar
xiongyu committed
93
94
95
96
97
    def test_slice(self):
        v = mmcv.VideoReader(self.video_path)
        imgs = v[-105:-103]
        assert int(round(imgs[0].mean())) == 94
        assert int(round(imgs[1].mean())) == 205
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
        assert len(imgs) == 2
        imgs = v[63:65]
        assert int(round(imgs[0].mean())) == 94
        assert int(round(imgs[1].mean())) == 205
        assert len(imgs) == 2
        imgs = v[64:62:-1]
        assert int(round(imgs[0].mean())) == 205
        assert int(round(imgs[1].mean())) == 94
        assert len(imgs) == 2
        imgs = v[:5]
        assert len(imgs) == 5
        for img in imgs:
            assert int(round(img.mean())) == 94
        imgs = v[165:]
        assert len(imgs) == 3
        for img in imgs:
            assert int(round(img.mean())) == 0
        imgs = v[-3:]
        assert len(imgs) == 3
        for img in imgs:
            assert int(round(img.mean())) == 0
xiongyu's avatar
xiongyu committed
119

120
121
122
123
124
125
126
127
128
129
130
131
132
    def test_current_frame(self):
        v = mmcv.VideoReader(self.video_path)
        assert v.current_frame() is None
        v.read()
        img = v.current_frame()
        assert int(round(img.mean())) == 94

    def test_position(self):
        v = mmcv.VideoReader(self.video_path)
        assert v.position == 0
        for _ in range(10):
            v.read()
        assert v.position == 10
xiongyu's avatar
xiongyu committed
133
        v.get_frame(99)
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
        assert v.position == 100

    def test_iterator(self):
        cnt = 0
        for img in mmcv.VideoReader(self.video_path):
            cnt += 1
            assert img.shape == (240, 294, 3)
        assert cnt == self.num_frames

    def test_with(self):
        with mmcv.VideoReader(self.video_path) as v:
            assert v.opened
        assert not v.opened

    def test_cvt2frames(self):
        v = mmcv.VideoReader(self.video_path)
        frame_dir = tempfile.mkdtemp()
        v.cvt2frames(frame_dir)
        assert osp.isdir(frame_dir)
        for i in range(self.num_frames):
Cao Yuhang's avatar
Cao Yuhang committed
154
            filename = f'{frame_dir}/{i:06d}.jpg'
155
156
157
158
159
160
161
            assert osp.isfile(filename)
            os.remove(filename)

        v = mmcv.VideoReader(self.video_path)
        v.cvt2frames(frame_dir, show_progress=False)
        assert osp.isdir(frame_dir)
        for i in range(self.num_frames):
Cao Yuhang's avatar
Cao Yuhang committed
162
            filename = f'{frame_dir}/{i:06d}.jpg'
163
164
165
166
167
168
169
170
171
172
173
174
            assert osp.isfile(filename)
            os.remove(filename)

        v = mmcv.VideoReader(self.video_path)
        v.cvt2frames(
            frame_dir,
            file_start=100,
            filename_tmpl='{:03d}.JPEG',
            start=100,
            max_num=20)
        assert osp.isdir(frame_dir)
        for i in range(100, 120):
Cao Yuhang's avatar
Cao Yuhang committed
175
            filename = f'{frame_dir}/{i:03d}.JPEG'
176
177
            assert osp.isfile(filename)
            os.remove(filename)
178
        shutil.rmtree(frame_dir)
179
180
181
182
183
184
185

    def test_frames2video(self):
        v = mmcv.VideoReader(self.video_path)
        frame_dir = tempfile.mkdtemp()
        v.cvt2frames(frame_dir)
        assert osp.isdir(frame_dir)
        for i in range(self.num_frames):
Cao Yuhang's avatar
Cao Yuhang committed
186
            filename = f'{frame_dir}/{i:06d}.jpg'
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
            assert osp.isfile(filename)

        out_filename = osp.join(tempfile.gettempdir(), 'mmcv_test.avi')
        mmcv.frames2video(frame_dir, out_filename)
        v = mmcv.VideoReader(out_filename)
        assert v.fps == 30
        assert len(v) == self.num_frames

        mmcv.frames2video(
            frame_dir,
            out_filename,
            fps=25,
            start=10,
            end=50,
            show_progress=False)
        v = mmcv.VideoReader(out_filename)
        assert v.fps == 25
        assert len(v) == 40

        for i in range(self.num_frames):
Cao Yuhang's avatar
Cao Yuhang committed
207
            filename = f'{frame_dir}/{i:06d}.jpg'
208
            os.remove(filename)
209
        shutil.rmtree(frame_dir)
210
        os.remove(out_filename)