diff --git a/.gitignore b/.gitignore
index 6ba2c81..2fab267 100644
--- a/.gitignore
+++ b/.gitignore
@@ -14,7 +14,7 @@
!labelCloud/resources/examples/exemplary.ply
!labelCloud/resources/examples/exemplary.json
!labelCloud/resources/labelCloud_icon.pcd
-!labels/segmentation/schema/label_definition.json
+!labels/schema/label_definition.json
!labels/segmentation/exemplary.bin
# ---------------------------------------------------------------------------- #
diff --git a/config.ini b/config.ini
index 7a904df..6aefc9a 100644
--- a/config.ini
+++ b/config.ini
@@ -1,5 +1,5 @@
[MODE]
-segmentation = true
+segmentation = false
[FILE]
; source of point clouds
@@ -28,8 +28,6 @@ label_color_mix_ratio = 0.3
[LABEL]
; format for exporting labels. choose from (vertices, centroid_rel, centroid_abs, kitti)
label_format = centroid_abs
-; list of object classes for autocompletion in the text field
-object_classes = cart, box
; default object class for new bounding boxes
std_object_class = cart
; number of decimal places for exporting the bounding box parameter.
diff --git a/docs/documentation.md b/docs/documentation.md
index 661f091..ea3ed89 100644
--- a/docs/documentation.md
+++ b/docs/documentation.md
@@ -47,7 +47,6 @@ The following parameters can be changed:
| `std_zoom` | Standard step for zooming (with mouse scroll). | *0.0025* |
| **[LABEL]** |
| `label_format` | Format for exporting labels, choose from `vertices`, `centroid_rel`, `centroid_abs` or `kitti`. | *centroid_abs* |
-| `object_classes` | List of object classes for autocompletion in the class text field. | *class1, class2, ...* |
| `std_object_class` | Default object class for new bounding boxes. | *default_class* |
| `export_precision` | Number of decimal places for exporting the bounding box parameters. | *8* |
| `std_boundingbox_length` | Default length of the bounding box (for picking mode). | *0.75* |
diff --git a/labelCloud/control/bbox_controller.py b/labelCloud/control/bbox_controller.py
index 73e2b7a..7328cdf 100644
--- a/labelCloud/control/bbox_controller.py
+++ b/labelCloud/control/bbox_controller.py
@@ -84,6 +84,9 @@ def add_bbox(self, bbox: BBox) -> None:
if isinstance(bbox, BBox):
self.bboxes.append(bbox)
self.set_active_bbox(self.bboxes.index(bbox))
+ self.view.current_class_dropdown.setCurrentText(
+ self.get_active_bbox().classname # type: ignore
+ )
self.view.status_manager.update_status(
"Bounding Box added, it can now be corrected.", Mode.CORRECTION
)
@@ -306,9 +309,11 @@ def update_z_dial(self) -> None:
def update_curr_class(self) -> None:
if self.has_active_bbox():
- self.view.update_curr_class_edit()
+ self.view.current_class_dropdown.setCurrentText(
+ self.get_active_bbox().classname # type: ignore
+ )
else:
- self.view.update_curr_class_edit(force="")
+ self.view.controller.pcd_manager.populate_class_dropdown()
def update_label_list(self) -> None:
"""Updates the list of drawn labels and highlights the active label.
diff --git a/labelCloud/control/pcd_manager.py b/labelCloud/control/pcd_manager.py
index ffb3939..1be1d26 100644
--- a/labelCloud/control/pcd_manager.py
+++ b/labelCloud/control/pcd_manager.py
@@ -7,10 +7,9 @@
from shutil import copyfile
from typing import TYPE_CHECKING, List, Optional, Set, Tuple
-import pkg_resources
-
import numpy as np
import open3d as o3d
+import pkg_resources
from ..definitions.types import Point3D
from ..io.pointclouds import BasePointCloudHandler, Open3DHandler
@@ -41,7 +40,9 @@ def __init__(self) -> None:
# Point cloud control
self.pointcloud: Optional[PointCloud] = None
- self.collected_object_classes: Set[str] = set()
+ self.collected_object_classes: Set[
+ str
+ ] = set() # TODO: this should integrate with the new label definition setup.
self.saved_perspective: Optional[Perspective] = None
@property
@@ -134,6 +135,13 @@ def get_prev_pcd(self) -> None:
else:
raise Exception("No point cloud left for loading!")
+ def populate_class_dropdown(self) -> None:
+ # Add point label list
+ self.view.current_class_dropdown.clear()
+ assert self.pointcloud is not None
+ for key in self.pointcloud.label_definition:
+ self.view.current_class_dropdown.addItem(key)
+
def get_labels_from_file(self) -> List[BBox]:
bboxes = self.label_manager.import_labels(self.pcd_path)
logging.info(green("Loaded %s bboxes!" % len(bboxes)))
@@ -150,8 +158,6 @@ def save_labels_into_file(self, bboxes: List[BBox]) -> None:
self.collected_object_classes.update(
{bbox.get_classname() for bbox in bboxes}
)
- self.view.update_label_completer(self.collected_object_classes)
- self.view.update_default_object_class_menu(self.collected_object_classes)
else:
logging.warning("No point clouds to save labels for!")
@@ -225,7 +231,7 @@ def rotate_pointcloud(
rotation_matrix = o3d.geometry.get_rotation_matrix_from_axis_angle(
np.multiply(axis, angle)
)
- o3d_pointcloud = Open3DHandler().to_open3d_point_cloud(self.pointcloud)
+ o3d_pointcloud = Open3DHandler.to_open3d_point_cloud(self.pointcloud)
o3d_pointcloud.rotate(rotation_matrix, center=tuple(rotation_point))
o3d_pointcloud.translate([0, 0, -rotation_point[2]])
logging.info("Rotating point cloud...")
@@ -241,8 +247,13 @@ def rotate_pointcloud(
center=(0, 0, 0),
)
+ points, colors = Open3DHandler.to_point_cloud(o3d_pointcloud)
self.pointcloud = PointCloud(
- self.pcd_path, *Open3DHandler().to_point_cloud(o3d_pointcloud)
+ self.pcd_path,
+ points,
+ self.pointcloud.label_definition,
+ colors,
+ self.pointcloud.labels,
)
self.pointcloud.to_file()
diff --git a/labelCloud/io/__init__.py b/labelCloud/io/__init__.py
index e69de29..f0dfbc2 100644
--- a/labelCloud/io/__init__.py
+++ b/labelCloud/io/__init__.py
@@ -0,0 +1,10 @@
+import json
+from pathlib import Path
+from typing import Dict
+
+
+def read_label_definition(label_definition_path: Path) -> Dict[str, int]:
+ with open(label_definition_path, "r") as f:
+ label_definition: Dict[str, int] = json.loads(f.read())
+ assert len(label_definition) > 0
+ return label_definition
diff --git a/labelCloud/io/pointclouds/open3d.py b/labelCloud/io/pointclouds/open3d.py
index eb50271..cdd13f1 100644
--- a/labelCloud/io/pointclouds/open3d.py
+++ b/labelCloud/io/pointclouds/open3d.py
@@ -3,7 +3,6 @@
import numpy as np
import numpy.typing as npt
-
import open3d as o3d
from . import BasePointCloudHandler
@@ -18,17 +17,17 @@ class Open3DHandler(BasePointCloudHandler):
def __init__(self) -> None:
super().__init__()
+ @staticmethod
def to_point_cloud(
- self, pointcloud: o3d.geometry.PointCloud
+ pointcloud: o3d.geometry.PointCloud,
) -> Tuple[npt.NDArray, Optional[npt.NDArray]]:
return (
np.asarray(pointcloud.points).astype("float32"),
np.asarray(pointcloud.colors).astype("float32"),
)
- def to_open3d_point_cloud(
- self, pointcloud: "PointCloud"
- ) -> o3d.geometry.PointCloud:
+ @staticmethod
+ def to_open3d_point_cloud(pointcloud: "PointCloud") -> o3d.geometry.PointCloud:
o3d_pointcloud = o3d.geometry.PointCloud(
o3d.utility.Vector3dVector(pointcloud.points)
)
diff --git a/labelCloud/io/segmentations/base.py b/labelCloud/io/segmentations/base.py
index 3c4cd90..c30c446 100644
--- a/labelCloud/io/segmentations/base.py
+++ b/labelCloud/io/segmentations/base.py
@@ -1,7 +1,6 @@
-import json
from abc import abstractmethod
from pathlib import Path
-from typing import Dict, Tuple, Type
+from typing import Dict, Set, Type
import numpy as np
import numpy.typing as npt
@@ -10,15 +9,10 @@
class BaseSegmentationHandler(object, metaclass=SingletonABCMeta):
- EXTENSIONS = set() # should be set in subclasses
+ EXTENSIONS: Set[str] = set() # should be set in subclasses
- def __init__(self, label_definition_path: Path) -> None:
- self.read_label_definition(label_definition_path)
-
- def read_label_definition(self, label_definition_path: Path) -> None:
- with open(label_definition_path, "r") as f:
- self.label_definition: Dict[str, int] = json.loads(f.read())
- assert len(self.label_definition) > 0
+ def __init__(self, label_definition: Dict[str, int]) -> None:
+ self.label_definition = label_definition
@property
def default_label(self) -> int:
@@ -26,7 +20,7 @@ def default_label(self) -> int:
def read_or_create_labels(
self, label_path: Path, num_points: int
- ) -> Tuple[Dict[str, int], npt.NDArray[np.int8]]:
+ ) -> npt.NDArray[np.int8]:
"""Read labels per point and its schema"""
if label_path.exists():
labels = self._read_labels(label_path)
@@ -36,7 +30,7 @@ def read_or_create_labels(
)
else:
labels = self._create_labels(num_points)
- return self.label_definition, labels
+ return labels
def overwrite_labels(self, label_path: Path, labels: npt.NDArray[np.int8]) -> None:
return self._write_labels(label_path, labels)
@@ -58,3 +52,6 @@ def get_handler(cls, file_extension: str) -> Type["BaseSegmentationHandler"]:
for subclass in cls.__subclasses__():
if file_extension in subclass.EXTENSIONS:
return subclass
+ raise NotImplementedError(
+ f"{file_extension} is not supported for segmentation labels."
+ )
diff --git a/labelCloud/io/segmentations/numpy.py b/labelCloud/io/segmentations/numpy.py
index 47d8dfd..d6f4b4f 100644
--- a/labelCloud/io/segmentations/numpy.py
+++ b/labelCloud/io/segmentations/numpy.py
@@ -12,7 +12,7 @@ class NumpySegmentationHandler(BaseSegmentationHandler):
def __init__(self, *args, **kwargs) -> None:
super().__init__(*args, **kwargs)
- def _create_labels(self, num_points: int) -> npt.NDArray[np.int8]:
+ def _create_labels(self, num_points: int, *args, **kwargs) -> npt.NDArray[np.int8]:
return np.ones(shape=(num_points,), dtype=np.int8) * self.default_label
def _read_labels(self, label_path: Path) -> npt.NDArray[np.int8]:
diff --git a/labelCloud/model/point_cloud.py b/labelCloud/model/point_cloud.py
index c8b6e28..be4793f 100644
--- a/labelCloud/model/point_cloud.py
+++ b/labelCloud/model/point_cloud.py
@@ -1,9 +1,7 @@
import ctypes
import logging
from pathlib import Path
-from typing import Dict, Optional, Tuple
-
-import pkg_resources
+from typing import Dict, Optional, Tuple, cast
import numpy as np
import numpy.typing as npt
@@ -11,6 +9,7 @@
from ..control.config_manager import config
from ..definitions.types import Point3D, Rotations3D, Translation3D
+from ..io import read_label_definition
from ..io.pointclouds import BasePointCloudHandler
from ..io.segmentations import BaseSegmentationHandler
from ..utils.color import colorize_points_with_height, get_distinct_colors
@@ -43,10 +42,10 @@ class PointCloud(object):
def __init__(
self,
path: Path,
- points: np.ndarray,
+ points: npt.NDArray[np.float32],
+ label_definition: Dict[str, int],
colors: Optional[np.ndarray] = None,
segmentation_labels: Optional[npt.NDArray[np.int8]] = None,
- label_definition: Optional[Dict[str, int]] = None,
init_translation: Optional[Tuple[float, float, float]] = None,
init_rotation: Optional[Tuple[float, float, float]] = None,
write_buffer: bool = True,
@@ -55,11 +54,11 @@ def __init__(
self.path = path
self.points = points
self.colors = colors if type(colors) == np.ndarray and len(colors) > 0 else None
+ self.label_definition = label_definition
- self.labels = self.label_definition = self.label_color_map = None
+ self.labels = self.label_color_map = None
if self.SEGMENTATION:
self.labels = segmentation_labels
- self.label_definition = label_definition
self.label_color_map = get_distinct_colors(len(label_definition))
self.mix_ratio = config.getfloat("POINTCLOUD", "label_color_mix_ratio")
@@ -95,7 +94,6 @@ def __init__(
logging.info(
"Generated colors for colorless point cloud based on `colorless_color`."
)
-
if write_buffer:
self.create_buffers()
@@ -109,6 +107,7 @@ def point_size(self) -> float:
def create_buffers(self) -> None:
"""Create 3 different buffers holding points, colors and label colors information"""
+ self.colors = cast(npt.NDArray[np.float32], self.colors)
(
self.position_vbo,
self.color_vbo,
@@ -126,9 +125,10 @@ def create_buffers(self) -> None:
@property
def label_colors(self) -> npt.NDArray[np.float32]:
"""blend the points with label color map"""
+ self.colors = cast(npt.NDArray[np.float32], self.colors)
if self.labels is not None:
label_one_hot = np.eye(len(self.label_definition))[self.labels]
- colors = np.dot(label_one_hot, self.label_color_map).astype(np.float32)
+ colors = np.dot(label_one_hot, self.label_color_map).astype(np.float32) # type: ignore
return colors * self.mix_ratio + self.colors * (1 - self.mix_ratio)
else:
return self.colors
@@ -149,30 +149,30 @@ def from_file(
path.suffix
).read_point_cloud(path=path)
- labels = label_def = None
+ label_definition = read_label_definition(
+ config.getpath("FILE", "label_folder")
+ / Path(f"schema/label_definition.json")
+ )
+ labels = None
if cls.SEGMENTATION:
label_path = config.getpath("FILE", "label_folder") / Path(
f"segmentation/{path.stem}.bin"
)
- label_defintion_path = config.getpath("FILE", "label_folder") / Path(
- f"segmentation/schema/label_definition.json"
- )
-
logging.info(f"Loading segmentation labels from {label_path}.")
seg_handler = BaseSegmentationHandler.get_handler(label_path.suffix)(
- label_definition_path=label_defintion_path
+ label_definition=label_definition
)
- label_def, labels = seg_handler.read_or_create_labels(
+ labels = seg_handler.read_or_create_labels(
label_path=label_path, num_points=points.shape[0]
)
return cls(
path,
points,
+ label_definition,
colors,
labels,
- label_def,
init_translation,
init_rotation,
write_buffer,
@@ -194,13 +194,11 @@ def color_with_label(self) -> bool:
return config.getboolean("POINTCLOUD", "color_with_label")
@property
- def int2label(self) -> Optional[Dict[int, str]]:
- if self.label_definition is not None:
- return {ind: label for label, ind in self.label_definition.items()}
- return None
+ def int2label(self) -> Dict[int, str]:
+ return {ind: label for label, ind in self.label_definition.items()}
@property
- def label_counts(self) -> Optional[Dict[int, int]]:
+ def label_counts(self) -> Optional[Dict[str, int]]:
if self.labels is not None and self.label_definition:
counter = {k: 0 for k in self.label_definition}
diff --git a/labelCloud/resources/default_config.ini b/labelCloud/resources/default_config.ini
index b7f5d4d..d5b50a4 100644
--- a/labelCloud/resources/default_config.ini
+++ b/labelCloud/resources/default_config.ini
@@ -19,8 +19,6 @@ std_zoom = 0.0025
[LABEL]
; format for exporting labels. choose from (vertices, centroid_rel, centroid_abs, kitti)
label_format = centroid_abs
-; list of object classes for autocompletion in the text field
-object_classes = cart, box
; default object class for new bounding boxes
std_object_class = cart
; number of decimal places for exporting the bounding box parameter.
diff --git a/labelCloud/resources/interfaces/interface.ui b/labelCloud/resources/interfaces/interface.ui
index c738965..7b4ecd3 100644
--- a/labelCloud/resources/interfaces/interface.ui
+++ b/labelCloud/resources/interfaces/interface.ui
@@ -893,16 +893,16 @@
- -
-
-
-
- 0
- 0
-
-
-
-
+ -
+
+
+
+ 0
+ 0
+
+
+
+
-
@@ -1685,7 +1685,7 @@
button_pick_bbox
button_span_bbox
button_save_label
- edit_current_class
+ current_class_dropdown
edit_pos_x
edit_pos_y
edit_pos_z
diff --git a/labelCloud/tests/unit/segmentation_handler/test_numpy_segmentation_handler.py b/labelCloud/tests/unit/segmentation_handler/test_numpy_segmentation_handler.py
index cf9e651..b3ca4f2 100644
--- a/labelCloud/tests/unit/segmentation_handler/test_numpy_segmentation_handler.py
+++ b/labelCloud/tests/unit/segmentation_handler/test_numpy_segmentation_handler.py
@@ -5,6 +5,7 @@
import numpy as np
import pytest
+from labelCloud.io import read_label_definition
from labelCloud.io.segmentations import NumpySegmentationHandler
@@ -16,12 +17,17 @@ def segmentation_path() -> Path:
@pytest.fixture
-def label_definition_path(segmentation_path) -> Path:
- path = segmentation_path / Path("schema/label_definition.json")
+def label_definition_path() -> Path:
+ path = Path("labels/schema/label_definition.json")
assert path.exists()
return path
+@pytest.fixture
+def label_definition(label_definition_path: Path) -> Dict[str, int]:
+ return read_label_definition(label_definition_path)
+
+
@pytest.fixture
def label_path(segmentation_path) -> Path:
path = segmentation_path / Path("exemplary.bin")
@@ -41,15 +47,15 @@ def expected_label_definition() -> Dict[str, int]:
return {
"unassigned": 0,
"person": 1,
- "car": 2,
+ "cart": 2,
"wall": 3,
"floor": 4,
}
@pytest.fixture
-def handler(label_definition_path) -> NumpySegmentationHandler:
- return NumpySegmentationHandler(label_definition_path=label_definition_path)
+def handler(label_definition) -> NumpySegmentationHandler:
+ return NumpySegmentationHandler(label_definition=label_definition)
def test_label_definition(
@@ -102,10 +108,10 @@ def test_read_or_create_labels_when_exist(
expected_label_definition: Dict[str, int],
) -> None:
with exception:
- label_definition, labels = handler.read_or_create_labels(
+ labels = handler.read_or_create_labels(
label_path=label_path, num_points=num_points
)
- assert label_definition == expected_label_definition
+ assert handler.label_definition == expected_label_definition
assert labels.dtype == np.int8
assert labels.shape == (num_points,)
@@ -115,10 +121,8 @@ def test_read_or_create_labels_when_not_exist(
not_label_path: Path,
expected_label_definition: Dict[str, int],
) -> None:
- label_definition, labels = handler.read_or_create_labels(
- label_path=not_label_path, num_points=420
- )
- assert label_definition == expected_label_definition
+ labels = handler.read_or_create_labels(label_path=not_label_path, num_points=420)
+ assert handler.label_definition == expected_label_definition
assert labels.dtype == np.int8
assert labels.shape == (420,)
assert (labels == np.zeros((420,))).all()
diff --git a/labelCloud/utils/color.py b/labelCloud/utils/color.py
index ef56b70..4507deb 100644
--- a/labelCloud/utils/color.py
+++ b/labelCloud/utils/color.py
@@ -29,7 +29,7 @@ def get_distinct_colors(n: int) -> npt.NDArray[np.float32]:
def colorize_points_with_height(
points: np.ndarray, z_min: float, z_max: float
-) -> np.ndarray:
+) -> npt.NDArray[np.float32]:
palette = np.loadtxt(
pkg_resources.resource_filename("labelCloud.resources", "rocket-palette.txt")
)
diff --git a/labelCloud/view/gui.py b/labelCloud/view/gui.py
index 17b3d59..eed01d8 100644
--- a/labelCloud/view/gui.py
+++ b/labelCloud/view/gui.py
@@ -11,7 +11,6 @@
from PyQt5.QtWidgets import (
QAction,
QActionGroup,
- QCompleter,
QFileDialog,
QInputDialog,
QLabel,
@@ -88,6 +87,9 @@ def set_keep_perspective(state: bool) -> None:
background: rgb(0, 0, 255);
background: url("{icons_dir}/cube-outline_white.svg") center left no-repeat, #0000ff;
}}
+ QComboBox#current_class_dropdown {{
+ selection-background-color: gray;
+ }}
"""
@@ -171,7 +173,7 @@ def __init__(self, control: "Controller") -> None:
# RIGHT PANEL
self.label_list: QtWidgets.QListWidget
- self.edit_current_class: QtWidgets.QLineEdit
+ self.current_class_dropdown: QtWidgets.QComboBox
self.button_deselect_label: QtWidgets.QPushButton
self.button_delete_label: QtWidgets.QPushButton
@@ -189,7 +191,6 @@ def __init__(self, control: "Controller") -> None:
self.edit_rot_z: QtWidgets.QLineEdit
self.all_line_edits = [
- self.edit_current_class,
self.edit_pos_x,
self.edit_pos_y,
self.edit_pos_z,
@@ -210,8 +211,6 @@ def __init__(self, control: "Controller") -> None:
# Connect all events to functions
self.connect_events()
self.set_checkbox_states() # tick in menu
- self.update_label_completer() # initialize label completer with classes in config
- self.update_default_object_class_menu()
# Start event cycle
self.timer = QtCore.QTimer(self)
@@ -259,7 +258,7 @@ def connect_events(self) -> None:
)
# LABELING CONTROL
- self.edit_current_class.textChanged.connect(
+ self.current_class_dropdown.currentTextChanged.connect(
self.controller.bbox_controller.set_classname
)
self.button_deselect_label.clicked.connect(
@@ -381,9 +380,9 @@ def eventFilter(self, event_object, event) -> bool:
self.controller.mouse_clicked(event)
self.update_bbox_stats(self.controller.bbox_controller.get_active_bbox())
elif (event.type() == QEvent.MouseButtonPress) and (
- event_object != self.edit_current_class
+ event_object != self.current_class_dropdown
):
- self.edit_current_class.clearFocus()
+ self.current_class_dropdown.clearFocus()
self.update_bbox_stats(self.controller.bbox_controller.get_active_bbox())
return False
@@ -456,19 +455,8 @@ def init_progress(self, min_value, max_value):
def update_progress(self, value) -> None:
self.progressbar_pcds.setValue(value)
- def update_curr_class_edit(self, force: str = None) -> None:
- if force is not None:
- self.edit_current_class.setText(force)
- else:
- bbox = self.controller.bbox_controller.get_active_bbox()
- if bbox:
- self.edit_current_class.setText(bbox.get_classname())
-
- def update_label_completer(self, classnames=None) -> None:
- if classnames is None:
- classnames = set()
- classnames.update(config.getlist("LABEL", "object_classes"))
- self.edit_current_class.setCompleter(QCompleter(classnames))
+ def update_current_class_dropdown(self) -> None:
+ self.controller.pcd_manager.populate_class_dropdown()
def update_bbox_stats(self, bbox) -> None:
viewing_precision = config.getint("USER_INTERFACE", "viewing_precision")
@@ -573,24 +561,6 @@ def change_label_folder(self) -> None:
)
logging.info("Changed label folder to %s!" % path_to_folder)
- def update_default_object_class_menu(self, new_classes: Set[str] = None) -> None:
- object_classes = {
- str(class_name) for class_name in config.getlist("LABEL", "object_classes")
- }
- object_classes.update(new_classes or [])
- existing_classes = {
- action.text() for action in self.actiongroup_default_class.actions()
- }
- for object_class in object_classes.difference(existing_classes):
- action = self.actiongroup_default_class.addAction(
- object_class
- ) # TODO: Add limiter for number of classes
- action.setCheckable(True)
- if object_class == config.get("LABEL", "std_object_class"):
- action.setChecked(True)
-
- self.act_set_default_class.addActions(self.actiongroup_default_class.actions())
-
def change_default_object_class(self, action: QAction) -> None:
config.set("LABEL", "std_object_class", action.text())
logging.info("Changed default object class to %s.", action.text())
diff --git a/labelCloud/view/settings_dialog.py b/labelCloud/view/settings_dialog.py
index 7e4c72c..083b384 100644
--- a/labelCloud/view/settings_dialog.py
+++ b/labelCloud/view/settings_dialog.py
@@ -52,9 +52,6 @@ def fill_with_current_settings(self) -> None:
LabelManager.LABEL_FORMATS
) # TODO: Fix visualization
self.comboBox_labelformat.setCurrentText(config.get("LABEL", "label_format"))
- self.plainTextEdit_objectclasses.setPlainText(
- config.get("LABEL", "object_classes")
- )
self.lineEdit_standardobjectclass.setText(
config.get("LABEL", "std_object_class")
)
@@ -124,9 +121,6 @@ def save(self) -> None:
# Label
config["LABEL"]["label_format"] = self.comboBox_labelformat.currentText()
- config["LABEL"][
- "object_classes"
- ] = self.plainTextEdit_objectclasses.toPlainText()
config["LABEL"]["std_object_class"] = self.lineEdit_standardobjectclass.text()
config["LABEL"]["export_precision"] = str(self.spinBox_exportprecision.value())
config["LABEL"]["min_boundingbox_dimension"] = str(
diff --git a/labels/segmentation/schema/label_definition.json b/labels/schema/label_definition.json
similarity index 81%
rename from labels/segmentation/schema/label_definition.json
rename to labels/schema/label_definition.json
index 1b2fe50..4b4b152 100644
--- a/labels/segmentation/schema/label_definition.json
+++ b/labels/schema/label_definition.json
@@ -1,7 +1,7 @@
{
"unassigned": 0,
"person": 1,
- "car": 2,
+ "cart": 2,
"wall": 3,
"floor": 4
-}
+}
\ No newline at end of file
diff --git a/requirements.txt b/requirements.txt
index 9a92581..54d8a4a 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -9,7 +9,7 @@ pytest~=7.1.2
pytest-qt~=4.1.0
# Development
-black~=22.1.0
+black~=22.3.0
mypy~=0.971
PyQt5-stubs~=5.15.6
types-setuptools~=57.4.17