Coverage for src/deepdraw/data/refuge/__init__.py: 63%

38 statements  

« prev     ^ index     » next       coverage.py v7.3.1, created at 2023-11-30 15:00 +0100

1# SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch> 

2# 

3# SPDX-License-Identifier: GPL-3.0-or-later 

4 

5"""REFUGE for Optic Disc and Cup Segmentation. 

6 

7The dataset consists of 1200 color fundus photographs, created for a MICCAI 

8challenge. The goal of the challenge is to evaluate and compare automated 

9algorithms for glaucoma detection and optic disc/cup segmentation on a common 

10dataset of retinal fundus images. 

11 

12* Reference (including train/dev/test split): [REFUGE-2018]_ 

13* Protocols ``optic-disc`` and ``cup``: 

14 

15 * Training samples: 

16 

17 * 400 

18 * includes optic-disc and cup labels 

19 * includes label: glaucomatous and non-glaucomatous 

20 * original resolution: 2056 x 2124 

21 

22 * Validation samples: 

23 

24 * 400 

25 * includes optic-disc and cup labels 

26 * original resolution: 1634 x 1634 

27 

28 * Test samples: 

29 

30 * 400 

31 * includes optic-disc and cup labels 

32 * includes label: glaucomatous and non-glaucomatous 

33 * original resolution: 

34""" 

35 

36import os 

37 

38import pkg_resources 

39 

40from ...data.dataset import JSONDataset 

41from ...utils.rc import load_rc 

42from ..loader import load_pil_1, load_pil_rgb, make_delayed 

43 

44_protocols = { 

45 "optic-disc": pkg_resources.resource_filename(__name__, "default.json"), 

46 "optic-cup": pkg_resources.resource_filename(__name__, "default.json"), 

47} 

48 

49_root_path = load_rc().get("datadir.refuge", os.path.realpath(os.curdir)) 

50_pkg_path = pkg_resources.resource_filename(__name__, "masks") 

51 

52 

53def _disc_loader(sample): 

54 retval = dict( 

55 data=load_pil_rgb(os.path.join(_root_path, sample["data"])), 

56 label=load_pil_rgb(os.path.join(_root_path, sample["label"])), 

57 mask=load_pil_1(os.path.join(_pkg_path, sample["mask"])), 

58 ) 

59 if "glaucoma" in sample: 

60 retval["glaucoma"] = sample["glaucoma"] 

61 retval["label"] = retval["label"].convert("L") 

62 retval["label"] = retval["label"].point(lambda p: p <= 150, mode="1") 

63 return retval 

64 

65 

66def _cup_loader(sample): 

67 retval = dict( 

68 data=load_pil_rgb(os.path.join(_root_path, sample["data"])), 

69 label=load_pil_rgb(os.path.join(_root_path, sample["label"])), 

70 mask=load_pil_1(os.path.join(_pkg_path, sample["mask"])), 

71 ) 

72 if "glaucoma" in sample: 

73 retval["glaucoma"] = sample["glaucoma"] 

74 retval["label"] = retval["label"].convert("L") 

75 retval["label"] = retval["label"].point(lambda p: p <= 100, mode="1") 

76 return retval 

77 

78 

79def _loader(context, sample): 

80 if context["subset"] == "train": 

81 # adds binary metadata for glaucoma/non-glaucoma patients 

82 sample["glaucoma"] = os.path.basename(sample["label"]).startswith("g") 

83 elif context["subset"] == "test": 

84 sample["glaucoma"] = sample["label"].split(os.sep)[-2] == "G" 

85 elif context["subset"] == "validation": 

86 pass 

87 else: 

88 raise RuntimeError(f"Unknown subset {context['subset']}") 

89 

90 # optic disc is drawn with gray == 128 and includes the cup, drawn with 

91 # black == 0. The rest is white == 255. 

92 if context["protocol"] == "optic-disc": 

93 return make_delayed(sample, _disc_loader) 

94 elif context["protocol"] == "optic-cup": 

95 return make_delayed(sample, _cup_loader) 

96 else: 

97 raise RuntimeError(f"Unknown protocol {context['protocol']}") 

98 

99 

100dataset = JSONDataset( 

101 protocols=_protocols, 

102 fieldnames=("data", "label", "mask"), 

103 loader=_loader, 

104) 

105"""REFUGE dataset object."""