Coretex
image_sample_data.py
1 # Copyright (C) 2023 Coretex LLC
2 
3 # This file is part of Coretex.ai
4 
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License as
7 # published by the Free Software Foundation, either version 3 of the
8 # License, or (at your option) any later version.
9 
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU Affero General Public License for more details.
14 
15 # You should have received a copy of the GNU Affero General Public License
16 # along with this program. If not, see <https://www.gnu.org/licenses/>.
17 
18 from typing import Final, Optional
19 from pathlib import Path
20 
21 import json
22 
23 from PIL import Image, ImageOps
24 from PIL.Image import Image as PILImage
25 
26 import numpy as np
27 
28 from .image_format import ImageFormat
29 from ...annotation import CoretexImageAnnotation, ImageDatasetClasses
30 
31 
32 def _findImage(path: Path) -> Path:
33  for format in ImageFormat:
34  imagePaths = list(path.glob(f"*.{format.extension}"))
35  imagePaths = [path for path in imagePaths if not "thumb" in str(path)]
36 
37  if len(imagePaths) > 0:
38  return Path(imagePaths[0])
39 
40  raise RuntimeError
41 
42 
43 def _readImageData(path: Path) -> np.ndarray:
44  image = ImageOps.exif_transpose(Image.open(path))
45  if not isinstance(image, PILImage):
46  raise TypeError(f"Expected \"PIL.Image.Image\" recieved \"{type(image)}\"")
47 
48  if image.mode != "RGB":
49  image = image.convert("RGB")
50 
51  imageData = np.frombuffer(image.tobytes(), dtype = np.uint8)
52  imageData = imageData.reshape((image.size[1], image.size[0], 3))
53 
54  return imageData
55 
56 
57 def _readAnnotationData(path: Path) -> CoretexImageAnnotation:
58  with open(path, "r") as annotationsFile:
59  return CoretexImageAnnotation.decode(
60  json.load(annotationsFile)
61  )
62 
63 
65 
66  """
67  Contains image data as well as its annotation\n
68  Annotation is expected to be in Coretex.ai format
69  """
70 
71  def __init__(self, path: Path) -> None:
72  self.image: Final = _readImageData(_findImage(path))
73  self.annotationannotation: Optional[CoretexImageAnnotation] = None
74 
75  annotationPath = path / "annotations.json"
76  if annotationPath.exists():
77  self.annotationannotation = _readAnnotationData(annotationPath)
78 
79  def extractSegmentationMask(self, classes: ImageDatasetClasses) -> np.ndarray:
80  """
81  Generates segmentation mask for the provided classes
82 
83  Parameters
84  ----------
85  classes : ImageDatasetClasses
86  list of dataset classes
87 
88  Returns
89  -------
90  np.ndarray -> segmentation mask represented as np.ndarray
91  """
92 
93  if self.annotationannotation is None:
94  raise ValueError
95 
96  return self.annotationannotation.extractSegmentationMask(classes)