Skip to content

Commit 7a1e96c

Browse files
committed
Merge branch 'dev' into cosy-eval-adapt
2 parents fcc8f7f + 7400e61 commit 7a1e96c

38 files changed

+6250
-4845
lines changed

.github/workflows/conda-test.yml

+3-3
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ jobs:
1010
shell: bash -el {0}
1111
strategy:
1212
matrix:
13-
python-version: ["3.9", "3.10"]
13+
python-version: ["3.10", "3.12"]
1414
steps:
1515
- uses: actions/checkout@v4
1616
with:
@@ -52,7 +52,7 @@ jobs:
5252
if: steps.cache.outputs.cache-hit != 'true'
5353

5454
- name: Install happypose
55-
run: pip install -e .
55+
run: pip install -e .[multiview]
5656

5757
- name: Download pre-trained models required for tests
5858
run: |
@@ -69,4 +69,4 @@ jobs:
6969
- name: Run tests
7070
run: |
7171
python -m unittest
72-
pytest
72+
pytest tests -v

.github/workflows/pip-test.yml

+3-3
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ jobs:
77
runs-on: ubuntu-latest
88
strategy:
99
matrix:
10-
python-version: ["3.9", "3.10"]
10+
python-version: ["3.10", "3.12"]
1111
steps:
1212
- uses: actions/checkout@v4
1313
with:
@@ -30,7 +30,7 @@ jobs:
3030
run: pip install -U pip
3131

3232
- name: Install happypose
33-
run: pip install ".[cpu,pypi]" --extra-index-url https://download.pytorch.org/whl/cpu
33+
run: pip install ".[multiview,pypi]"
3434

3535
- name: Download pre-trained models required for tests
3636
run: |
@@ -47,4 +47,4 @@ jobs:
4747
- name: Run tests
4848
run: |
4949
python -m unittest
50-
pytest
50+
pytest tests -v

.github/workflows/poetry-test.yml

+3-3
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ jobs:
77
runs-on: ubuntu-latest
88
strategy:
99
matrix:
10-
python-version: ["3.9", "3.10"]
10+
python-version: ["3.10", "3.12"]
1111
steps:
1212
- uses: actions/checkout@v4
1313
with:
@@ -31,7 +31,7 @@ jobs:
3131
cache: poetry
3232

3333
- name: Install happypose
34-
run: poetry install --with dev -E cpu -E pypi
34+
run: poetry install --with dev -E pypi -E multiview
3535

3636
- name: Download pre-trained models required for tests
3737
run: |
@@ -48,7 +48,7 @@ jobs:
4848
- name: Run tests
4949
run: |
5050
poetry run coverage run --source=happypose -m unittest
51-
poetry run coverage run --source=happypose -m pytest
51+
poetry run coverage run --source=happypose -m pytest tests -v
5252
5353
- name: Process coverage
5454
run: poetry run coverage xml

.pre-commit-config.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
repos:
22
- repo: https://github.com/astral-sh/ruff-pre-commit
3-
rev: v0.4.1
3+
rev: v0.5.2
44
hooks:
55
- id: ruff
66
args:

README.md

