• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

ContinualAI / avalanche / 5399886876

pending completion
5399886876

Pull #1398

github

web-flow
Merge 2c8aba8e6 into a61ae5cab
Pull Request #1398: switch to black formatting

1023 of 1372 new or added lines in 177 files covered. (74.56%)

144 existing lines in 66 files now uncovered.

16366 of 22540 relevant lines covered (72.61%)

2.9 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

21.18
/avalanche/benchmarks/datasets/penn_fudan/penn_fudan_dataset.py
1
# The dataset code has been adapted from:
2
# https://pytorch.org/tutorials/intermediate/torchvision_tutorial.html
3
# from https://github.com/pytorch/tutorials
4
# which has been distributed under the following license:
5
################################################################################
6
# BSD 3-Clause License
7
#
8
# Copyright (c) 2017, Pytorch contributors
9
# All rights reserved.
10
#
11
# Redistribution and use in source and binary forms, with or without
12
# modification, are permitted provided that the following conditions are met:
13
#
14
# * Redistributions of source code must retain the above copyright notice, this
15
#   list of conditions and the following disclaimer.
16
#
17
# * Redistributions in binary form must reproduce the above copyright notice,
18
#   this list of conditions and the following disclaimer in the documentation
19
#   and/or other materials provided with the distribution.
20
#
21
# * Neither the name of the copyright holder nor the names of its
22
#   contributors may be used to endorse or promote products derived from
23
#   this software without specific prior written permission.
24
#
25
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
28
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
29
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
31
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
32
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
33
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35
################################################################################
36

37
# For the Avalanche data loader adaptation:
38
################################################################################
39
# Copyright (c) 2022 ContinualAI                                               #
40
# Copyrights licensed under the MIT License.                                   #
41
# See the accompanying LICENSE file for terms.                                 #
42
#                                                                              #
43
# Date: 21-03-2022                                                             #
44
# Author: Lorenzo Pellegrini                                                   #
45
#                                                                              #
46
# E-mail: contact@continualai.org                                              #
47
# Website: www.continualai.org                                                 #
48
################################################################################
49

50

51
from pathlib import Path
4✔
52
from typing import Dict, List, Optional, Sequence, Union
4✔
53

54
import numpy as np
4✔
55
import torch
4✔
56
from PIL import Image
4✔
57
from torchvision.datasets.folder import default_loader
4✔
58

59
from avalanche.benchmarks.datasets import (
4✔
60
    SimpleDownloadableDataset,
61
    default_dataset_location,
62
)
63
from avalanche.benchmarks.datasets.penn_fudan.penn_fudan_data import (
4✔
64
    penn_fudan_data,
65
)
66

67

68
def default_mask_loader(mask_path):
4✔
69
    return Image.open(mask_path)
×
70

71

72
class PennFudanDataset(SimpleDownloadableDataset):
4✔
73
    """
4✔
74
    The Penn-Fudan Pedestrian detection and segmentation dataset
75

76
    Adapted from the "TorchVision Object Detection Finetuning Tutorial":
77
    https://pytorch.org/tutorials/intermediate/torchvision_tutorial.html
78
    """
79

80
    def __init__(
4✔
81
        self,
82
        root: Optional[Union[str, Path]] = None,
83
        *,
84
        transform=None,
85
        loader=default_loader,
86
        mask_loader=default_mask_loader,
87
        download=True
88
    ):
89
        """
90
        Creates an instance of the Penn-Fudan dataset.
91

92
        :param root: The directory where the dataset can be found or downloaded.
93
            Defaults to None, which means that the default location for
94
            "pennfudanped" will be used.
95
        :param transform: The transformation to apply to (img, annotations)
96
            values.
97
        :param loader: The image loader to use.
98
        :param mask_loader: The mask image loader to use.
99
        :param download: If True, the dataset will be downloaded if needed.
100
        """
101

102
        if root is None:
×
103
            root = default_dataset_location("pennfudanped")
×
104

105
        self.imgs: Sequence[Path] = None  # type: ignore
×
106
        self.masks: Sequence[Path] = None  # type: ignore
×
107
        self.targets: List[Dict] = None  # type: ignore
×
108
        self.transform = transform
×
109
        self.loader = loader
×
110
        self.mask_loader = mask_loader
×
111

