From ae91f6e5cf01b7e34b193ab06903bb042689c6f7 Mon Sep 17 00:00:00 2001 From: Guilhem Saurel Date: Mon, 18 Dec 2023 18:41:29 +0100 Subject: [PATCH 1/4] fix type hint for py38 --- .../megapose/evaluation/eval_config.py | 6 +++--- .../megapose/inference/depth_refiner.py | 4 ++-- happypose/toolbox/datasets/object_dataset.py | 16 ++++++++-------- happypose/toolbox/lib3d/symmetries.py | 6 +++--- happypose/toolbox/lib3d/transform.py | 6 +++--- happypose/toolbox/utils/distributed.py | 8 ++++---- happypose/toolbox/utils/tensor_collection.py | 3 ++- 7 files changed, 25 insertions(+), 24 deletions(-) diff --git a/happypose/pose_estimators/megapose/evaluation/eval_config.py b/happypose/pose_estimators/megapose/evaluation/eval_config.py index 9aba8b1e..d3b4890f 100644 --- a/happypose/pose_estimators/megapose/evaluation/eval_config.py +++ b/happypose/pose_estimators/megapose/evaluation/eval_config.py @@ -16,7 +16,7 @@ # Standard Library from dataclasses import dataclass -from typing import Optional +from typing import Optional, List # MegaPose from happypose.pose_estimators.megapose.inference.types import InferenceConfig @@ -85,8 +85,8 @@ class EvalConfig: @dataclass class FullEvalConfig(EvalConfig): # Full eval - detection_coarse_types: Optional[list] = None - ds_names: Optional[list[str]] = None + detection_coarse_types: Optional[List] = None + ds_names: Optional[List[str]] = None run_bop_eval: bool = True eval_coarse_also: bool = False convert_only: bool = False diff --git a/happypose/pose_estimators/megapose/inference/depth_refiner.py b/happypose/pose_estimators/megapose/inference/depth_refiner.py index c948d32e..49034ec3 100644 --- a/happypose/pose_estimators/megapose/inference/depth_refiner.py +++ b/happypose/pose_estimators/megapose/inference/depth_refiner.py @@ -16,7 +16,7 @@ # Standard Library from abc import ABC, abstractmethod -from typing import Optional +from typing import Optional, Tuple # Third Party import torch @@ -33,7 +33,7 @@ def refine_poses( masks: Optional[torch.tensor] = None, depth: Optional[torch.tensor] = None, K: Optional[torch.tensor] = None, - ) -> tuple[PoseEstimatesType, dict]: + ) -> Tuple[PoseEstimatesType, dict]: """Run the depth refinement. Args: diff --git a/happypose/toolbox/datasets/object_dataset.py b/happypose/toolbox/datasets/object_dataset.py index ba591430..42c1241f 100644 --- a/happypose/toolbox/datasets/object_dataset.py +++ b/happypose/toolbox/datasets/object_dataset.py @@ -17,7 +17,7 @@ # Standard Library import itertools from pathlib import Path -from typing import Optional +from typing import List, Optional, Set, Tuple # Third Party import numpy as np @@ -38,9 +38,9 @@ def __init__( category: Optional[str] = None, mesh_diameter: Optional[float] = None, mesh_units: str = "m", - symmetries_discrete: list[DiscreteSymmetry] = [], - symmetries_continuous: list[ContinuousSymmetry] = [], - ypr_offset_deg: tuple[float, float, float] = (0.0, 0.0, 0.0), + symmetries_discrete: List[DiscreteSymmetry] = [], + symmetries_continuous: List[ContinuousSymmetry] = [], + ypr_offset_deg: Tuple[float, float, float] = (0.0, 0.0, 0.0), scaling_factor: float = 1.0, scaling_factor_mesh_units_to_meters: Optional[float] = None, ): @@ -147,7 +147,7 @@ def make_symmetry_poses(self, n_symmetries_continuous: int = 64) -> np.ndarray: class RigidObjectDataset: def __init__( self, - objects: list[RigidObject], + objects: List[RigidObject], ): self.list_objects = objects self.label_to_objects = {obj.label: obj for obj in objects} @@ -165,11 +165,11 @@ def __len__(self) -> int: return len(self.list_objects) @property - def objects(self) -> list[RigidObject]: + def objects(self) -> List[RigidObject]: """Returns a list of objects in this dataset.""" return self.list_objects - def filter_objects(self, keep_labels: set[str]) -> "RigidObjectDataset": + def filter_objects(self, keep_labels: Set[str]) -> "RigidObjectDataset": list_objects = [obj for obj in self.list_objects if obj.label in keep_labels] return RigidObjectDataset(list_objects) @@ -183,6 +183,6 @@ def append_dataset_name_to_object_labels( return object_dataset -def concat_object_datasets(datasets: list[RigidObjectDataset]) -> RigidObjectDataset: +def concat_object_datasets(datasets: List[RigidObjectDataset]) -> RigidObjectDataset: objects = list(itertools.chain.from_iterable([ds.list_objects for ds in datasets])) return RigidObjectDataset(objects) diff --git a/happypose/toolbox/lib3d/symmetries.py b/happypose/toolbox/lib3d/symmetries.py index 891f14ae..23b03f76 100644 --- a/happypose/toolbox/lib3d/symmetries.py +++ b/happypose/toolbox/lib3d/symmetries.py @@ -16,7 +16,7 @@ # Standard Library from dataclasses import dataclass -from typing import Optional +from typing import List, Optional # Third Party import numpy as np @@ -46,8 +46,8 @@ class DiscreteSymmetry: def make_symmetries_poses( - symmetries_discrete: list[DiscreteSymmetry] = [], - symmetries_continuous: list[ContinuousSymmetry] = [], + symmetries_discrete: List[DiscreteSymmetry] = [], + symmetries_continuous: List[ContinuousSymmetry] = [], n_symmetries_continuous: int = 8, units: str = "mm", scale: Optional[float] = None, diff --git a/happypose/toolbox/lib3d/transform.py b/happypose/toolbox/lib3d/transform.py index 048c57da..ec3fb2fc 100644 --- a/happypose/toolbox/lib3d/transform.py +++ b/happypose/toolbox/lib3d/transform.py @@ -15,7 +15,7 @@ # Standard Library -from typing import Union +from typing import Union, Tuple # Third Party import numpy as np @@ -34,9 +34,9 @@ def __init__( pin.Quaternion, np.ndarray, torch.Tensor, - tuple[float, float, float, float], + Tuple[float, float, float, float], ], # rotation - Union[np.ndarray, torch.Tensor, tuple[float, float, float]], # translation + Union[np.ndarray, torch.Tensor, Tuple[float, float, float]], # translation ], ): """- Transform(T): SE3 or (4, 4) array diff --git a/happypose/toolbox/utils/distributed.py b/happypose/toolbox/utils/distributed.py index dd8f7288..755b2c12 100644 --- a/happypose/toolbox/utils/distributed.py +++ b/happypose/toolbox/utils/distributed.py @@ -19,7 +19,7 @@ import os import sys from pathlib import Path -from typing import Any +from typing import Any, List, Dict import omegaconf @@ -46,7 +46,7 @@ def get_tmp_dir() -> Path: def sync_config( cfg: omegaconf.dictconfig.DictConfig, - local_fields: list[str] = [], + local_fields: List[str] = [], ) -> omegaconf.dictconfig.DictConfig: cfg_path = get_tmp_dir() / "config.yaml" if get_rank() == 0: @@ -104,9 +104,9 @@ def get_world_size() -> int: def reduce_dict( - input_dict: dict[str, Any], + input_dict: Dict[str, Any], average: bool = True, -) -> dict[str, Any]: +) -> Dict[str, Any]: """https://github.com/pytorch/vision/blob/master/references/detection/utils.py Args: input_dict (dict): all the values will be reduced diff --git a/happypose/toolbox/utils/tensor_collection.py b/happypose/toolbox/utils/tensor_collection.py index c1bd696f..fa9f491e 100644 --- a/happypose/toolbox/utils/tensor_collection.py +++ b/happypose/toolbox/utils/tensor_collection.py @@ -16,6 +16,7 @@ # Standard Library from pathlib import Path +from typing import List # Third Party import pandas as pd @@ -201,7 +202,7 @@ def __setstate__(self, state): def filter_top_pose_estimates( data_TCO: PandasTensorCollection, top_K: int, - group_cols: list[str], + group_cols: List[str], filter_field: str, ascending: bool = False, ) -> PandasTensorCollection: From 43f7c6997c76bb0f4013fe78de83cc2982ab42d3 Mon Sep 17 00:00:00 2001 From: Guilhem Saurel Date: Mon, 18 Dec 2023 18:41:29 +0100 Subject: [PATCH 2/4] fix type hint for py38 --- experiments/generate_dataset.py | 3 +- experiments/job-runner/job_runner/configs.py | 7 +-- experiments/job-runner/job_runner/utils.py | 5 +- experiments/make_shapenet_ids.py | 9 ++-- .../cosypose/evaluation/evaluation.py | 4 +- .../cosypose/evaluation/prediction_runner.py | 6 +-- .../cosypose/integrated/pose_estimator.py | 8 +-- .../cosypose/integrated/pose_predictor.py | 5 +- .../scripts/run_full_cosypose_eval_new.py | 5 +- .../scripts/run_inference_on_example.py | 4 +- .../megapose/evaluation/data_utils.py | 4 +- .../megapose/evaluation/evaluation.py | 4 +- .../megapose/inference/icp_refiner.py | 4 +- .../megapose/inference/pose_estimator.py | 12 ++--- .../megapose/inference/teaserpp_refiner.py | 4 +- .../megapose/models/pose_rigid.py | 49 +++++++++---------- .../pose_estimators/megapose/models/resnet.py | 14 +++--- .../megapose/models/torchvision_resnet.py | 15 +++--- .../scripts/run_full_megapose_eval.py | 5 +- .../scripts/run_inference_on_datasettemp.py | 6 +-- .../scripts/run_inference_on_example.py | 6 +-- .../run_inference_on_example_newdetections.py | 6 +-- .../megapose/scripts/run_megapose_training.py | 6 +-- .../training/megapose_forward_loss.py | 6 +-- .../megapose/training/train_megapose.py | 10 ++-- .../megapose/training/training_config.py | 10 ++-- .../megapose/training/utils.py | 2 +- happypose/toolbox/datasets/augmentations.py | 24 ++++----- happypose/toolbox/datasets/datasets_cfg.py | 6 +-- happypose/toolbox/datasets/gso_dataset.py | 3 +- happypose/toolbox/datasets/pose_dataset.py | 13 ++--- happypose/toolbox/datasets/scene_dataset.py | 28 +++++------ happypose/toolbox/datasets/utils.py | 3 +- .../toolbox/datasets/web_scene_dataset.py | 14 +++--- happypose/toolbox/inference/pose_estimator.py | 7 +-- happypose/toolbox/inference/utils.py | 12 ++--- happypose/toolbox/lib3d/camera_geometry.py | 5 +- .../toolbox/lib3d/rigid_mesh_database.py | 3 +- happypose/toolbox/lib3d/transform_ops.py | 5 +- .../renderer/panda3d_batch_renderer.py | 22 ++++----- .../renderer/panda3d_scene_renderer.py | 41 ++++++++-------- happypose/toolbox/renderer/types.py | 8 +-- happypose/toolbox/utils/conversion.py | 5 +- happypose/toolbox/utils/download.py | 3 +- happypose/toolbox/utils/types.py | 3 +- .../toolbox/visualization/bokeh_plotter.py | 10 ++-- .../toolbox/visualization/bokeh_utils.py | 4 +- happypose/toolbox/visualization/utils.py | 6 +-- 48 files changed, 230 insertions(+), 214 deletions(-) diff --git a/experiments/generate_dataset.py b/experiments/generate_dataset.py index 8b00d21e..6032a2d4 100644 --- a/experiments/generate_dataset.py +++ b/experiments/generate_dataset.py @@ -2,6 +2,7 @@ import time import typing as tp from dataclasses import dataclass +from typing import List import hydra import numpy as np @@ -15,7 +16,7 @@ @dataclass class DatasetGenerationConfig: dataset_id: str - chunk_ids: tp.Optional[list[int]] + chunk_ids: tp.Optional[List[int]] debug: bool = False verbose: bool = True overwrite: bool = False diff --git a/experiments/job-runner/job_runner/configs.py b/experiments/job-runner/job_runner/configs.py index 33b44aa3..21ab4b71 100644 --- a/experiments/job-runner/job_runner/configs.py +++ b/experiments/job-runner/job_runner/configs.py @@ -1,5 +1,6 @@ import typing as tp from dataclasses import dataclass +from typing import Dict, List from hydra.core.config_store import ConfigStore @@ -31,21 +32,21 @@ class SlurmJobConfig(JobConfig): account: str qos: str time: str - additional_parameters: tp.Optional[dict[str, tp.Any]] + additional_parameters: tp.Optional[Dict[str, tp.Any]] @dataclass class CodeSnapshotConfig: snapshot_dir: tp.Optional[str] exclude_path: tp.Optional[str] - python_packages_dir: tp.Optional[list[str]] = None + python_packages_dir: tp.Optional[List[str]] = None @dataclass class JobEnvironmentConfig: conda_env: str code_snapshot: tp.Optional[CodeSnapshotConfig] = None - env: tp.Optional[dict[str, str]] = None + env: tp.Optional[Dict[str, str]] = None @dataclass diff --git a/experiments/job-runner/job_runner/utils.py b/experiments/job-runner/job_runner/utils.py index ed2b0c53..2b24a298 100644 --- a/experiments/job-runner/job_runner/utils.py +++ b/experiments/job-runner/job_runner/utils.py @@ -1,11 +1,12 @@ import pathlib import typing as tp +from typing import List import submitit from job_runner.configs import JobEnvironmentConfig, RunnerConfig -def make_setup(cfg: JobEnvironmentConfig) -> list[str]: +def make_setup(cfg: JobEnvironmentConfig) -> List[str]: setup = [] if cfg.env: for k, v in cfg.env.items(): @@ -14,7 +15,7 @@ def make_setup(cfg: JobEnvironmentConfig) -> list[str]: def make_snapshots( - code_directories: list[pathlib.Path], + code_directories: List[pathlib.Path], output_dir: pathlib.Path, exclude: tp.Sequence[str] = (), ): diff --git a/experiments/make_shapenet_ids.py b/experiments/make_shapenet_ids.py index 14005d50..350cce71 100644 --- a/experiments/make_shapenet_ids.py +++ b/experiments/make_shapenet_ids.py @@ -4,14 +4,15 @@ import typing as tp from collections import deque from dataclasses import dataclass +from typing import Dict, List @dataclass class ShapeNetSynset: id: str name: str - parents: list[str] - children: list[str] + parents: List[str] + children: List[str] @dataclass @@ -26,7 +27,7 @@ def read_models(shapenet_dir): # TODO: This probably has issues / is poorly implemented and very slow taxonomy = json.load(open(shapenet_dir / "taxonomy.json")) - id_to_synset: dict[int, ShapeNetSynset] = {} + id_to_synset: Dict[int, ShapeNetSynset] = {} for synset in taxonomy: synset_id = synset["synsetId"] @@ -55,7 +56,7 @@ def get_names(synset_id, id_to_synset): return names models_path = shapenet_dir.glob("**/**/models/model_normalized.obj") - models: list[dict[str, tp.Union[int, str]]] = [] + models: List[Dict[str, tp.Union[int, str]]] = [] for n, model_path in enumerate(models_path): source_id = model_path.parent.parent.name synset_id = model_path.parent.parent.parent.name diff --git a/happypose/pose_estimators/cosypose/cosypose/evaluation/evaluation.py b/happypose/pose_estimators/cosypose/cosypose/evaluation/evaluation.py index f5dab43e..4e65c3e0 100644 --- a/happypose/pose_estimators/cosypose/cosypose/evaluation/evaluation.py +++ b/happypose/pose_estimators/cosypose/cosypose/evaluation/evaluation.py @@ -1,6 +1,6 @@ # Standard Library from pathlib import Path -from typing import Any, Optional +from typing import Any, Optional, Dict # Third Party import torch @@ -157,7 +157,7 @@ def get_save_dir(cfg: EvalConfig) -> Path: def run_eval( cfg: EvalConfig, save_dir: Optional[Path] = None, -) -> dict[str, Any]: +) -> Dict[str, Any]: """Run eval for a single setting on a single dataset. A single setting is a (detection_type, coarse_estimation_type) such diff --git a/happypose/pose_estimators/cosypose/cosypose/evaluation/prediction_runner.py b/happypose/pose_estimators/cosypose/cosypose/evaluation/prediction_runner.py index e1178393..33ec1f24 100644 --- a/happypose/pose_estimators/cosypose/cosypose/evaluation/prediction_runner.py +++ b/happypose/pose_estimators/cosypose/cosypose/evaluation/prediction_runner.py @@ -17,7 +17,7 @@ # Standard Library import time from collections import defaultdict -from typing import Optional +from typing import Dict, Optional # Third Party import numpy as np @@ -84,7 +84,7 @@ def run_inference_pipeline( obs_tensor: ObservationTensor, gt_detections: DetectionsType, initial_estimates: Optional[PoseEstimatesType] = None, - ) -> dict[str, PoseEstimatesType]: + ) -> Dict[str, PoseEstimatesType]: """Runs inference pipeline, extracts the results. Returns: A dict with keys @@ -160,7 +160,7 @@ def run_inference_pipeline( def get_predictions( self, pose_estimator: PoseEstimator, - ) -> dict[str, PoseEstimatesType]: + ) -> Dict[str, PoseEstimatesType]: """Runs predictions. Returns: A dict with keys diff --git a/happypose/pose_estimators/cosypose/cosypose/integrated/pose_estimator.py b/happypose/pose_estimators/cosypose/cosypose/integrated/pose_estimator.py index f2cfca6d..2e23eb70 100644 --- a/happypose/pose_estimators/cosypose/cosypose/integrated/pose_estimator.py +++ b/happypose/pose_estimators/cosypose/cosypose/integrated/pose_estimator.py @@ -1,6 +1,6 @@ import time from collections import defaultdict -from typing import Any, Optional +from typing import Any, Optional, Tuple import numpy as np import torch @@ -146,7 +146,7 @@ def run_inference_pipeline( coarse_estimates: Optional[PoseEstimatesType] = None, detection_th: float = 0.7, mask_th: float = 0.8, - ) -> tuple[PoseEstimatesType, dict]: + ) -> Tuple[PoseEstimatesType, dict]: timing_str = "" timer = SimpleTimer() timer.start() @@ -248,7 +248,7 @@ def forward_coarse_model( n_iterations: int = 5, keep_all_outputs: bool = False, cuda_timer: bool = False, - ) -> tuple[dict, dict]: + ) -> Tuple[dict, dict]: """Runs the refiner model for the specified number of iterations. Will actually use the batched_model_predictions to stay within @@ -357,7 +357,7 @@ def forward_refiner( n_iterations: int = 5, keep_all_outputs: bool = False, cuda_timer: bool = False, - ) -> tuple[dict, dict]: + ) -> Tuple[dict, dict]: """Runs the refiner model for the specified number of iterations. Will actually use the batched_model_predictions to stay within diff --git a/happypose/pose_estimators/cosypose/cosypose/integrated/pose_predictor.py b/happypose/pose_estimators/cosypose/cosypose/integrated/pose_predictor.py index 3dc06210..ae4291d7 100644 --- a/happypose/pose_estimators/cosypose/cosypose/integrated/pose_predictor.py +++ b/happypose/pose_estimators/cosypose/cosypose/integrated/pose_predictor.py @@ -1,4 +1,5 @@ from collections import defaultdict +from typing import Tuple import torch from torch.utils.data import DataLoader, TensorDataset @@ -133,7 +134,7 @@ def forward_coarse_model( K, data_TCO_init, n_coarse_iterations, - ) -> tuple[PoseEstimatesType, dict]: + ) -> Tuple[PoseEstimatesType, dict]: return self.batched_model_predictions( self.coarse_model, images, @@ -148,7 +149,7 @@ def forward_refiner( K, data_TCO, n_refiner_iterations, - ) -> tuple[dict, dict]: + ) -> Tuple[dict, dict]: return self.batched_model_predictions( self.refiner_model, images, diff --git a/happypose/pose_estimators/cosypose/cosypose/scripts/run_full_cosypose_eval_new.py b/happypose/pose_estimators/cosypose/cosypose/scripts/run_full_cosypose_eval_new.py index 265467e1..200cc613 100644 --- a/happypose/pose_estimators/cosypose/cosypose/scripts/run_full_cosypose_eval_new.py +++ b/happypose/pose_estimators/cosypose/cosypose/scripts/run_full_cosypose_eval_new.py @@ -2,6 +2,7 @@ import copy import os from pathlib import Path +from typing import Dict, Tuple # Third Party from omegaconf import OmegaConf @@ -68,7 +69,7 @@ def create_eval_cfg( detection_type: str, coarse_estimation_type: str, ds_name: str, -) -> tuple[str, EvalConfig]: +) -> Tuple[str, EvalConfig]: cfg = copy.deepcopy(cfg) cfg.inference.detection_type = detection_type @@ -107,7 +108,7 @@ def run_full_eval(cfg: FullEvalConfig) -> None: # Iterate over each dataset for ds_name in cfg.ds_names: # create the EvalConfig objects that we will call `run_eval` on - eval_configs: dict[str, EvalConfig] = {} + eval_configs: Dict[str, EvalConfig] = {} for detection_type, coarse_estimation_type in cfg.detection_coarse_types: name, cfg_ = create_eval_cfg( cfg, diff --git a/happypose/pose_estimators/cosypose/cosypose/scripts/run_inference_on_example.py b/happypose/pose_estimators/cosypose/cosypose/scripts/run_inference_on_example.py index 8e798371..1d6dcb78 100644 --- a/happypose/pose_estimators/cosypose/cosypose/scripts/run_inference_on_example.py +++ b/happypose/pose_estimators/cosypose/cosypose/scripts/run_inference_on_example.py @@ -5,7 +5,7 @@ ######################## # Add cosypose to my path -> dirty from pathlib import Path -from typing import Union +from typing import Tuple, Union # Third Party import numpy as np @@ -47,7 +47,7 @@ def load_observation( example_dir: Path, load_depth: bool = False, -) -> tuple[np.ndarray, Union[None, np.ndarray], CameraData]: +) -> Tuple[np.ndarray, Union[None, np.ndarray], CameraData]: camera_data = CameraData.from_json((example_dir / "camera_data.json").read_text()) rgb = np.array(Image.open(example_dir / "image_rgb.png"), dtype=np.uint8) diff --git a/happypose/pose_estimators/megapose/evaluation/data_utils.py b/happypose/pose_estimators/megapose/evaluation/data_utils.py index e1a149e9..259df05a 100644 --- a/happypose/pose_estimators/megapose/evaluation/data_utils.py +++ b/happypose/pose_estimators/megapose/evaluation/data_utils.py @@ -15,7 +15,7 @@ # Standard Library -from typing import Optional +from typing import List, Optional # Third Party import numpy as np @@ -30,7 +30,7 @@ def parse_obs_data( obs: SceneObservation, - object_labels: Optional[list[str]] = None, + object_labels: Optional[List[str]] = None, ) -> PandasTensorCollection: """Parses object data into PandasTensorCollection. diff --git a/happypose/pose_estimators/megapose/evaluation/evaluation.py b/happypose/pose_estimators/megapose/evaluation/evaluation.py index f13c50f4..81083957 100644 --- a/happypose/pose_estimators/megapose/evaluation/evaluation.py +++ b/happypose/pose_estimators/megapose/evaluation/evaluation.py @@ -16,7 +16,7 @@ # Standard Library from pathlib import Path -from typing import Any, Optional +from typing import Any, Dict, Optional # Third Party import torch @@ -80,7 +80,7 @@ def get_save_dir(cfg: EvalConfig) -> Path: def run_eval( cfg: EvalConfig, save_dir: Optional[Path] = None, -) -> dict[str, Any]: +) -> Dict[str, Any]: """Run eval for a single setting on a single dataset. A single setting is a (detection_type, coarse_estimation_type) such diff --git a/happypose/pose_estimators/megapose/inference/icp_refiner.py b/happypose/pose_estimators/megapose/inference/icp_refiner.py index 16dba411..5acfd528 100644 --- a/happypose/pose_estimators/megapose/inference/icp_refiner.py +++ b/happypose/pose_estimators/megapose/inference/icp_refiner.py @@ -15,7 +15,7 @@ # Standard Library -from typing import Optional +from typing import Optional, Tuple, Dict # Third Party import cv2 @@ -236,7 +236,7 @@ def refine_poses( masks: Optional[torch.tensor] = None, depth: Optional[torch.tensor] = None, K: Optional[torch.tensor] = None, - ) -> tuple[PoseEstimatesType, dict]: + ) -> Tuple[PoseEstimatesType, Dict]: """Runs icp refinement. See superclass DepthRefiner for full documentation.""" assert depth is not None assert K is not None diff --git a/happypose/pose_estimators/megapose/inference/pose_estimator.py b/happypose/pose_estimators/megapose/inference/pose_estimator.py index df0e3dcd..fe74b4d0 100644 --- a/happypose/pose_estimators/megapose/inference/pose_estimator.py +++ b/happypose/pose_estimators/megapose/inference/pose_estimator.py @@ -18,7 +18,7 @@ # Standard Library import time from collections import defaultdict -from typing import Any, Optional +from typing import Any, Optional, Tuple # Third Party import numpy as np @@ -109,7 +109,7 @@ def forward_refiner( keep_all_outputs: bool = False, cuda_timer: bool = False, **refiner_kwargs, - ) -> tuple[dict, dict]: + ) -> Tuple[dict, dict]: """Runs the refiner model for the specified number of iterations. Will actually use the batched_model_predictions to stay within @@ -225,7 +225,7 @@ def forward_scoring_model( data_TCO: PoseEstimatesType, cuda_timer: bool = False, return_debug_data: bool = False, - ) -> tuple[PoseEstimatesType, dict]: + ) -> Tuple[PoseEstimatesType, dict]: """Score the estimates using the coarse model. Adds the 'pose_score' field to data_TCO.infos @@ -330,7 +330,7 @@ def forward_coarse_model( detections: DetectionsType, cuda_timer: bool = False, return_debug_data: bool = False, - ) -> tuple[PoseEstimatesType, dict]: + ) -> Tuple[PoseEstimatesType, dict]: """Generates pose hypotheses and scores them with the coarse model. - Generates coarse hypotheses using the SO(3) grid. @@ -497,7 +497,7 @@ def run_depth_refiner( self, observation: ObservationTensor, predictions: PoseEstimatesType, - ) -> tuple[PoseEstimatesType, dict]: + ) -> Tuple[PoseEstimatesType, dict]: """Runs the depth refiner.""" assert self.depth_refiner is not None, "You must specify a depth refiner" depth = observation.depth @@ -526,7 +526,7 @@ def run_inference_pipeline( bsz_objects: Optional[int] = None, cuda_timer: Optional[bool] = False, coarse_estimates: Optional[PoseEstimatesType] = None, - ) -> tuple[PoseEstimatesType, dict]: + ) -> Tuple[PoseEstimatesType, dict]: """Runs the entire pose estimation pipeline. Performs the following steps diff --git a/happypose/pose_estimators/megapose/inference/teaserpp_refiner.py b/happypose/pose_estimators/megapose/inference/teaserpp_refiner.py index c2ecab7f..5268a724 100644 --- a/happypose/pose_estimators/megapose/inference/teaserpp_refiner.py +++ b/happypose/pose_estimators/megapose/inference/teaserpp_refiner.py @@ -16,7 +16,7 @@ # Standard Library import time -from typing import Optional +from typing import Optional, Tuple # Third Party import numpy as np @@ -199,7 +199,7 @@ def refine_poses( masks: Optional[torch.tensor] = None, depth: Optional[torch.tensor] = None, K: Optional[torch.tensor] = None, - ) -> tuple[PoseEstimatesType, dict]: + ) -> Tuple[PoseEstimatesType, dict]: """Runs Teaserpp refiner. See superclass DepthRefiner for full documentation. To generate correspondences for Teaser++ we use the following approach. diff --git a/happypose/pose_estimators/megapose/models/pose_rigid.py b/happypose/pose_estimators/megapose/models/pose_rigid.py index c06ded1f..f37de84e 100644 --- a/happypose/pose_estimators/megapose/models/pose_rigid.py +++ b/happypose/pose_estimators/megapose/models/pose_rigid.py @@ -13,12 +13,11 @@ limitations under the License. """ - # Standard Library import time from collections import defaultdict from dataclasses import dataclass -from typing import Any, Callable, Optional, Union +from typing import Any, Callable, Dict, List, Optional, Tuple, Union # Third Party import numpy as np @@ -55,7 +54,7 @@ class PosePredictorOutputCosypose: TCO_input: torch.Tensor renders: torch.Tensor images_crop: torch.Tensor - labels: list[str] + labels: List[str] K: torch.Tensor K_crop: torch.Tensor boxes_rend: torch.Tensor @@ -71,14 +70,14 @@ class PosePredictorOutput: TCV_O_input: torch.Tensor KV_crop: torch.Tensor tCR: torch.Tensor - labels: list[str] + labels: List[str] K: torch.Tensor K_crop: torch.Tensor - network_outputs: dict[str, torch.Tensor] + network_outputs: Dict[str, torch.Tensor] boxes_rend: torch.Tensor boxes_crop: torch.Tensor renderings_logits: torch.Tensor - timing_dict: dict[str, float] + timing_dict: Dict[str, float] @dataclass @@ -132,7 +131,7 @@ def __init__( assert isinstance(n_features, int) # TODO: Change to torch ModuleDict - self.heads: dict[str, Union[torch.nn.Linear, Callable]] = {} + self.heads: Dict[str, Union[torch.nn.Linear, Callable]] = {} self.predict_pose_update = predict_pose_update if self.predict_pose_update: self._pose_dim = 9 @@ -177,23 +176,23 @@ def __init__( ) self.debug = False - self.timing_dict: dict[str, float] = defaultdict(float) + self.timing_dict: Dict[str, float] = defaultdict(float) self.debug_data = PosePredictorDebugData() @property - def input_rgb_dims(self) -> list[int]: + def input_rgb_dims(self) -> List[int]: return self._input_rgb_dims @property - def input_depth_dims(self) -> list[int]: + def input_depth_dims(self) -> List[int]: return self._input_depth_dims @property - def render_rgb_dims(self) -> list[int]: + def render_rgb_dims(self) -> List[int]: return self._render_rgb_dims @property - def render_depth_dims(self) -> list[int]: + def render_depth_dims(self) -> List[int]: return self._render_depth_dims def crop_inputs( @@ -202,8 +201,8 @@ def crop_inputs( K: torch.Tensor, TCO: torch.Tensor, tCR: torch.Tensor, - labels: list[str], - ) -> tuple[torch.Tensor, torch.Tensor, torch.Tensor, torch.Tensor]: + labels: List[str], + ) -> Tuple[torch.Tensor, torch.Tensor, torch.Tensor, torch.Tensor]: """Crop input images. The image is cropped using the reprojection of the object points in the input @@ -282,7 +281,7 @@ def compute_crops_multiview( K: torch.Tensor, TCV_O: torch.Tensor, tCR: torch.Tensor, - labels: list[str], + labels: List[str], ) -> torch.Tensor: """Computes the intrinsics of the fictive camera used to render the additional viewpoints. @@ -349,7 +348,7 @@ def update_pose( TCO_updated = pose_update_with_reference_point(TCO, K_crop, vxvyvz, dR, tCR) return TCO_updated - def net_forward(self, x: torch.Tensor) -> dict[str, torch.Tensor]: + def net_forward(self, x: torch.Tensor) -> Dict[str, torch.Tensor]: """Forward pass of the neural network. Args: @@ -375,7 +374,7 @@ def net_forward(self, x: torch.Tensor) -> dict[str, torch.Tensor]: def render_images_multiview( self, - labels: list[str], + labels: List[str], TCV_O: torch.Tensor, KV: torch.Tensor, random_ambient_light: bool = False, @@ -384,7 +383,7 @@ def render_images_multiview( Args: ---- - labels: list[str] with length bsz + labels: List[str] with length bsz TCV_O: [bsz, n_views, 4, 4] pose of the cameras defining each view KV: [bsz, n_views, 4, 4] intrinsics of the associated cameras random_ambient_light: Whether to use randomize ambient light parameter. @@ -461,7 +460,7 @@ def normalize_images( tCR: torch.Tensor, images_inplace: bool = False, renders_inplace: bool = False, - ) -> tuple[torch.Tensor, torch.Tensor]: + ) -> Tuple[torch.Tensor, torch.Tensor]: """Normalize the depth images by the distance from the camera. If we are using depth then this involves inplace ops so to be @@ -549,12 +548,12 @@ def forward( self, images: torch.Tensor, K: torch.Tensor, - labels: list[str], + labels: List[str], TCO: torch.Tensor, n_iterations: int = 1, random_ambient_light: bool = False, - ) -> dict[str, PosePredictorOutput]: - timing_dict: dict[str, float] = defaultdict(float) + ) -> Dict[str, PosePredictorOutput]: + timing_dict: Dict[str, float] = defaultdict(float) if not self.input_depth: # Remove the depth dimension if it is not used @@ -679,7 +678,7 @@ def forward_coarse_tensor( self, x: torch.Tensor, cuda_timer: bool = False, - ) -> dict[str, Union[torch.Tensor, float]]: + ) -> Dict[str, Union[torch.Tensor, float]]: """Forward pass on coarse model given an input tensor. The input already contains the concatenated input + rendered images and has @@ -711,11 +710,11 @@ def forward_coarse( self, images: torch.Tensor, K: torch.Tensor, - labels: list[str], + labels: List[str], TCO_input: torch.Tensor, cuda_timer: bool = False, return_debug_data: bool = False, - ) -> dict[str, Any]: + ) -> Dict[str, Any]: # TODO: Is this still necessary ? """Run the coarse model given images + poses. diff --git a/happypose/pose_estimators/megapose/models/resnet.py b/happypose/pose_estimators/megapose/models/resnet.py index e3a2e8b6..27bab762 100644 --- a/happypose/pose_estimators/megapose/models/resnet.py +++ b/happypose/pose_estimators/megapose/models/resnet.py @@ -21,7 +21,7 @@ from torch.utils.model_zoo import load_url as load_state_dict_from_url # Standard Library -from typing import Any, Callable, Optional, Union +from typing import Any, Callable, List, Optional, Union # Third Party import torch.nn as nn @@ -183,14 +183,14 @@ def forward(self, x: Tensor) -> Tensor: class ResNet(nn.Module): def __init__( self, - block: type[Union[BasicBlock, Bottleneck]], - layers: list[int], + block: Union[BasicBlock, Bottleneck], + layers: List[int], num_classes: int = 1000, zero_init_residual: bool = False, groups: int = 1, width_per_group: int = 64, n_inputs: int = 3, - replace_stride_with_dilation: Optional[list[bool]] = None, + replace_stride_with_dilation: Optional[List[bool]] = None, norm_layer: Optional[Callable[..., nn.Module]] = None, ) -> None: super().__init__() @@ -266,7 +266,7 @@ def __init__( def _make_layer( self, - block: type[Union[BasicBlock, Bottleneck]], + block: Union[BasicBlock, Bottleneck], planes: int, blocks: int, stride: int = 1, @@ -331,8 +331,8 @@ def forward(self, x: Tensor) -> Tensor: def _resnet( arch: str, - block: type[Union[BasicBlock, Bottleneck]], - layers: list[int], + block: Union[BasicBlock, Bottleneck], + layers: List[int], pretrained: bool, progress: bool, **kwargs: Any, diff --git a/happypose/pose_estimators/megapose/models/torchvision_resnet.py b/happypose/pose_estimators/megapose/models/torchvision_resnet.py index 92c88486..4e86af49 100644 --- a/happypose/pose_estimators/megapose/models/torchvision_resnet.py +++ b/happypose/pose_estimators/megapose/models/torchvision_resnet.py @@ -13,9 +13,8 @@ limitations under the License. """ - # Standard Library -from typing import Any, Callable, Optional, Union +from typing import Any, Callable, List, Optional, Union # Third Party import torch @@ -192,13 +191,13 @@ def forward(self, x: Tensor) -> Tensor: class ResNet(nn.Module): def __init__( self, - block: type[Union[BasicBlock, Bottleneck]], - layers: list[int], + block: Union[BasicBlock, Bottleneck], + layers: List[int], num_classes: int = 1000, zero_init_residual: bool = False, groups: int = 1, width_per_group: int = 64, - replace_stride_with_dilation: Optional[list[bool]] = None, + replace_stride_with_dilation: Optional[List[bool]] = None, norm_layer: Optional[Callable[..., nn.Module]] = None, n_input_channels: int = 3, ) -> None: @@ -277,7 +276,7 @@ def __init__( def _make_layer( self, - block: type[Union[BasicBlock, Bottleneck]], + block: Union[BasicBlock, Bottleneck], planes: int, blocks: int, stride: int = 1, @@ -347,8 +346,8 @@ def forward(self, x: Tensor) -> Tensor: def _resnet( arch: str, - block: type[Union[BasicBlock, Bottleneck]], - layers: list[int], + block: Union[BasicBlock, Bottleneck], + layers: List[int], pretrained: bool, progress: bool, **kwargs: Any, diff --git a/happypose/pose_estimators/megapose/scripts/run_full_megapose_eval.py b/happypose/pose_estimators/megapose/scripts/run_full_megapose_eval.py index 7081c0ad..4863518d 100644 --- a/happypose/pose_estimators/megapose/scripts/run_full_megapose_eval.py +++ b/happypose/pose_estimators/megapose/scripts/run_full_megapose_eval.py @@ -18,6 +18,7 @@ import copy import os from pathlib import Path +from typing import Dict, Tuple # Third Party from omegaconf import OmegaConf @@ -72,7 +73,7 @@ def create_eval_cfg( detection_type: str, coarse_estimation_type: str, ds_name: str, -) -> tuple[str, EvalConfig]: +) -> Tuple[str, EvalConfig]: cfg = copy.deepcopy(cfg) cfg.inference.detection_type = detection_type @@ -113,7 +114,7 @@ def run_full_eval(cfg: FullEvalConfig) -> None: # Iterate over each dataset for ds_name in cfg.ds_names: # create the EvalConfig objects that we will call `run_eval` on - eval_configs: dict[str, EvalConfig] = {} + eval_configs: Dict[str, EvalConfig] = {} for detection_type, coarse_estimation_type in cfg.detection_coarse_types: name, cfg_ = create_eval_cfg( cfg, diff --git a/happypose/pose_estimators/megapose/scripts/run_inference_on_datasettemp.py b/happypose/pose_estimators/megapose/scripts/run_inference_on_datasettemp.py index 317b4f29..a2e504d1 100644 --- a/happypose/pose_estimators/megapose/scripts/run_inference_on_datasettemp.py +++ b/happypose/pose_estimators/megapose/scripts/run_inference_on_datasettemp.py @@ -3,7 +3,7 @@ import json import os from pathlib import Path -from typing import Union +from typing import List, Tuple, Union # Third Party import numpy as np @@ -45,7 +45,7 @@ def load_observation( scene_id: str, image_id: str, load_depth: bool = False, -) -> tuple[np.ndarray, Union[None, np.ndarray], CameraData]: +) -> Tuple[np.ndarray, Union[None, np.ndarray], CameraData]: camera_data_json = json.loads((dataset_dir / "scene_camera.json").read_text()) camera_data = CameraData( K=np.array(camera_data_json[str(image_id)]["cam_K"]).reshape(3, 3), @@ -88,7 +88,7 @@ def load_observation_tensor( return observation -def load_object_data(data_path: Path) -> list[ObjectData]: +def load_object_data(data_path: Path) -> List[ObjectData]: object_data = json.loads(data_path.read_text()) for object in object_data: object["bbox_modal"] = object["bbox"] diff --git a/happypose/pose_estimators/megapose/scripts/run_inference_on_example.py b/happypose/pose_estimators/megapose/scripts/run_inference_on_example.py index 6cfeb8c3..e5eb9c05 100644 --- a/happypose/pose_estimators/megapose/scripts/run_inference_on_example.py +++ b/happypose/pose_estimators/megapose/scripts/run_inference_on_example.py @@ -3,7 +3,7 @@ import json import os from pathlib import Path -from typing import Union +from typing import List, Tuple, Union # Third Party import numpy as np @@ -43,7 +43,7 @@ def load_observation( example_dir: Path, load_depth: bool = False, -) -> tuple[np.ndarray, Union[None, np.ndarray], CameraData]: +) -> Tuple[np.ndarray, Union[None, np.ndarray], CameraData]: camera_data = CameraData.from_json((example_dir / "camera_data.json").read_text()) rgb = np.array(Image.open(example_dir / "image_rgb.png"), dtype=np.uint8) @@ -69,7 +69,7 @@ def load_observation_tensor( return observation -def load_object_data(data_path: Path) -> list[ObjectData]: +def load_object_data(data_path: Path) -> List[ObjectData]: object_data = json.loads(data_path.read_text()) object_data = [ObjectData.from_json(d) for d in object_data] return object_data diff --git a/happypose/pose_estimators/megapose/scripts/run_inference_on_example_newdetections.py b/happypose/pose_estimators/megapose/scripts/run_inference_on_example_newdetections.py index 6cfeb8c3..e5eb9c05 100644 --- a/happypose/pose_estimators/megapose/scripts/run_inference_on_example_newdetections.py +++ b/happypose/pose_estimators/megapose/scripts/run_inference_on_example_newdetections.py @@ -3,7 +3,7 @@ import json import os from pathlib import Path -from typing import Union +from typing import List, Tuple, Union # Third Party import numpy as np @@ -43,7 +43,7 @@ def load_observation( example_dir: Path, load_depth: bool = False, -) -> tuple[np.ndarray, Union[None, np.ndarray], CameraData]: +) -> Tuple[np.ndarray, Union[None, np.ndarray], CameraData]: camera_data = CameraData.from_json((example_dir / "camera_data.json").read_text()) rgb = np.array(Image.open(example_dir / "image_rgb.png"), dtype=np.uint8) @@ -69,7 +69,7 @@ def load_observation_tensor( return observation -def load_object_data(data_path: Path) -> list[ObjectData]: +def load_object_data(data_path: Path) -> List[ObjectData]: object_data = json.loads(data_path.read_text()) object_data = [ObjectData.from_json(d) for d in object_data] return object_data diff --git a/happypose/pose_estimators/megapose/scripts/run_megapose_training.py b/happypose/pose_estimators/megapose/scripts/run_megapose_training.py index 2a4ca03f..4ca5b2d4 100644 --- a/happypose/pose_estimators/megapose/scripts/run_megapose_training.py +++ b/happypose/pose_estimators/megapose/scripts/run_megapose_training.py @@ -38,7 +38,7 @@ # Standard Library import os -from typing import Optional +from typing import List, Optional # Third Party import numpy as np @@ -84,7 +84,7 @@ def train_on_bop_pbr_datasets( def train_on_shapenet( cfg: TrainingConfig, ds_name: str = "shapenet_1M", - obj_filters: list[str] = [ + obj_filters: List[str] = [ "10mb_20k", ], remove_modelnet: bool = False, @@ -164,7 +164,7 @@ def update_cfg_with_config_id(cfg: TrainingConfig, config_id: str) -> TrainingCo def train_on_gso_and_shapenet( cfg: TrainingConfig, shapenet_obj_ds_name: Optional[str] = "shapenet_1M", - shapenet_obj_filters: list[str] = ["10mb_20k"], + shapenet_obj_filters: List[str] = ["10mb_20k"], gso_obj_ds_name: Optional[str] = "gso_1M", gso_n_objects: int = 940, remove_modelnet: bool = False, diff --git a/happypose/pose_estimators/megapose/training/megapose_forward_loss.py b/happypose/pose_estimators/megapose/training/megapose_forward_loss.py index 2b3548ff..e965071c 100644 --- a/happypose/pose_estimators/megapose/training/megapose_forward_loss.py +++ b/happypose/pose_estimators/megapose/training/megapose_forward_loss.py @@ -15,7 +15,7 @@ # Standard Library -from typing import Any +from typing import Any, Dict # Third Party import numpy as np @@ -48,10 +48,10 @@ def megapose_forward_loss( model: PosePredictor, cfg: TrainingConfig, data: BatchPoseData, - meters: dict[str, torchnet.meter.AverageValueMeter], + meters: Dict[str, torchnet.meter.AverageValueMeter], mesh_db: BatchedMeshes, n_iterations: int, - debug_dict: dict[str, Any], + debug_dict: Dict[str, Any], make_visualization: bool = False, train: bool = True, is_notebook: bool = False, diff --git a/happypose/pose_estimators/megapose/training/train_megapose.py b/happypose/pose_estimators/megapose/training/train_megapose.py index 72fe673c..fe3fcaca 100644 --- a/happypose/pose_estimators/megapose/training/train_megapose.py +++ b/happypose/pose_estimators/megapose/training/train_megapose.py @@ -19,7 +19,7 @@ import os import time from collections import defaultdict -from typing import Any +from typing import Any, Dict, List # Third Party import numpy as np @@ -156,7 +156,7 @@ def split_objects_across_gpus( # Scene dataset def make_iterable_scene_dataset( - dataset_configs: list[DatasetConfig], + dataset_configs: List[DatasetConfig], deterministic: bool = False, ) -> IterableMultiSceneDataset: scene_dataset_iterators = [] @@ -299,10 +299,10 @@ def make_iterable_scene_dataset( scaler = torch.cuda.amp.GradScaler() for epoch in range(start_epoch, cfg.n_epochs + 1): - meters_train: dict[str, AverageValueMeter] = defaultdict( + meters_train: Dict[str, AverageValueMeter] = defaultdict( lambda: AverageValueMeter(), ) - meters_val: dict[str, AverageValueMeter] = defaultdict( + meters_val: Dict[str, AverageValueMeter] = defaultdict( lambda: AverageValueMeter(), ) @@ -339,7 +339,7 @@ def train() -> None: optimizer.zero_grad() - debug_dict: dict[str, Any] = {} + debug_dict: Dict[str, Any] = {} timer_forward = CudaTimer(enabled=cfg.cuda_timing) timer_forward.start() with torch.cuda.amp.autocast(): diff --git a/happypose/pose_estimators/megapose/training/training_config.py b/happypose/pose_estimators/megapose/training/training_config.py index ddc7d9bf..f15f3185 100644 --- a/happypose/pose_estimators/megapose/training/training_config.py +++ b/happypose/pose_estimators/megapose/training/training_config.py @@ -15,7 +15,7 @@ # Standard Library from dataclasses import dataclass, field -from typing import Optional +from typing import Optional, List, Tuple # Third Party import numpy as np @@ -53,9 +53,9 @@ class TrainingConfig(omegaconf.dictconfig.DictConfig): """ # Datasets - train_datasets: list[DatasetConfig] = field(default_factory=lambda: []) + train_datasets: List[DatasetConfig] = field(default_factory=lambda: []) input_resize: Resolution = (540, 720) - val_datasets: list[DatasetConfig] = field(default_factory=lambda: []) + val_datasets: List[DatasetConfig] = field(default_factory=lambda: []) val_epoch_interval: int = 10 split_objects_across_gpus: bool = True n_max_objects: Optional[int] = None @@ -106,8 +106,8 @@ class TrainingConfig(omegaconf.dictconfig.DictConfig): # Hypotheses hypotheses_init_method: str = "refiner_gt+noise" n_hypotheses: int = 1 - init_euler_deg_std: tuple[float, float, float] = (15, 15, 15) - init_trans_std: tuple[float, float, float] = (0.01, 0.01, 0.05) + init_euler_deg_std: Tuple[float, float, float] = (15, 15, 15) + init_trans_std: Tuple[float, float, float] = (0.01, 0.01, 0.05) # Optimizer optimizer: str = "adam" diff --git a/happypose/pose_estimators/megapose/training/utils.py b/happypose/pose_estimators/megapose/training/utils.py index 68753d56..8e8afb89 100644 --- a/happypose/pose_estimators/megapose/training/utils.py +++ b/happypose/pose_estimators/megapose/training/utils.py @@ -115,7 +115,7 @@ def cast_raw_numpy_images_to_tensor(images): def make_optimizer( - parameters: Iterator[torch.nn.Parameter], + parameters, # : Iterator[torch.nn.Parameter], cfg: TrainingConfig, ) -> torch.optim.Optimizer: optimizer: Optional[torch.optim.Optimizer] = None diff --git a/happypose/toolbox/datasets/augmentations.py b/happypose/toolbox/datasets/augmentations.py index bb5fcbe5..d4e35781 100644 --- a/happypose/toolbox/datasets/augmentations.py +++ b/happypose/toolbox/datasets/augmentations.py @@ -19,7 +19,7 @@ import random from copy import deepcopy from pathlib import Path -from typing import Union +from typing import Dict, Union, List, Tuple # Third Party import cv2 @@ -47,7 +47,7 @@ def __init__( self, transform: Union[ SceneObservationTransform, - list["SceneObservationAugmentation"], + List["SceneObservationAugmentation"], ], p: float = 1.0, ): @@ -69,7 +69,7 @@ class PillowRGBTransform(SceneObservationTransform): def __init__( self, pillow_fn: PIL.ImageEnhance._Enhance, - factor_interval: tuple[float, float], + factor_interval: Tuple[float, float], ): self.pillow_fn = pillow_fn self.factor_interval = factor_interval @@ -84,7 +84,7 @@ def __call__(self, obs: SceneObservation) -> SceneObservation: class PillowSharpness(PillowRGBTransform): - def __init__(self, factor_interval: tuple[float, float] = (0.0, 50.0)): + def __init__(self, factor_interval: Tuple[float, float] = (0.0, 50.0)): super().__init__( pillow_fn=ImageEnhance.Sharpness, factor_interval=factor_interval, @@ -92,7 +92,7 @@ def __init__(self, factor_interval: tuple[float, float] = (0.0, 50.0)): class PillowContrast(PillowRGBTransform): - def __init__(self, factor_interval: tuple[float, float] = (0.2, 50.0)): + def __init__(self, factor_interval: Tuple[float, float] = (0.2, 50.0)): super().__init__( pillow_fn=ImageEnhance.Contrast, factor_interval=factor_interval, @@ -100,7 +100,7 @@ def __init__(self, factor_interval: tuple[float, float] = (0.2, 50.0)): class PillowBrightness(PillowRGBTransform): - def __init__(self, factor_interval: tuple[float, float] = (0.1, 6.0)): + def __init__(self, factor_interval: Tuple[float, float] = (0.1, 6.0)): super().__init__( pillow_fn=ImageEnhance.Brightness, factor_interval=factor_interval, @@ -108,12 +108,12 @@ def __init__(self, factor_interval: tuple[float, float] = (0.1, 6.0)): class PillowColor(PillowRGBTransform): - def __init__(self, factor_interval: tuple[float, float] = (0, 20.0)): + def __init__(self, factor_interval: Tuple[float, float] = (0, 20.0)): super().__init__(pillow_fn=ImageEnhance.Color, factor_interval=factor_interval) class PillowBlur(SceneObservationTransform): - def __init__(self, factor_interval: tuple[int, int] = (1, 3)): + def __init__(self, factor_interval: Tuple[int, int] = (1, 3)): self.factor_interval = factor_interval def __call__(self, obs: SceneObservation) -> SceneObservation: @@ -234,8 +234,8 @@ def __init__( @staticmethod def generate_random_ellipses( depth_img: np.ndarray, - noise_params: dict[str, float], - ) -> tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]: + noise_params: Dict[str, float], + ) -> Tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]: # Sample number of ellipses to dropout num_ellipses_to_dropout = np.random.poisson( noise_params["ellipse_dropout_mean"], @@ -270,7 +270,7 @@ def generate_random_ellipses( @staticmethod def dropout_random_ellipses( depth_img: np.ndarray, - noise_params: dict[str, float], + noise_params: Dict[str, float], ) -> np.ndarray: """Randomly drop a few ellipses in the image for robustness. @@ -385,7 +385,7 @@ def _transform_depth(self, depth: np.ndarray) -> np.ndarray: class DepthBlurTransform(DepthTransform): - def __init__(self, factor_interval: tuple[int, int] = (3, 7)): + def __init__(self, factor_interval: Tuple[int, int] = (3, 7)): self.factor_interval = factor_interval def _transform_depth(self, depth: np.ndarray) -> np.ndarray: diff --git a/happypose/toolbox/datasets/datasets_cfg.py b/happypose/toolbox/datasets/datasets_cfg.py index 452323aa..fb6566ab 100644 --- a/happypose/toolbox/datasets/datasets_cfg.py +++ b/happypose/toolbox/datasets/datasets_cfg.py @@ -16,7 +16,7 @@ # Standard Library import json -from typing import Optional +from typing import List, Optional, Tuple # Third Party import numpy as np @@ -376,7 +376,7 @@ def make_object_dataset(ds_name: str) -> RigidObjectDataset: elif ds_name.startswith("shapenet."): ds_name = ds_name[len("shapenet.") :] - filters_list: list[str] = [] + filters_list: List[str] = [] if ds_name.startswith("filters="): filter_str = ds_name.split(".")[0] filters_list = filter_str.split("filters=")[1].split(",") @@ -494,7 +494,7 @@ def make_urdf_dataset(ds_name: str) -> RigidObjectDataset: return ds -def get_obj_ds_info(ds_name: str) -> tuple[Optional[str], str]: +def get_obj_ds_info(ds_name: str) -> Tuple[Optional[str], str]: urdf_ds_name = None # Only used for bullet compatibility if ds_name == "ycbv.bop19": ds_name = "ycbv" diff --git a/happypose/toolbox/datasets/gso_dataset.py b/happypose/toolbox/datasets/gso_dataset.py index 0a8ede67..06d7a79b 100644 --- a/happypose/toolbox/datasets/gso_dataset.py +++ b/happypose/toolbox/datasets/gso_dataset.py @@ -17,6 +17,7 @@ # Standard Library import json from pathlib import Path +from typing import List # MegaPose from happypose.pose_estimators.megapose.config import MEMORY @@ -26,7 +27,7 @@ @MEMORY.cache -def make_gso_infos(gso_dir: Path, model_name: str = "model.obj") -> list[str]: +def make_gso_infos(gso_dir: Path, model_name: str = "model.obj") -> List[str]: gso_dir = Path(gso_dir) models_dir = gso_dir.iterdir() invalid_ids = set(json.loads((gso_dir.parent / "invalid_meshes.json").read_text())) diff --git a/happypose/toolbox/datasets/pose_dataset.py b/happypose/toolbox/datasets/pose_dataset.py index 1b330565..d71cea76 100644 --- a/happypose/toolbox/datasets/pose_dataset.py +++ b/happypose/toolbox/datasets/pose_dataset.py @@ -19,7 +19,7 @@ import time from collections.abc import Iterator from dataclasses import dataclass -from typing import Optional, Union +from typing import List, Optional, Union, Set # Third Party import numpy as np @@ -86,7 +86,7 @@ class BatchPoseData: """ rgbs: torch.Tensor - object_datas: list[ObjectData] + object_datas: List[ObjectData] bboxes: torch.Tensor TCO: torch.Tensor K: torch.Tensor @@ -119,7 +119,7 @@ def __init__( apply_depth_augmentation: bool = False, apply_background_augmentation: bool = False, return_first_object: bool = False, - keep_labels_set: Optional[set[str]] = None, + keep_labels_set: Optional[Set[str]] = None, depth_augmentation_level: int = 1, ): self.scene_ds = scene_ds @@ -224,7 +224,7 @@ def __init__( if keep_labels_set is not None: self.keep_labels_set = keep_labels_set - def collate_fn(self, list_data: list[PoseData]) -> BatchPoseData: + def collate_fn(self, list_data: List[PoseData]) -> BatchPoseData: batch_data = BatchPoseData( rgbs=torch.from_numpy(np.stack([d.rgb for d in list_data])).permute( 0, @@ -338,7 +338,8 @@ def __getitem__(self, index: int) -> Union[PoseData, None]: obs = self.scene_ds[index] return self.make_data_from_obs(obs) - def find_valid_data(self, iterator: Iterator[SceneObservation]) -> PoseData: + # def find_valid_data(self, iterator: Iterator[SceneObservation]) -> PoseData: + def find_valid_data(self, iterator) -> PoseData: n_attempts = 0 while True: obs = next(iterator) @@ -350,7 +351,7 @@ def find_valid_data(self, iterator: Iterator[SceneObservation]) -> PoseData: msg = "Cannot find valid image in the dataset" raise ValueError(msg) - def __iter__(self) -> Iterator[PoseData]: + def __iter__(self): # -> Iterator[PoseData]: assert isinstance(self.scene_ds, IterableSceneDataset) iterator = iter(self.scene_ds) while True: diff --git a/happypose/toolbox/datasets/scene_dataset.py b/happypose/toolbox/datasets/scene_dataset.py index a218477c..469d123f 100644 --- a/happypose/toolbox/datasets/scene_dataset.py +++ b/happypose/toolbox/datasets/scene_dataset.py @@ -23,7 +23,7 @@ import time from collections.abc import Iterator from dataclasses import dataclass -from typing import Any, Optional, Union +from typing import Any, Dict, List, Optional, Union # Third Party import numpy as np @@ -38,8 +38,8 @@ from happypose.toolbox.utils.tensor_collection import PandasTensorCollection from happypose.toolbox.utils.types import Resolution -ListBbox = list[int] -ListPose = list[list[float]] +ListBbox = List[int] +ListPose = List[List[float]] """ infos: pd.DataFrame with fields @@ -61,7 +61,7 @@ SceneObservationTensorCollection = PandasTensorCollection SingleDataJsonType = Union[str, float, ListPose, int, ListBbox, Any] -DataJsonType = Union[dict[str, SingleDataJsonType], list[SingleDataJsonType]] +DataJsonType = Union[Dict[str, SingleDataJsonType], List[SingleDataJsonType]] def transform_to_list(T: Transform) -> ListPose: @@ -82,8 +82,8 @@ class ObjectData: # Some pose estimation datasets (ModelNet) provide an initial pose estimate # NOTE: This should be loaded externally - def to_json(self) -> dict[str, SingleDataJsonType]: - d: dict[str, SingleDataJsonType] = {"label": self.label} + def to_json(self) -> Dict[str, SingleDataJsonType]: + d: Dict[str, SingleDataJsonType] = {"label": self.label} for k in ("TWO", "TWO_init"): if getattr(self, k) is not None: d[k] = transform_to_list(getattr(self, k)) @@ -131,7 +131,7 @@ class CameraData: # NOTE: This should be loaded externally def to_json(self) -> str: - d: dict[str, SingleDataJsonType] = {} + d: Dict[str, SingleDataJsonType] = {} for k in ("TWC", "TWC_init"): if getattr(self, k) is not None: d[k] = transform_to_list(getattr(self, k)) @@ -197,16 +197,16 @@ class SceneObservation: # contains objects unique ids. int64 are not handled and can be dangerous when used # with PIL infos: Optional[ObservationInfos] = None - object_datas: Optional[list[ObjectData]] = None + object_datas: Optional[List[ObjectData]] = None camera_data: Optional[CameraData] = None # dict mapping unique id to (h, w) np.bool_ - binary_masks: Optional[dict[int, np.ndarray]] = None + binary_masks: Optional[Dict[int, np.ndarray]] = None @staticmethod def collate_fn( - batch: list[SceneObservation], - object_labels: Optional[list[str]] = None, - ) -> dict[Any, Any]: + batch: List[SceneObservation], + object_labels: Optional[List[str]] = None, + ) -> Dict[Any, Any]: """Collate a batch of SceneObservation objects. Args: @@ -302,7 +302,7 @@ def collate_fn( def as_pandas_tensor_collection( self, - object_labels: Optional[list[str]] = None, + object_labels: Optional[List[str]] = None, ) -> SceneObservationTensorCollection: """Convert SceneData to a PandasTensorCollection representation.""" obs = self @@ -475,7 +475,7 @@ def __iter__(self) -> Iterator[SceneObservation]: class IterableMultiSceneDataset(IterableSceneDataset): def __init__( self, - list_iterable_scene_ds: list[IterableSceneDataset], + list_iterable_scene_ds: List[IterableSceneDataset], deterministic: bool = False, ): self.list_iterable_scene_ds = list_iterable_scene_ds diff --git a/happypose/toolbox/datasets/utils.py b/happypose/toolbox/datasets/utils.py index 4e671bfa..fd64288e 100644 --- a/happypose/toolbox/datasets/utils.py +++ b/happypose/toolbox/datasets/utils.py @@ -15,6 +15,7 @@ # Standard Library +from typing import List, Dict # Third Party import numpy as np @@ -22,7 +23,7 @@ def make_detections_from_segmentation( segmentations: np.ndarray, -) -> list[dict[int, np.ndarray]]: +) -> List[Dict[int, np.ndarray]]: """segmentations: (n, h, w) int np.ndarray.""" assert segmentations.ndim == 3 detections = [] diff --git a/happypose/toolbox/datasets/web_scene_dataset.py b/happypose/toolbox/datasets/web_scene_dataset.py index 01e6dff9..0d14b23c 100644 --- a/happypose/toolbox/datasets/web_scene_dataset.py +++ b/happypose/toolbox/datasets/web_scene_dataset.py @@ -22,7 +22,7 @@ from functools import partial from hashlib import sha1 from pathlib import Path -from typing import Any, Optional, Union +from typing import Any, Dict, List, Optional, Set, Union # Third Party import imageio @@ -59,9 +59,9 @@ def write_scene_ds_as_wds( n_reading_workers: int = 8, maxcount: int = 1000, shard_format: str = "shard-%08d.tar", - keep_labels_set: Optional[set] = None, + keep_labels_set: Optional[Set] = None, n_max_frames: Optional[int] = None, - frame_ids: Optional[list[int]] = None, + frame_ids: Optional[List[int]] = None, depth_scale: int = 1000, ) -> None: assert scene_ds.frame_index is not None @@ -102,7 +102,7 @@ def write_scene_ds_as_wds( continue key = sha1(obs.rgb.data).hexdigest() - sample: dict[str, Any] = { + sample: Dict[str, Any] = { "__key__": key, } if obs.rgb is not None: @@ -135,7 +135,7 @@ def write_scene_ds_as_wds( def load_scene_ds_obs( - sample: dict[str, Union[bytes, str]], + sample: Dict[str, Union[bytes, str]], depth_scale: float = 1000.0, load_depth: bool = False, label_format: str = "{label}", @@ -155,7 +155,7 @@ def load_scene_ds_obs( depth = np.asarray(depth, dtype=np.float32) depth /= depth_scale - object_datas_json: list[DataJsonType] = json.loads(sample["object_datas.json"]) + object_datas_json: List[DataJsonType] = json.loads(sample["object_datas.json"]) object_datas = [ObjectData.from_json(d) for d in object_datas_json] for obj in object_datas: obj.label = label_format.format(label=obj.label) @@ -203,7 +203,7 @@ def __init__( load_segmentation=load_segmentation, ) - def get_tar_list(self) -> list[str]: + def get_tar_list(self) -> List[str]: tar_files = [str(x) for x in self.wds_dir.iterdir() if x.suffix == ".tar"] tar_files.sort() return tar_files diff --git a/happypose/toolbox/inference/pose_estimator.py b/happypose/toolbox/inference/pose_estimator.py index 06ab1c07..9fe537fa 100644 --- a/happypose/toolbox/inference/pose_estimator.py +++ b/happypose/toolbox/inference/pose_estimator.py @@ -1,5 +1,6 @@ # Standard Library from abc import ABCMeta, abstractmethod +from typing import Tuple # Third Party import torch @@ -12,17 +13,17 @@ class PoseEstimationModule(torch.nn.Module, metaclass=ABCMeta): @abstractmethod def forward_coarse_model( self, - ) -> tuple[PoseEstimatesType, dict]: + ) -> Tuple[PoseEstimatesType, dict]: pass @abstractmethod def forward_refiner( self, - ) -> tuple[dict, dict]: + ) -> Tuple[dict, dict]: pass @abstractmethod def run_inference_pipeline( self, - ) -> tuple[PoseEstimatesType, dict]: + ) -> Tuple[PoseEstimatesType, dict]: pass diff --git a/happypose/toolbox/inference/utils.py b/happypose/toolbox/inference/utils.py index d61a0154..d20492f3 100644 --- a/happypose/toolbox/inference/utils.py +++ b/happypose/toolbox/inference/utils.py @@ -16,7 +16,7 @@ # Standard Library from pathlib import Path -from typing import Optional, Union +from typing import Dict, List, Optional, Tuple, Union # Third Party import numpy as np @@ -88,9 +88,9 @@ def load_pose_models( refiner_run_id: str, object_dataset: RigidObjectDataset, force_panda3d_renderer: bool = False, - renderer_kwargs: Optional[dict] = None, + renderer_kwargs: Optional[Dict] = None, models_root: Path = EXP_DIR, -) -> tuple[ +) -> Tuple[ torch.nn.Module, torch.nn.Module, happypose.toolbox.lib3d.rigid_mesh_database.BatchedMeshes, @@ -188,7 +188,7 @@ def create_instance_id(df: pd.DataFrame) -> pd.DataFrame: def filter_detections( detections: DetectionsType, - labels: Optional[list[str]] = None, + labels: Optional[List[str]] = None, one_instance_per_class: bool = False, ) -> DetectionsType: """Filter detections based on kwargs.""" @@ -208,7 +208,7 @@ def filter_detections( return detections -def make_cameras(camera_data: list[CameraData]) -> PandasTensorCollection: +def make_cameras(camera_data: List[CameraData]) -> PandasTensorCollection: """Creates a PandasTensorCollection from list of camera data. Returns @@ -226,7 +226,7 @@ def make_cameras(camera_data: list[CameraData]) -> PandasTensorCollection: return tc.PandasTensorCollection(infos=pd.DataFrame(infos), K=torch.stack(K)) -def make_detections_from_object_data(object_data: list[ObjectData]) -> DetectionsType: +def make_detections_from_object_data(object_data: List[ObjectData]) -> DetectionsType: infos = pd.DataFrame( { "label": [data.label for data in object_data], diff --git a/happypose/toolbox/lib3d/camera_geometry.py b/happypose/toolbox/lib3d/camera_geometry.py index 7664c489..b61182d6 100644 --- a/happypose/toolbox/lib3d/camera_geometry.py +++ b/happypose/toolbox/lib3d/camera_geometry.py @@ -15,6 +15,7 @@ # Standard Library +from typing import Tuple # Third Party import torch @@ -70,8 +71,8 @@ def boxes_from_uv(uv): def get_K_crop_resize( K: torch.Tensor, boxes: torch.Tensor, - orig_size: tuple[int, int], - crop_resize: tuple[int, int], + orig_size: Tuple[int, int], + crop_resize: Tuple[int, int], ) -> torch.Tensor: """Adapted from https://github.com/BerkeleyAutomation/perception/blob/master/perception/camera_intrinsics.py Skew is not handled. diff --git a/happypose/toolbox/lib3d/rigid_mesh_database.py b/happypose/toolbox/lib3d/rigid_mesh_database.py index ed26cc3b..b0648194 100644 --- a/happypose/toolbox/lib3d/rigid_mesh_database.py +++ b/happypose/toolbox/lib3d/rigid_mesh_database.py @@ -21,6 +21,7 @@ import numpy as np import torch import trimesh +from typing import List # MegaPose from happypose.toolbox.datasets.object_dataset import RigidObject @@ -50,7 +51,7 @@ def as_mesh(scene_or_mesh): class MeshDataBase: - def __init__(self, obj_list: list[RigidObject]): + def __init__(self, obj_list: List[RigidObject]): self.obj_dict = {obj.label: obj for obj in obj_list} self.obj_list = obj_list self.infos = {obj.label: {} for obj in obj_list} diff --git a/happypose/toolbox/lib3d/transform_ops.py b/happypose/toolbox/lib3d/transform_ops.py index 66f4ac2c..95348050 100644 --- a/happypose/toolbox/lib3d/transform_ops.py +++ b/happypose/toolbox/lib3d/transform_ops.py @@ -15,6 +15,7 @@ # Standard Library +from typing import Tuple # Third Party import numpy as np @@ -69,8 +70,8 @@ def invert_transform_matrices(T: torch.Tensor) -> torch.Tensor: def add_noise( TCO: torch.Tensor, - euler_deg_std: tuple[float, float, float] = (15, 15, 15), - trans_std: tuple[float, float, float] = (0.01, 0.01, 0.05), + euler_deg_std: Tuple[float, float, float] = (15, 15, 15), + trans_std: Tuple[float, float, float] = (0.01, 0.01, 0.05), ) -> torch.Tensor: TCO_out = TCO.clone() device = TCO_out.device diff --git a/happypose/toolbox/renderer/panda3d_batch_renderer.py b/happypose/toolbox/renderer/panda3d_batch_renderer.py index c1e6ee34..df74b70e 100644 --- a/happypose/toolbox/renderer/panda3d_batch_renderer.py +++ b/happypose/toolbox/renderer/panda3d_batch_renderer.py @@ -16,7 +16,7 @@ # Standard Library from dataclasses import dataclass -from typing import Optional, Union +from typing import List, Optional, Set, Union # Third Party import numpy as np @@ -72,8 +72,8 @@ class BatchRenderOutput: @dataclass class SceneData: camera_data: Panda3dCameraData - light_datas: list[Panda3dLightData] - object_datas: list[Panda3dObjectData] + light_datas: List[Panda3dLightData] + object_datas: List[Panda3dObjectData] @dataclass @@ -89,7 +89,7 @@ def worker_loop( in_queue: torch.multiprocessing.Queue, out_queue: torch.multiprocessing.Queue, object_dataset: RigidObjectDataset, - preload_labels: set[str] = set(), + preload_labels: Set[str] = set(), ) -> None: logger.debug(f"Init worker: {worker_id}") renderer = Panda3dSceneRenderer( @@ -161,12 +161,12 @@ def __init__( def make_scene_data( self, - labels: list[str], + labels: List[str], TCO: torch.Tensor, K: torch.Tensor, - light_datas: list[list[Panda3dLightData]], + light_datas: List[List[Panda3dLightData]], resolution: Resolution, - ) -> list[SceneData]: + ) -> List[SceneData]: """_summary_. Args: @@ -210,10 +210,10 @@ def make_scene_data( def render( self, - labels: list[str], + labels: List[str], TCO: torch.Tensor, K: torch.Tensor, - light_datas: list[list[Panda3dLightData]], + light_datas: List[List[Panda3dLightData]], resolution: Resolution, render_depth: bool = False, render_mask: bool = False, @@ -288,9 +288,9 @@ def render( def _init_renderers(self, preload_cache: bool) -> None: object_labels = [obj.label for obj in self._object_dataset.list_objects] - self._renderers: list[torch.multiprocessing.Process] = [] + self._renderers: List[torch.multiprocessing.Process] = [] if self._split_objects: - self._in_queues: list[torch.multiprocessing.Queue] = [ + self._in_queues: List[torch.multiprocessing.Queue] = [ torch.multiprocessing.Queue() for _ in range(self._n_workers) ] self._worker_id_to_queue = { diff --git a/happypose/toolbox/renderer/panda3d_scene_renderer.py b/happypose/toolbox/renderer/panda3d_scene_renderer.py index 0933dcd3..d1c6597a 100644 --- a/happypose/toolbox/renderer/panda3d_scene_renderer.py +++ b/happypose/toolbox/renderer/panda3d_scene_renderer.py @@ -23,6 +23,7 @@ from collections import defaultdict from dataclasses import dataclass from functools import partial +from typing import Dict, List, Set import numpy as np import panda3d as p3d @@ -50,7 +51,7 @@ @dataclass class Panda3dDebugData: - timings: dict[str, float] + timings: Dict[str, float] class App(ShowBase): @@ -106,7 +107,7 @@ def __init__(self) -> None: def make_scene_lights( ambient_light_color: RgbaColor = (0.1, 0.1, 0.1, 1.0), point_lights_color: RgbaColor = (0.4, 0.4, 0.4, 1.0), -) -> list[Panda3dLightData]: +) -> List[Panda3dLightData]: """Creates 1 ambient light + 6 point lights to illuminate a panda3d scene.""" pos = np.array( [ @@ -151,17 +152,17 @@ class Panda3dSceneRenderer: def __init__( self, asset_dataset: RigidObjectDataset, - preload_labels: set[str] = set(), + preload_labels: Set[str] = set(), debug: bool = False, verbose: bool = False, ): self._asset_dataset = asset_dataset - self._label_to_node: dict[str, p3d.core.NodePath] = {} + self._label_to_node: Dict[str, p3d.core.NodePath] = {} self.verbose = verbose self.debug = debug self.debug_data = Panda3dDebugData(timings={}) - self._cameras_pool: dict[Resolution, list[Panda3dCamera]] = defaultdict(list) + self._cameras_pool: Dict[Resolution, List[Panda3dCamera]] = defaultdict(list) if hasattr(builtins, "base"): self._app = builtins.base # type: ignore else: @@ -184,10 +185,10 @@ def create_new_camera(self, resolution: Resolution) -> Panda3dCamera: self._cameras_pool[resolution].append(cam) return cam - def get_cameras(self, data_cameras: list[Panda3dCameraData]) -> list[Panda3dCamera]: - resolution_to_data_cameras: dict[ + def get_cameras(self, data_cameras: List[Panda3dCameraData]) -> List[Panda3dCamera]: + resolution_to_data_cameras: Dict[ Resolution, - list[Panda3dCameraData], + List[Panda3dCameraData], ] = defaultdict(list) for data_camera in data_cameras: resolution_to_data_cameras[data_camera.resolution].append(data_camera) @@ -233,8 +234,8 @@ def use_normals_texture(self, obj_node: p3d.core.NodePath) -> p3d.core.NodePath: def setup_scene( self, root_node: p3d.core.NodePath, - data_objects: list[Panda3dObjectData], - ) -> list[p3d.core.NodePath]: + data_objects: List[Panda3dObjectData], + ) -> List[p3d.core.NodePath]: obj_nodes = [] for n, data_obj in enumerate(data_objects): label = data_obj.label @@ -255,8 +256,8 @@ def setup_scene( def setup_cameras( self, root_node: p3d.core.NodePath, - data_cameras: list[Panda3dCameraData], - ) -> list[Panda3dCamera]: + data_cameras: List[Panda3dCameraData], + ) -> List[Panda3dCamera]: cameras = self.get_cameras(data_cameras) for data_camera, camera in zip(data_cameras, cameras): @@ -273,10 +274,10 @@ def setup_cameras( def render_images( self, - cameras: list[Panda3dCamera], + cameras: List[Panda3dCamera], copy_arrays: bool = True, render_depth: bool = False, - ) -> list[CameraRenderingData]: + ) -> List[CameraRenderingData]: self._app.graphicsEngine.renderFrame() self._app.graphicsEngine.syncFrame() @@ -295,8 +296,8 @@ def render_images( def setup_lights( self, root_node: p3d.core, - light_datas: list[Panda3dLightData], - ) -> list[p3d.core.NodePath]: + light_datas: List[Panda3dLightData], + ) -> List[p3d.core.NodePath]: light_node_paths = [] for n, light_data in enumerate(light_datas): if light_data.light_type == "point": @@ -320,15 +321,15 @@ def setup_lights( def render_scene( self, - object_datas: list[Panda3dObjectData], - camera_datas: list[Panda3dCameraData], - light_datas: list[Panda3dLightData], + object_datas: List[Panda3dObjectData], + camera_datas: List[Panda3dCameraData], + light_datas: List[Panda3dLightData], render_depth: bool = False, copy_arrays: bool = True, render_binary_mask: bool = False, render_normals: bool = False, clear: bool = True, - ) -> list[CameraRenderingData]: + ) -> List[CameraRenderingData]: start = time.time() root_node = self._app.render.attachNewNode("world") object_nodes = self.setup_scene(root_node, object_datas) diff --git a/happypose/toolbox/renderer/types.py b/happypose/toolbox/renderer/types.py index 516162b9..bfc7d5af 100644 --- a/happypose/toolbox/renderer/types.py +++ b/happypose/toolbox/renderer/types.py @@ -16,7 +16,7 @@ # Standard Library from dataclasses import dataclass -from typing import Callable, Optional +from typing import Callable, Optional, Tuple # Third Party import numpy as np @@ -30,12 +30,12 @@ # Local Folder from .utils import depth_image_from_depth_buffer -RgbaColor = tuple[float, float, float, float] +RgbaColor = Tuple[float, float, float, float] NodeFunction = Callable[ [p3d.core.NodePath, p3d.core.NodePath], None, ] # (root_node_path, object_node_path) -Resolution = tuple[int, int] +Resolution = Tuple[int, int] TCCGL = Transform( np.array([[1, 0, 0, 0], [0, 0, -1, 0], [0, 1, 0, 0], [0, 0, 0, 1]], dtype=float), @@ -59,7 +59,7 @@ class CameraRenderingData: @dataclass class Panda3dCameraData: K: np.ndarray - resolution: tuple[int, int] + resolution: Tuple[int, int] TWC: Transform = Transform((0.0, 0.0, 0.0, 1.0), (0.0, 0.0, 0.0)) z_near: float = 0.1 z_far: float = 10 diff --git a/happypose/toolbox/utils/conversion.py b/happypose/toolbox/utils/conversion.py index 0bcba699..9fbeb55b 100644 --- a/happypose/toolbox/utils/conversion.py +++ b/happypose/toolbox/utils/conversion.py @@ -15,6 +15,7 @@ # Standard Library +from typing import List, Tuple # MegaPose from happypose.toolbox.datasets.scene_dataset import CameraData, ObjectData @@ -23,8 +24,8 @@ def convert_scene_observation_to_panda3d( camera_data: CameraData, - object_datas: list[ObjectData], -) -> tuple[Panda3dCameraData, list[Panda3dObjectData]]: + object_datas: List[ObjectData], +) -> Tuple[Panda3dCameraData, list[Panda3dObjectData]]: assert camera_data.TWC is not None assert camera_data.K is not None assert camera_data.resolution is not None diff --git a/happypose/toolbox/utils/download.py b/happypose/toolbox/utils/download.py index 1e3681ae..865dfc5f 100755 --- a/happypose/toolbox/utils/download.py +++ b/happypose/toolbox/utils/download.py @@ -7,6 +7,7 @@ import re import zipfile from pathlib import Path +from typing import Set import httpx from bs4 import BeautifulSoup @@ -452,7 +453,7 @@ class Flags: def __init__(self, flags: [str]): # only '--exclude' were used before so this is the only flag currently usable # if you need to use other flags, feel free to implement them here - self.exclude_set: set[str] = set() + self.exclude_set: Set[str] = set() parser = argparse.ArgumentParser("Flags parsing") parser.add_argument("--exclude", default="", type=str) diff --git a/happypose/toolbox/utils/types.py b/happypose/toolbox/utils/types.py index d5bbdafb..04aa5edf 100644 --- a/happypose/toolbox/utils/types.py +++ b/happypose/toolbox/utils/types.py @@ -12,6 +12,7 @@ See the License for the specific language governing permissions and limitations under the License. """ +from typing import Tuple -Resolution = tuple[int, int] +Resolution = Tuple[int, int] diff --git a/happypose/toolbox/visualization/bokeh_plotter.py b/happypose/toolbox/visualization/bokeh_plotter.py index ca915d4b..9d727bb1 100644 --- a/happypose/toolbox/visualization/bokeh_plotter.py +++ b/happypose/toolbox/visualization/bokeh_plotter.py @@ -20,7 +20,7 @@ from hashlib import sha1 from itertools import cycle from pathlib import Path -from typing import Optional, Union +from typing import Dict, List, Optional, Tuple, Union # Third Party import bokeh @@ -48,7 +48,7 @@ def __init__( Contains an internal state `source_map` holding pointers to image data. This can be useful for updating images in real-time without re-creating figures. """ - self.source_map: dict[str, bokeh.models.sources.ColumnDataSource] = {} + self.source_map: Dict[str, bokeh.models.sources.ColumnDataSource] = {} self.dump_image_dir = dump_image_dir self.read_image_dir = read_image_dir if is_notebook: @@ -59,13 +59,13 @@ def hex_colors(self) -> Iterator[str]: return cycle(sns.color_palette(n_colors=40).as_hex()) @property - def colors(self) -> Iterator[tuple[float, float, float]]: + def colors(self) -> Iterator[Tuple[float, float, float]]: return cycle(sns.color_palette(n_colors=40)) def get_source( self, name: str, - ) -> tuple[bokeh.models.sources.ColumnDataSource, bool]: + ) -> Tuple[bokeh.models.sources.ColumnDataSource, bool]: if name in self.source_map: source = self.source_map[name] new = False @@ -145,7 +145,7 @@ def plot_detections( self, f: bokeh.plotting.figure, detections: PandasTensorCollection, - colors: Union[str, list[str]] = "red", + colors: Union[str, List[str]] = "red", text: Optional[Union[str, list[str]]] = None, text_auto: bool = True, text_font_size: str = "8pt", diff --git a/happypose/toolbox/visualization/bokeh_utils.py b/happypose/toolbox/visualization/bokeh_utils.py index 2611109d..6be1a781 100644 --- a/happypose/toolbox/visualization/bokeh_utils.py +++ b/happypose/toolbox/visualization/bokeh_utils.py @@ -18,7 +18,7 @@ # Standard Library from pathlib import Path -from typing import Optional +from typing import Optional, Tuple # Third Party import bokeh @@ -64,7 +64,7 @@ def plot_image( tools: str = "", im_size: Optional[Resolution] = None, figure: Optional[bokeh.plotting.figure] = None, -) -> tuple[bokeh.plotting.figure, bokeh.models.sources.ColumnDataSource]: +) -> Tuple[bokeh.plotting.figure, bokeh.models.sources.ColumnDataSource]: if np.asarray(im).ndim == 2: gray = True else: diff --git a/happypose/toolbox/visualization/utils.py b/happypose/toolbox/visualization/utils.py index c1e83ce8..d93aa0e9 100644 --- a/happypose/toolbox/visualization/utils.py +++ b/happypose/toolbox/visualization/utils.py @@ -15,7 +15,7 @@ # Standard Library -from typing import Any, Optional, Union +from typing import Any, Dict, Optional, Tuple, Union # Third Party import cv2 @@ -55,9 +55,9 @@ def get_mask_from_rgb(img: np.ndarray) -> np.ndarray: def make_contour_overlay( img: np.ndarray, render: np.ndarray, - color: Optional[tuple[int, int, int]] = None, + color: Optional[Tuple[int, int, int]] = None, dilate_iterations: int = 1, -) -> dict[str, Any]: +) -> Dict[str, Any]: if color is None: color = (0, 255, 0) From 1ea74d302f3b802726482e6a59a1333b5424328b Mon Sep 17 00:00:00 2001 From: Mederic Fourmy Date: Fri, 12 Jan 2024 18:09:37 +0100 Subject: [PATCH 3/4] py38: drop type hints --- happypose/toolbox/datasets/web_scene_dataset.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/happypose/toolbox/datasets/web_scene_dataset.py b/happypose/toolbox/datasets/web_scene_dataset.py index 0d14b23c..069bea5d 100644 --- a/happypose/toolbox/datasets/web_scene_dataset.py +++ b/happypose/toolbox/datasets/web_scene_dataset.py @@ -238,8 +238,8 @@ def __init__(self, web_scene_dataset: WebSceneDataset, buffer_size: int = 1): ) def load_scene_ds_obs_iterator( - samples: Iterator[SceneObservation], - ) -> Iterator[SceneObservation]: + samples, + ): for sample in samples: yield load_scene_ds_obs_(sample) @@ -250,5 +250,5 @@ def load_scene_ds_obs_iterator( wds.shuffle(buffer_size), ) - def __iter__(self) -> Iterator[SceneObservation]: + def __iter__(self): return iter(self.datapipeline) From dddd0a9336894139755bd8fcbdb241ea1f2ed272 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 12 Jan 2024 18:11:52 +0000 Subject: [PATCH 4/4] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- .../cosypose/cosypose/evaluation/evaluation.py | 2 +- happypose/pose_estimators/megapose/evaluation/eval_config.py | 2 +- happypose/pose_estimators/megapose/inference/icp_refiner.py | 2 +- .../pose_estimators/megapose/training/training_config.py | 2 +- happypose/pose_estimators/megapose/training/utils.py | 3 +-- happypose/toolbox/datasets/augmentations.py | 2 +- happypose/toolbox/datasets/pose_dataset.py | 5 ++--- happypose/toolbox/datasets/utils.py | 2 +- happypose/toolbox/datasets/web_scene_dataset.py | 1 - happypose/toolbox/lib3d/rigid_mesh_database.py | 2 +- happypose/toolbox/lib3d/transform.py | 2 +- happypose/toolbox/utils/distributed.py | 2 +- happypose/toolbox/utils/types.py | 1 - 13 files changed, 12 insertions(+), 16 deletions(-) diff --git a/happypose/pose_estimators/cosypose/cosypose/evaluation/evaluation.py b/happypose/pose_estimators/cosypose/cosypose/evaluation/evaluation.py index 4e65c3e0..4a22cf77 100644 --- a/happypose/pose_estimators/cosypose/cosypose/evaluation/evaluation.py +++ b/happypose/pose_estimators/cosypose/cosypose/evaluation/evaluation.py @@ -1,6 +1,6 @@ # Standard Library from pathlib import Path -from typing import Any, Optional, Dict +from typing import Any, Dict, Optional # Third Party import torch diff --git a/happypose/pose_estimators/megapose/evaluation/eval_config.py b/happypose/pose_estimators/megapose/evaluation/eval_config.py index d3b4890f..3b8ae582 100644 --- a/happypose/pose_estimators/megapose/evaluation/eval_config.py +++ b/happypose/pose_estimators/megapose/evaluation/eval_config.py @@ -16,7 +16,7 @@ # Standard Library from dataclasses import dataclass -from typing import Optional, List +from typing import List, Optional # MegaPose from happypose.pose_estimators.megapose.inference.types import InferenceConfig diff --git a/happypose/pose_estimators/megapose/inference/icp_refiner.py b/happypose/pose_estimators/megapose/inference/icp_refiner.py index 5acfd528..d1f649cf 100644 --- a/happypose/pose_estimators/megapose/inference/icp_refiner.py +++ b/happypose/pose_estimators/megapose/inference/icp_refiner.py @@ -15,7 +15,7 @@ # Standard Library -from typing import Optional, Tuple, Dict +from typing import Dict, Optional, Tuple # Third Party import cv2 diff --git a/happypose/pose_estimators/megapose/training/training_config.py b/happypose/pose_estimators/megapose/training/training_config.py index f15f3185..563485a8 100644 --- a/happypose/pose_estimators/megapose/training/training_config.py +++ b/happypose/pose_estimators/megapose/training/training_config.py @@ -15,7 +15,7 @@ # Standard Library from dataclasses import dataclass, field -from typing import Optional, List, Tuple +from typing import List, Optional, Tuple # Third Party import numpy as np diff --git a/happypose/pose_estimators/megapose/training/utils.py b/happypose/pose_estimators/megapose/training/utils.py index 8e8afb89..63081e50 100644 --- a/happypose/pose_estimators/megapose/training/utils.py +++ b/happypose/pose_estimators/megapose/training/utils.py @@ -16,7 +16,6 @@ # Standard Library import time -from collections.abc import Iterator from pathlib import Path from typing import Callable, Optional @@ -115,7 +114,7 @@ def cast_raw_numpy_images_to_tensor(images): def make_optimizer( - parameters, # : Iterator[torch.nn.Parameter], + parameters, # : Iterator[torch.nn.Parameter], cfg: TrainingConfig, ) -> torch.optim.Optimizer: optimizer: Optional[torch.optim.Optimizer] = None diff --git a/happypose/toolbox/datasets/augmentations.py b/happypose/toolbox/datasets/augmentations.py index d4e35781..9d1a80b5 100644 --- a/happypose/toolbox/datasets/augmentations.py +++ b/happypose/toolbox/datasets/augmentations.py @@ -19,7 +19,7 @@ import random from copy import deepcopy from pathlib import Path -from typing import Dict, Union, List, Tuple +from typing import Dict, List, Tuple, Union # Third Party import cv2 diff --git a/happypose/toolbox/datasets/pose_dataset.py b/happypose/toolbox/datasets/pose_dataset.py index d71cea76..b3f753ea 100644 --- a/happypose/toolbox/datasets/pose_dataset.py +++ b/happypose/toolbox/datasets/pose_dataset.py @@ -17,9 +17,8 @@ # Standard Library import random import time -from collections.abc import Iterator from dataclasses import dataclass -from typing import List, Optional, Union, Set +from typing import List, Optional, Set, Union # Third Party import numpy as np @@ -351,7 +350,7 @@ def find_valid_data(self, iterator) -> PoseData: msg = "Cannot find valid image in the dataset" raise ValueError(msg) - def __iter__(self): # -> Iterator[PoseData]: + def __iter__(self): # -> Iterator[PoseData]: assert isinstance(self.scene_ds, IterableSceneDataset) iterator = iter(self.scene_ds) while True: diff --git a/happypose/toolbox/datasets/utils.py b/happypose/toolbox/datasets/utils.py index fd64288e..19802615 100644 --- a/happypose/toolbox/datasets/utils.py +++ b/happypose/toolbox/datasets/utils.py @@ -15,7 +15,7 @@ # Standard Library -from typing import List, Dict +from typing import Dict, List # Third Party import numpy as np diff --git a/happypose/toolbox/datasets/web_scene_dataset.py b/happypose/toolbox/datasets/web_scene_dataset.py index 069bea5d..0f1ff87e 100644 --- a/happypose/toolbox/datasets/web_scene_dataset.py +++ b/happypose/toolbox/datasets/web_scene_dataset.py @@ -18,7 +18,6 @@ import io import json from collections import defaultdict -from collections.abc import Iterator from functools import partial from hashlib import sha1 from pathlib import Path diff --git a/happypose/toolbox/lib3d/rigid_mesh_database.py b/happypose/toolbox/lib3d/rigid_mesh_database.py index b0648194..13263897 100644 --- a/happypose/toolbox/lib3d/rigid_mesh_database.py +++ b/happypose/toolbox/lib3d/rigid_mesh_database.py @@ -16,12 +16,12 @@ # Standard Library from copy import deepcopy +from typing import List # Third Party import numpy as np import torch import trimesh -from typing import List # MegaPose from happypose.toolbox.datasets.object_dataset import RigidObject diff --git a/happypose/toolbox/lib3d/transform.py b/happypose/toolbox/lib3d/transform.py index ec3fb2fc..001a19c2 100644 --- a/happypose/toolbox/lib3d/transform.py +++ b/happypose/toolbox/lib3d/transform.py @@ -15,7 +15,7 @@ # Standard Library -from typing import Union, Tuple +from typing import Tuple, Union # Third Party import numpy as np diff --git a/happypose/toolbox/utils/distributed.py b/happypose/toolbox/utils/distributed.py index 755b2c12..91b1ae26 100644 --- a/happypose/toolbox/utils/distributed.py +++ b/happypose/toolbox/utils/distributed.py @@ -19,7 +19,7 @@ import os import sys from pathlib import Path -from typing import Any, List, Dict +from typing import Any, Dict, List import omegaconf diff --git a/happypose/toolbox/utils/types.py b/happypose/toolbox/utils/types.py index 04aa5edf..2d564835 100644 --- a/happypose/toolbox/utils/types.py +++ b/happypose/toolbox/utils/types.py @@ -14,5 +14,4 @@ """ from typing import Tuple - Resolution = Tuple[int, int]