+56-4
Original file line numberDiff line numberDiff line change
@@ -39,19 +39,71 @@ git clone --branch dev --recurse-submodules https://github.com/agimus-project/ha
3939
cd happypose
4040
python -m venv .venv
4141
source .venv/bin/activate
42-
pip install .[pypi,cpu] --extra-index-url https://download.pytorch.org/whl/cpu
42+
pip install .[pypi]
4343
```
4444

4545
### Install extras:
4646

47-
- `cpu`: required to get pytorch CPU from PyPI (don't use this for GPU or with conda)
48-
- `gpu`: required to get pytorch GPU from PyPI (don't use this for CPU or with conda)
4947
- `multiview`: installs cosypose c++ extension
50-
- `pypi`: install pinocchio & opencv from PyPI (don't use this with conda)
48+
- `pypi`: install torch, pinocchio & opencv from PyPI (don't use this with conda)
5149

5250
## Create data directory
5351

5452
```
5553
Create data dir /somewhere/convenient. The dataset to store are quite large.
5654
export HAPPYPOSE_DATA_DIR=/somewhere/convenient
5755
```
56+
57+
## Test the install
58+
59+
### CPU
60+
61+
If you work on CPU, these models need to be download :
62+
63+
```
64+
#hope dataset models for CosyPose
65+
python -m happypose.toolbox.utils.download --cosypose_models \
66+
detector-bop-hope-pbr--15246 \
67+
coarse-bop-hope-pbr--225203 \
68+
refiner-bop-hope-pbr--955392
69+
```
70+
71+
```
72+
# For MegaPose
73+
python -m happypose.toolbox.utils.download --megapose_models
74+
```
75+
76+
and the examples
77+
78+
```
79+
python -m happypose.toolbox.utils.download --examples barbecue-sauce
80+
```
81+
82+
In the HappyPose folder:
83+
84+
```
85+
pytest -v ./tests
86+
```
87+
88+
You may need to install `pytest-order` : `pip installp pytest-order`. In this case, test related to the `evaluation` and the `training` of CosyPose are not run. If you want to use these functionalities, you need a GPU.
89+
90+
### GPU
91+
92+
Tests related to `evaluation` and `training` will be run if a GPU is available. Hence, a few more downloads are needed :
93+
94+
```
95+
#ycbv models
96+
python -m happypose.toolbox.utils.download --cosypose_models \
97+
coarse-bop-ycbv-pbr--724183 \
98+
refiner-bop-ycbv-pbr--604090
99+
```
100+
101+
```
102+
python -m happypose.toolbox.utils.download --bop_dataset ycbv
103+
```
104+
105+
```
106+
python -m happypose.toolbox.utils.download --test-results
107+
```
108+
109+
The tests take much longer in this case.

environment.yml

+8-6
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,20 @@
1-
name: happypose
1+
#name: happypose_torch2
22
channels:
33
- conda-forge
44
- pytorch
55
- nvidia
66
- anaconda
77
- defaults
88
dependencies:
9-
- nvidia::cudatoolkit==11.3.1
10-
- python=3.9
9+
- pytorch-cuda==12.1
1110
- pip
12-
- pytorch::pytorch==1.11.0
13-
- torchvision==0.12.0
14-
- mkl==2024.0.0
11+
- pytorch
12+
- torchvision
1513
- geckodriver
1614
- firefox
1715
- opencv
1816
- pinocchio
17+
- torchtnt
18+
- pip:
19+
- torchnet
20+
- numpy<2

happypose/pose_estimators/cosypose/cosypose/models/mask_rcnn.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ def __init__(
1212
anchor_sizes=((32,), (64,), (128,), (256,), (512,)),
1313
):
1414
assert backbone_str == "resnet50-fpn"
15-
backbone = resnet_fpn_backbone("resnet50", pretrained=False)
15+
backbone = resnet_fpn_backbone(backbone_name="resnet50", weights=None)
1616

1717
aspect_ratios = ((0.5, 1.0, 2.0),) * len(anchor_sizes)
1818
rpn_anchor_generator = AnchorGenerator(anchor_sizes, aspect_ratios)

happypose/pose_estimators/cosypose/cosypose/scripts/run_detector_training.py

+2-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
import os
33

44
import numpy as np
5-
from colorama import Fore, Style
65

76
from happypose.pose_estimators.cosypose.cosypose.training.train_detector import (
87
train_detector,
@@ -23,13 +22,13 @@
2322
cfg = argparse.ArgumentParser("").parse_args([])
2423
if args.config:
2524
logger.info(
26-
f"{Fore.GREEN}Training with config: {args.config} {Style.RESET_ALL}",
25+
f"Training with config: {args.config}",
2726
)
2827

2928
cfg.resume_run_id = None
3029
if len(args.resume) > 0:
3130
cfg.resume_run_id = args.resume
32-
logger.info(f"{Fore.RED}Resuming {cfg.resume_run_id} {Style.RESET_ALL}")
31+
logger.info(f"Resuming {cfg.resume_run_id}")
3332

3433
N_CPUS = int(os.environ.get("N_CPUS", 10))
3534
N_GPUS = int(os.environ.get("N_PROCS", 1))

happypose/pose_estimators/cosypose/cosypose/training/train_detector.py

+5-3
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
from torch.hub import load_state_dict_from_url
1313
from torch.utils.data import DataLoader
1414
from torchnet.meter import AverageValueMeter
15-
from torchvision.models.detection.mask_rcnn import model_urls
1615
from tqdm import tqdm
1716

1817
from happypose.pose_estimators.cosypose.cosypose.config import EXP_DIR
@@ -232,7 +231,9 @@ def make_datasets(dataset_names):
232231
logger.info(f"Using pretrained model from {pretrain_path}.")
233232
model.load_state_dict(torch.load(pretrain_path)["state_dict"])
234233
elif args.pretrain_coco:
235-
state_dict = load_state_dict_from_url(model_urls["maskrcnn_resnet50_fpn_coco"])
234+
state_dict = load_state_dict_from_url(
235+
"https://download.pytorch.org/models/maskrcnn_resnet50_fpn_coco-bf2d0c1e.pth"
236+
)
236237

237238
def keep(k):
238239
return "box_predictor" not in k and "mask_predictor" not in k
@@ -289,7 +290,8 @@ def lambd(batch):
289290
gamma=0.1,
290291
)
291292
lr_scheduler.last_epoch = start_epoch - 1
292-
lr_scheduler.step()
293+
# This led to a warning in newer version of PyTorch?
294+
# lr_scheduler.step()
293295

294296
for epoch in range(start_epoch, end_epoch):
295297
meters_train = defaultdict(AverageValueMeter)

happypose/pose_estimators/cosypose/cosypose/training/train_pose.py

+32-39
Original file line numberDiff line numberDiff line change
@@ -421,52 +421,45 @@ def train_epoch():
421421
iterator = tqdm(ds_iter_train, ncols=80)
422422
t = time.time()
423423
for n, data in enumerate(iterator):
424-
if n < 3:
425-
if n > 0:
426-
meters_time["data"].add(time.time() - t)
427-
428-
optimizer.zero_grad()
429-
430-
t = time.time()
431-
loss = h(data=data, meters=meters_train)
432-
meters_time["forward"].add(time.time() - t)
433-
iterator.set_postfix(loss=loss.item())
434-
meters_train["loss_total"].add(loss.item())
435-
436-
t = time.time()
437-
loss.backward()
438-
total_grad_norm = torch.nn.utils.clip_grad_norm_(
439-
model.parameters(),
440-
max_norm=args.clip_grad_norm,
441-
norm_type=2,
442-
)
443-
meters_train["grad_norm"].add(
444-
torch.as_tensor(total_grad_norm).item()
445-
)
446-
447-
optimizer.step()
448-
meters_time["backward"].add(time.time() - t)
449-
meters_time["memory"].add(
450-
torch.cuda.max_memory_allocated() / 1024.0**2,
451-
)
452-
453-
if epoch < args.n_epochs_warmup:
454-
lr_scheduler_warmup.step()
455-
t = time.time()
456-
else:
457-
break
424+
if n > 0:
425+
meters_time["data"].add(time.time() - t)
426+
427+
optimizer.zero_grad()
428+
429+
t = time.time()
430+
loss = h(data=data, meters=meters_train)
431+
meters_time["forward"].add(time.time() - t)
432+
iterator.set_postfix(loss=loss.item())
433+
meters_train["loss_total"].add(loss.item())
434+
435+
t = time.time()
436+
loss.backward()
437+
total_grad_norm = torch.nn.utils.clip_grad_norm_(
438+
model.parameters(),
439+
max_norm=args.clip_grad_norm,
440+
norm_type=2,
441+
)
442+
meters_train["grad_norm"].add(torch.as_tensor(total_grad_norm).item())
443+
444+
optimizer.step()
445+
meters_time["backward"].add(time.time() - t)
446+
meters_time["memory"].add(
447+
torch.cuda.max_memory_allocated() / 1024.0**2,
448+
)
449+
450+
if epoch < args.n_epochs_warmup:
451+
lr_scheduler_warmup.step()
452+
t = time.time()
453+
458454
if epoch >= args.n_epochs_warmup:
459455
lr_scheduler.step()
460456

461457
@torch.no_grad()
462458
def validation():
463459
model.eval()
464460
for n, sample in enumerate(tqdm(ds_iter_val, ncols=80)):
465-
if n < 3:
466-
loss = h(data=sample, meters=meters_val)
467-
meters_val["loss_total"].add(loss.item())
468-
else:
469-
break
461+
loss = h(data=sample, meters=meters_val)
462+
meters_val["loss_total"].add(loss.item())
470463

471464
@torch.no_grad()
472465
def test():

happypose/pose_estimators/megapose/docker/Dockerfile.megapose

+1-2
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ RUN source $CONDA_DIR/bin/activate && \
5656
pip install selenium omegaconf simplejson line_profiler opencv-python \
5757
torchnet tqdm lxml transforms3d panda3d joblib xarray pandas xarray matplotlib \
5858
bokeh plyfile trimesh wget ipdb panda3d-gltf colorama pyyaml ipykernel \
59-
scipy pypng h5py seaborn kornia meshcat pyarrow dt_apriltags open3d structlog \
59+
scipy pypng h5py seaborn kornia meshcat pyarrow dt_apriltags structlog \
6060
imageio
6161

6262
# Blender
@@ -132,7 +132,6 @@ RUN apt-get install -y tmux
132132
# Install TEASER++
133133
RUN apt install -y cmake libeigen3-dev libboost-all-dev \
134134
&& source $CONDA_DIR/bin/activate \
135-
&& pip install open3d \
136135
&& mkdir /build && cd /build && git clone https://github.com/MIT-SPARK/TEASER-plusplus.git \
137136
&& cd TEASER-plusplus && mkdir build && cd build \
138137
&& cmake -DTEASERPP_PYTHON_VERSION=3.9 .. && make teaserpp_python \

happypose/pose_estimators/megapose/evaluation/bop.py

+7-9
Original file line numberDiff line numberDiff line change
@@ -119,18 +119,19 @@ def convert_results_to_bop(
119119
t = TCO_n[:3, -1] * 1e3 # m -> mm conversion
120120
R = TCO_n[:3, :3]
121121
row = predictions.infos.iloc[n]
122+
print("row =", row)
122123
obj_id = int(row.label.split("_")[-1])
123124
if use_pose_score:
124-
score = row.pose_score
125+
score = row["pose_score"]
125126
else:
126-
score = row.score
127+
score = row["score"]
127128
if "time" in row:
128-
time = row.time
129+
time = row["time"]
129130
else:
130131
time = -1
131132
pred = dict(
132-
scene_id=row.scene_id,
133-
im_id=row.view_id,
133+
scene_id=row["scene_id"],
134+
im_id=row["view_id"],
134135
obj_id=obj_id,
135136
score=score,
136137
t=t,
@@ -184,7 +185,6 @@ def _run_bop_evaluation(filename, eval_dir, eval_detection=False, dummy=False):
184185

185186
def run_evaluation(cfg: BOPEvalConfig) -> None:
186187
"""Runs the bop evaluation for the given setting."""
187-
print(cfg)
188188
results_path = Path(cfg.results_path)
189189
eval_dir = Path(cfg.eval_dir)
190190

@@ -203,9 +203,7 @@ def run_evaluation(cfg: BOPEvalConfig) -> None:
203203
csv_path = eval_dir / f"{method}_{cfg.dataset.split('.')[0]}-{cfg.split}.csv"
204204

205205
# pose scores give better AR scores in general
206-
convert_results_to_bop(
207-
results_path, csv_path, cfg.method, use_pose_score=cfg.use_post_score
208-
)
206+
convert_results_to_bop(results_path, csv_path, cfg.method, use_pose_score=False)
209207

210208
if not cfg.convert_only:
211209
_run_bop_evaluation(csv_path, cfg.eval_dir, eval_detection=False)

0 commit comments

Comments
 (0)