test_transforms_video.py 6.15 KB
Newer Older
Zhicheng Yan's avatar
Zhicheng Yan committed
1
import random
2
import warnings
3
4
5
6

import numpy as np
import pytest
import torch
7
from common_utils import assert_equal
8
from torchvision.transforms import Compose
Zhicheng Yan's avatar
Zhicheng Yan committed
9
10
11
12
13
14
15

try:
    from scipy import stats
except ImportError:
    stats = None


16
17
18
19
20
with warnings.catch_warnings(record=True):
    warnings.simplefilter("always")
    import torchvision.transforms._transforms_video as transforms


21
class TestVideoTransforms:
Zhicheng Yan's avatar
Zhicheng Yan committed
22
23
24
25
26
27
28
    def test_random_crop_video(self):
        numFrames = random.randint(4, 128)
        height = random.randint(10, 32) * 2
        width = random.randint(10, 32) * 2
        oheight = random.randint(5, (height - 2) / 2) * 2
        owidth = random.randint(5, (width - 2) / 2) * 2
        clip = torch.randint(0, 256, (numFrames, height, width, 3), dtype=torch.uint8)
29
30
31
32
33
34
        result = Compose(
            [
                transforms.ToTensorVideo(),
                transforms.RandomCropVideo((oheight, owidth)),
            ]
        )(clip)
35
36
        assert result.size(2) == oheight
        assert result.size(3) == owidth
Zhicheng Yan's avatar
Zhicheng Yan committed
37
38
39
40
41
42
43
44
45
46

        transforms.RandomCropVideo((oheight, owidth)).__repr__()

    def test_random_resized_crop_video(self):
        numFrames = random.randint(4, 128)
        height = random.randint(10, 32) * 2
        width = random.randint(10, 32) * 2
        oheight = random.randint(5, (height - 2) / 2) * 2
        owidth = random.randint(5, (width - 2) / 2) * 2
        clip = torch.randint(0, 256, (numFrames, height, width, 3), dtype=torch.uint8)
47
48
49
50
51
52
        result = Compose(
            [
                transforms.ToTensorVideo(),
                transforms.RandomResizedCropVideo((oheight, owidth)),
            ]
        )(clip)
53
54
        assert result.size(2) == oheight
        assert result.size(3) == owidth
Zhicheng Yan's avatar
Zhicheng Yan committed
55
56
57
58
59
60
61
62
63
64
65
66
67

        transforms.RandomResizedCropVideo((oheight, owidth)).__repr__()

    def test_center_crop_video(self):
        numFrames = random.randint(4, 128)
        height = random.randint(10, 32) * 2
        width = random.randint(10, 32) * 2
        oheight = random.randint(5, (height - 2) / 2) * 2
        owidth = random.randint(5, (width - 2) / 2) * 2

        clip = torch.ones((numFrames, height, width, 3), dtype=torch.uint8) * 255
        oh1 = (height - oheight) // 2
        ow1 = (width - owidth) // 2
68
        clipNarrow = clip[:, oh1 : oh1 + oheight, ow1 : ow1 + owidth, :]
Zhicheng Yan's avatar
Zhicheng Yan committed
69
        clipNarrow.fill_(0)
70
71
72
73
74
75
76
77
78
79
        result = Compose(
            [
                transforms.ToTensorVideo(),
                transforms.CenterCropVideo((oheight, owidth)),
            ]
        )(clip)

        msg = (
            "height: " + str(height) + " width: " + str(width) + " oheight: " + str(oheight) + " owidth: " + str(owidth)
        )
80
        assert result.sum().item() == 0, msg
Zhicheng Yan's avatar
Zhicheng Yan committed
81
82
83

        oheight += 1
        owidth += 1
84
85
86
87
88
89
        result = Compose(
            [
                transforms.ToTensorVideo(),
                transforms.CenterCropVideo((oheight, owidth)),
            ]
        )(clip)
Zhicheng Yan's avatar
Zhicheng Yan committed
90
91
        sum1 = result.sum()

92
93
94
        msg = (
            "height: " + str(height) + " width: " + str(width) + " oheight: " + str(oheight) + " owidth: " + str(owidth)
        )
95
        assert sum1.item() > 1, msg
Zhicheng Yan's avatar
Zhicheng Yan committed
96
97
98

        oheight += 1
        owidth += 1
99
100
101
102
103
104
        result = Compose(
            [
                transforms.ToTensorVideo(),
                transforms.CenterCropVideo((oheight, owidth)),
            ]
        )(clip)