112
        super().__init__(
×
113
            root,
114
            penn_fudan_data[0],
115
            penn_fudan_data[1],
116
            download=download,
117
            verbose=True,
118
        )
119

120
        self._load_dataset()
×
121

122
    def _load_metadata(self):
4✔
123
        # load all image files, sorting them to
124
        # ensure that they are aligned
125
        imgs = (self.root / "PennFudanPed" / "PNGImages").iterdir()
×
126
        masks = (self.root / "PennFudanPed" / "PedMasks").iterdir()
×
127

128
        self.imgs = list(sorted(imgs))
×
129
        self.masks = list(sorted(masks))
×
130

131
        self.targets = [self.make_targets(i) for i in range(len(self.imgs))]
×
132
        return Path(self.imgs[0]).exists() and Path(self.masks[0]).exists()
×
133

134
    def make_targets(self, idx):
4✔
135
        # load images and masks
136
        mask_path = self.masks[idx]
×
137

138
        # note that we haven't converted the mask to RGB,
139
        # because each color corresponds to a different instance
140
        # with 0 being background
141
        mask = self.mask_loader(mask_path)
×
142
        # convert the PIL Image into a numpy array
143
        mask = np.array(mask)
×
144
        # instances are encoded as different colors
145
        obj_ids = np.unique(mask)
×
146
        # first id is the background, so remove it
147
        obj_ids = obj_ids[1:]
×
148

149
        # split the color-encoded mask into a set
150
        # of binary masks
151
        masks = mask == obj_ids[:, None, None]
×
152

153
        # get bounding box coordinates for each mask
154
        num_objs = len(obj_ids)
×
155
        boxes = []
×
156
        for i in range(num_objs):
×
157
            pos = np.where(masks[i])
×
158
            xmin: np.integer = np.min(pos[1])
×
159
            xmax: np.integer = np.max(pos[1])
×
160
            ymin: np.integer = np.min(pos[0])
×
161
            ymax: np.integer = np.max(pos[0])
×
162
            boxes.append([xmin, ymin, xmax, ymax])
×
163

164
        # convert everything into a torch.Tensor
165
        boxes_as_tensor = torch.as_tensor(boxes, dtype=torch.float32)
×
166
        del boxes
×
167
        # there is only one class
168
        labels = torch.ones((num_objs,), dtype=torch.int64)
×
169
        masks = torch.as_tensor(masks, dtype=torch.uint8)
×
170

171
        image_id = torch.tensor([idx])
×
NEW
172
        area = (boxes_as_tensor[:, 3] - boxes_as_tensor[:, 1]) * (
×
173
            boxes_as_tensor[:, 2] - boxes_as_tensor[:, 0]
174
        )
175
        # suppose all instances are not crowd
176
        iscrowd = torch.zeros((num_objs,), dtype=torch.int64)
×
177

178
        target = {}
×
179
        target["boxes"] = boxes_as_tensor
×
180
        target["labels"] = labels
×
181
        target["masks"] = masks
×
182
        target["image_id"] = image_id
×
183
        target["area"] = area
×
184
        target["iscrowd"] = iscrowd
×
185
        return target
×
186

187
    def __getitem__(self, idx):
4✔
188
        target = self.targets[idx]
×
189
        img_path = self.imgs[idx]
×
190
        img = self.loader(img_path)
×
191

192
        if self.transform is not None:
×
193
            img, target = self.transform(img, target)
×
194

195
        return img, target
×
196

197
    def __len__(self):
4✔
198
        return len(self.imgs)
×
199

200

201
if __name__ == "__main__":
4✔
202
    # this little example script can be used to visualize the first image
203
    # loaded from the dataset.
204
    from torch.utils.data.dataloader import DataLoader
×
205
    import matplotlib.pyplot as plt
×
206
    from torchvision import transforms
×
207
    import torch
×
208

209
    train_data = PennFudanDataset(
×
210
        transform=lambda im, ann: (transforms.ToTensor()(im), ann)
211
    )
212
    dataloader = DataLoader(train_data, batch_size=1)
×
213

214
    for batch_data in dataloader:
×
215
        x, y = batch_data
×
216
        plt.imshow(transforms.ToPILImage()(torch.squeeze(x)))
×
217
        plt.show()
×
218
        print(x.shape)
×
219
        print(y)
×
220
        break
×
221

222

223
__all__ = ["PennFudanDataset"]
4✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc