Coretex
base_converter.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 Any, Final, List, Set
19 from enum import Enum
20 from abc import ABC, abstractmethod
21 
22 import logging
23 
24 from ..annotation import CoretexImageAnnotation
25 from ...entities import ImageDataset, ImageDatasetClass
26 from ...threading import MultithreadedDataProcessor
27 
28 
30 
31  """
32  List of all annotation formats supported by Coretex
33  """
34 
35  coco = 0
36  yolo = 1
37  createML = 2
38  voc = 3
39  labelMe = 4
40  pascalSeg = 5
41 
42  # TODO: Migrate to Human Segmentation task template repo, or try to make it generic
43  humanSegmentation = 6
44 
45  cityScape = 7
46 
47 
48 class BaseConverter(ABC):
49 
50  """
51  Base class for Coretex Annotation format conversion
52 
53  Properties
54  ----------
55  datasetName : str
56  name of dataset
57  projectId : int
58  id of Coretex Project
59  datasetPath : str
60  path to dataset
61  """
62 
63  def __init__(self, datasetName: str, projectId: int, datasetPath: str) -> None:
64  self._dataset: Final = ImageDataset.createDataset(datasetName, projectId)
65  self._datasetPath: Final = datasetPath
66 
67  def _saveImageAnnotationPair(self, imagePath: str, annotation: CoretexImageAnnotation) -> None:
68  sample = self._dataset.add(imagePath)
69 
70  # Attach annotation to sample
71  if not sample.saveAnnotation(annotation):
72  logging.getLogger("coretexpylib").info(">> [Coretex] Failed to save ImageSample annotation")
73 
74  @abstractmethod
75  def _dataSource(self) -> List[Any]:
76  pass
77 
78  @abstractmethod
79  def _extractLabels(self) -> Set[str]:
80  pass
81 
82  @abstractmethod
83  def _extractSingleAnnotation(self, value: Any) -> None:
84  pass
85 
86  def convert(self) -> ImageDataset:
87  """
88  Converts the dataset to Coretex Format
89 
90  Returns
91  -------
92  ImageDatasetType -> The converted ImageDataset object
93  """
94 
95  # Extract classes
96  labels = self._extractLabels_extractLabels()
97  classes = ImageDatasetClass.generate(labels)
98 
99  if self._dataset.saveClasses(classes):
100  logging.getLogger("coretexpylib").info(">> [Coretex] Dataset classes saved successfully")
101  else:
102  logging.getLogger("coretexpylib").info(">> [Coretex] Failed to save dataset classes")
103 
104  # Extract annotations
105  MultithreadedDataProcessor(
106  self._dataSource_dataSource(),
107  self._extractSingleAnnotation_extractSingleAnnotation,
108  message = "Converting dataset..."
109  ).process()
110 
111  if not self._dataset.finalize():
112  raise ValueError(f"Failed to finalize dataset \"{self._dataset.name}\"")
113 
114  return self._dataset