Zhicheng Yan's avatar
Zhicheng Yan committed
105
106
        sum2 = result.sum()

107
108
109
        msg = (
            "height: " + str(height) + " width: " + str(width) + " oheight: " + str(oheight) + " owidth: " + str(owidth)
        )
110
111
        assert sum2.item() > 1, msg
        assert sum2.item() > sum1.item(), msg
Zhicheng Yan's avatar
Zhicheng Yan committed
112

113
114
    @pytest.mark.skipif(stats is None, reason="scipy.stats is not available")
    @pytest.mark.parametrize("channels", [1, 3])
115
    def test_normalize_video(self, channels):
Zhicheng Yan's avatar
Zhicheng Yan committed
116
        def samples_from_standard_normal(tensor):
117
            p_value = stats.kstest(list(tensor.view(-1)), "norm", args=(0, 1)).pvalue
Zhicheng Yan's avatar
Zhicheng Yan committed
118
119
120
121
            return p_value > 0.0001

        random_state = random.getstate()
        random.seed(42)
122
123
124
125
126
127
128
129
130
131
132

        numFrames = random.randint(4, 128)
        height = random.randint(32, 256)
        width = random.randint(32, 256)
        mean = random.random()
        std = random.random()
        clip = torch.normal(mean, std, size=(channels, numFrames, height, width))
        mean = [clip[c].mean().item() for c in range(channels)]
        std = [clip[c].std().item() for c in range(channels)]
        normalized = transforms.NormalizeVideo(mean, std)(clip)
        assert samples_from_standard_normal(normalized)
Zhicheng Yan's avatar
Zhicheng Yan committed
133
134
135
136
137
        random.setstate(random_state)

        # Checking the optional in-place behaviour
        tensor = torch.rand((3, 128, 16, 16))
        tensor_inplace = transforms.NormalizeVideo((0.5, 0.5, 0.5), (0.5, 0.5, 0.5), inplace=True)(tensor)
138
        assert_equal(tensor, tensor_inplace)
Zhicheng Yan's avatar
Zhicheng Yan committed
139
140
141
142
143
144
145

        transforms.NormalizeVideo((0.5, 0.5, 0.5), (0.5, 0.5, 0.5), inplace=True).__repr__()

    def test_to_tensor_video(self):
        numFrames, height, width = 64, 4, 4
        trans = transforms.ToTensorVideo()

146
        with pytest.raises(TypeError):
147
148
            np_rng = np.random.RandomState(0)
            trans(np_rng.rand(numFrames, height, width, 1).tolist())
149
        with pytest.raises(TypeError):
Zhicheng Yan's avatar
Zhicheng Yan committed
150
151
            trans(torch.rand((numFrames, height, width, 1), dtype=torch.float))

152
        with pytest.raises(ValueError):
Zhicheng Yan's avatar
Zhicheng Yan committed
153
            trans(torch.ones((3, numFrames, height, width, 3), dtype=torch.uint8))
154
        with pytest.raises(ValueError):
Zhicheng Yan's avatar
Zhicheng Yan committed
155
            trans(torch.ones((height, width, 3), dtype=torch.uint8))
156
        with pytest.raises(ValueError):
Zhicheng Yan's avatar
Zhicheng Yan committed
157
            trans(torch.ones((width, 3), dtype=torch.uint8))
158
        with pytest.raises(ValueError):
Zhicheng Yan's avatar
Zhicheng Yan committed
159
160
161
162
            trans(torch.ones((3), dtype=torch.uint8))

        trans.__repr__()

163
164
    @pytest.mark.parametrize("p", (0, 1))
    def test_random_horizontal_flip_video(self, p):
Zhicheng Yan's avatar
Zhicheng Yan committed
165
        clip = torch.rand((3, 4, 112, 112), dtype=torch.float)
166
        hclip = clip.flip(-1)
Zhicheng Yan's avatar
Zhicheng Yan committed
167

168
169
170
171
172
        out = transforms.RandomHorizontalFlipVideo(p=p)(clip)
        if p == 0:
            torch.testing.assert_close(out, clip)
        elif p == 1:
            torch.testing.assert_close(out, hclip)
Zhicheng Yan's avatar
Zhicheng Yan committed
173
174
175
176

        transforms.RandomHorizontalFlipVideo().__repr__()


177
if __name__ == "__main__":
178
    pytest.main([__file__])