Skip to content

Commit 9a667d9

Browse files
authored
Merge pull request #32 from NWalker4483/main
Based on v1.1.10, updated requirements to PEP 517, Removed Wildcard imports, Added multi tag estimation
2 parents 2e546d2 + 7668c1e commit 9a667d9

30 files changed

+4439
-464
lines changed

.DS_Store

8 KB
Binary file not shown.

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
.idea/
22
aruco_estimator/data/
33
data/
4+
__pycache__/
45

56
# Byte-compiled / optimized / DLL files
67
__pycache__/git s
@@ -9,7 +10,9 @@ __pycache__/git s
910

1011
# C extensions
1112
*.so
12-
13+
_config.yml
14+
.*_cache/
15+
.vscode/
1316
# Distribution / packaging
1417
.Python
1518
build/

README.md

Lines changed: 13 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,6 @@
88
<a href="https://pypi.org/project/aruco-estimator/"><img alt="PyPI" src="https://img.shields.io/pypi/v/aruco-estimator"></a>
99
<a href="https://github.com/meyerls/aruco-estimator/actions"><img alt="GitHub Workflow Status" src="https://img.shields.io/github/workflow/status/meyerls/aruco-estimator/Python%20package"></a>
1010
<a href="https://github.com/meyerls/aruco-estimator/blob/main/LICENSE"><img alt="license" src="https://img.shields.io/github/license/meyerls/aruco-estimator"></a>
11-
<!--a href="https://pepy.tech/project/aruco-estimator"><img alt="PyPI - Downloads" src="https://img.shields.io/pypi/dm/aruco-estimator?label=PyPi%20downloads"></a-->
12-
13-
14-
<!--![PyPI](https://img.shields.io/pypi/v/aruco-estimator)
15-
![PyPI - Downloads](https://img.shields.io/pypi/dm/aruco-estimator?label=PyPi%20downloads)
16-
![GitHub Workflow Status](https://img.shields.io/github/workflow/status/meyerls/aruco-estimator/Publish%20Python%20%F0%9F%90%8D%20distributions%20%F0%9F%93%A6%20to%20PyPI%20and%20TestPyPI)
17-
![GitHub](https://img.shields.io/github/license/meyerls/aruco-estimator)-->
1811

1912
## About
2013

@@ -26,7 +19,6 @@ with [COLMAP](https://colmap.github.io/) by placing an aruco marker into the sce
2619
### PyPi
2720

2821
This repository is tested on Python 3.6+ and can be installed from [PyPi](https://pypi.org/project/aruco-estimator)
29-
<!-- Tutorial: https://www.youtube.com/watch?v=JkeNVaiUq_c -->
3022

3123
````angular2html
3224
pip install aruco-estimator
@@ -51,7 +43,7 @@ dataset.download_door_dataset(output_path='.')
5143
An example of how to use the aruco estimator is shown below.
5244

5345
````python
54-
from aruco_estimator.aruco_scale_factor import ArucoScaleFactor
46+
from aruco_estimator.aruco_localizer import ArucoLocalizer
5547
from aruco_estimator.visualization import ArucoVisualization
5648
from aruco_estimator import download
5749
from colmap_wrapper.colmap import COLMAP
@@ -66,53 +58,39 @@ dataset.download_door_dataset()
6658
project = COLMAP(project_path=dataset.dataset_path, image_resize=0.4)
6759

6860
# Init & run pose estimation of corners in 3D & estimate mean L2 distance between the four aruco corners
69-
aruco_scale_factor = ArucoScaleFactor(photogrammetry_software=project, aruco_size=dataset.scale)
70-
aruco_distance, aruco_corners_3d = aruco_scale_factor.run()
71-
print('Size of the unscaled aruco markers: ', aruco_distance)
61+
aruco_localizer = ArucoLocalizer(photogrammetry_software=project, aruco_size=dataset.scale)
62+
aruco_distance, aruco_corners_3d = aruco_localizer.run()
63+
logging.info('Size of the unscaled aruco markers: ', aruco_distance)
7264

7365
# Calculate scaling factor, apply it to the scene and save scaled point cloud
74-
dense, scale_factor = aruco_scale_factor.apply()
75-
print('Point cloud and poses are scaled by: ', scale_factor)
76-
print('Size of the scaled (true to scale) aruco markers in meters: ', aruco_distance * scale_factor)
66+
dense, scale_factor = aruco_localizer.apply()
67+
logging.info('Point cloud and poses are scaled by: ', scale_factor)
68+
logging.info('Size of the scaled (true to scale) aruco markers in meters: ', aruco_distance * scale_factor)
7769

7870
# Visualization of the scene and rays
79-
vis = ArucoVisualization(aruco_colmap=aruco_scale_factor)
71+
vis = ArucoVisualization(aruco_colmap=aruco_localizer)
8072
vis.visualization(frustum_scale=0.7, point_size=0.1)
8173

8274
# Write Data
83-
aruco_scale_factor.write_data()
75+
aruco_localizer.write_data()
8476
````
8577

8678
### Registration and Scaling
8779

8880
In some cases COLMAP is not able to registrate all images into one dense reconstruction. If appears to be reconstructed
8981
into two seperated reconstruction. To registrate both (up to know only two are possible) reconstructions the aruco
90-
markers are used to registrate both sides using ```ArucoMarkerScaledRegistration```.
82+
markers are used to registrate both sides using ```ArucoRegistration```.
9183

9284
```python
93-
from aruco_estimator.registration import ArucoMarkerScaledRegistration
85+
from aruco_estimator.registration import ArucoRegistration
9486

95-
scaled_registration = ArucoMarkerScaledRegistration(project_path_a=[path2part1],
87+
scaled_registration = ArucoRegistration(project_path_a=[path2part1],
9688
project_path_b=[path2part2])
9789
scaled_registration.scale(debug=True)
9890
scaled_registration.registrate(manual=False, debug=True)
9991
scaled_registration.write()
10092
```
10193

102-
103-
## Source
104-
105-
If you want to install the repo from source make sure that conda is installed. Afterwards clone this repository, give
106-
the bash file executable rights and install the conda env:
107-
108-
````angular2html
109-
git clone https://github.com/meyerls/aruco-estimator.git
110-
cd aruco-estimator
111-
chmod u+x init_env.sh
112-
# You might need a password to install exiftools
113-
./init_env.sh
114-
````
115-
11694
To test the code on your local machine try the example project by using:
11795

11896
````angular2html
@@ -147,7 +125,7 @@ repo [COLMAP Utility Scripts](https://github.com/uzh-rpg/colmap_utils) by [uzh-r
147125
* In some cases cv2 does not detect the aruco marker module. Reinstalling opencv-python and opencv-python-python might
148126
help [Source](https://stackoverflow.com/questions/45972357/python-opencv-aruco-no-module-named-cv2-aruco)
149127
* [PyExifTool](https://github.com/sylikc/pyexiftool): A library to communicate with the [ExifTool](https://exiftool.org)
150-
command- application. If you have trouble installing it please refer to the PyExifTool-Homepage.
128+
application. If you have trouble installing it please refer to the PyExifTool-Homepage.
151129
```bash
152130
# For Ubuntu users:
153131
wget https://exiftool.org/Image-ExifTool-12.51.tar.gz

aruco_estimator/.DS_Store

6 KB
Binary file not shown.

aruco_estimator/__init__.py

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,5 @@
66
See LICENSE file for more information.
77
"""
88

9-
# Built-in/Generic Imports
10-
# ...
11-
# Libs
12-
# ...
13-
14-
# Own modules
15-
from . import aruco
16-
from . import aruco_scale_factor
17-
from . import base
18-
from . import download
19-
from . import opt
20-
from . import visualization
21-
from . import utils
9+
from . import aruco, opt, utils, visualization
2210

aruco_estimator/aruco.py

Lines changed: 21 additions & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -8,105 +8,48 @@
88
"""
99

1010
# Built-in/Generic Imports
11-
from typing import Union
12-
from typing import Tuple
11+
import logging
12+
from typing import Tuple, Union
1313

14-
# Libs
1514
import cv2
16-
from cv2 import aruco
1715
import matplotlib.pyplot as plt
1816
import numpy as np
1917
import open3d as o3d
18+
from colmap_wrapper.visualization import COLMAP
2019
from PIL import Image
21-
# Own modules
2220

23-
import sys
24-
sys.path.append("C:/Users/meyerls/Documents/AIST/code/gaussian-splatting/colmap-wrapper")
25-
from colmap_wrapper.visualization.visualization import *
26-
27-
28-
def ray_cast_aruco_corners(extrinsics: np.ndarray, intrinsics: np.ndarray, corners: tuple) \
29-
-> Tuple[np.ndarray, np.ndarray]:
30-
'''
3121

22+
def ray_cast_aruco_corners(
23+
extrinsics: np.ndarray, intrinsics: np.ndarray, corners: tuple
24+
) -> Tuple[np.ndarray, np.ndarray]:
25+
"""
3226
n = x @ K^-1 @ R.T
3327
3428
:param extrinsics:
3529
:param intrinsics:
3630
:param corners:
3731
:return:
38-
'''
32+
"""
3933
R, camera_origin = extrinsics[:3, :3], extrinsics[:3, 3]
4034
aruco_corners = np.concatenate((corners[0][0], np.ones((4, 1))), axis=1)
4135
rays = aruco_corners @ np.linalg.inv(intrinsics).T @ R.T
4236
rays_norm = rays / np.linalg.norm(rays, ord=2, axis=1, keepdims=True)
4337

4438
return camera_origin, rays_norm
4539

46-
47-
def load_image(image_path: str) -> np.ndarray:
48-
"""
49-
Load Image. This takes almost 50% of the time. Would be nice if it is possible to speed up this process. Any
50-
ideas?
51-
52-
:param image_path:
53-
:return:
54-
"""
55-
return cv2.imread(image_path)#np.asarray(Image.open(image_path))
56-
57-
58-
class ArucoDetection:
59-
def __init__(self, dict_type: int = aruco.DICT_4X4_1000):
60-
"""
61-
More information on aruco parameters: https://docs.opencv.org/4.x/d1/dcd/structcv_1_1aruco_1_1DetectorParameters.html
62-
63-
@param dict_type:
64-
"""
65-
self.dict_type = dict_type
66-
self.aruco_dict = aruco.Dictionary_get(dict_type)
67-
self.aruco_parameters = aruco.DetectorParameters_create()
68-
69-
# aruco_parameters = aruco.DetectorParameters_create()
70-
# aruco_parameters.adaptiveThreshConstant = 9.0
71-
# aruco_parameters.adaptiveThreshWinSizeMax = 369
72-
# aruco_parameters.adaptiveThreshWinSizeMin = 7
73-
# aruco_parameters.adaptiveThreshWinSizeStep = 49
74-
# aruco_parameters.cornerRefinementWinSize = 9
75-
# aruco_parameters.minDistanceToBorder = 7
76-
# aruco_parameters.cornerRefinementMaxIterations = 149
77-
# aruco_parameters.minOtsuStdDev = 4.0
78-
#
79-
# aruco_parameters.minMarkerDistanceRate = 0.05
80-
# aruco_parameters.minMarkerPerimeterRate = 5
81-
# aruco_parameters.maxMarkerPerimeterRate = 10
82-
#
83-
#
84-
# aruco_parameters.polygonalApproxAccuracyRate = 0.05
85-
# aruco_parameters.minCornerDistanceRate = 0.05
86-
87-
def detect_aruco_marker(self, image: Union[np.ndarray, str]) -> Tuple[tuple, np.ndarray, np.ndarray]:
88-
return detect_aruco_marker(image=image, dict_type=self.aruco_dict, aruco_parameters=self.aruco_parameters)
89-
90-
91-
def detect_aruco_marker(image: np.ndarray, dict_type: int = aruco.DICT_4X4_1000,
92-
aruco_parameters: cv2.aruco.DetectorParameters = aruco.DetectorParameters_create()) -> Tuple[
93-
tuple, np.ndarray]:
40+
def detect_aruco_marker(
41+
image: np.ndarray,
42+
dict_type: int = cv2.aruco.DICT_4X4_100,
43+
aruco_parameters: cv2.aruco.DetectorParameters = cv2.aruco.DetectorParameters(),
44+
) -> Tuple[tuple, np.ndarray]:
9445
"""
46+
Info: https://docs.opencv.org/4.x/d5/dae/tutorial_aruco_detection.html
9547
More information on aruco parameters: https://docs.opencv.org/4.x/d1/dcd/structcv_1_1aruco_1_1DetectorParameters.html
9648
9749
@param dict_type:
9850
@param image:
9951
@param aruco_parameters:
100-
"""
101-
102-
# Info: https://docs.opencv.org/4.x/d5/dae/tutorial_aruco_detection.html
103-
aruco_dict = aruco.Dictionary_get(dict_type)
104-
aruco_parameters = aruco.DetectorParameters_create()
10552
106-
aruco_parameters.polygonalApproxAccuracyRate = 0.01
107-
aruco_parameters.minMarkerPerimeterRate = 0.1
108-
aruco_parameters.maxMarkerPerimeterRate = 4.0
109-
"""
11053
Aruco Corners
11154
11255
p1------------p2
@@ -119,64 +62,15 @@ def detect_aruco_marker(image: np.ndarray, dict_type: int = aruco.DICT_4X4_1000,
11962
:param image:
12063
:return:
12164
"""
122-
if isinstance(image, np.ndarray):
123-
pass
124-
elif isinstance(image, str):
125-
image = load_image(image_path=image)
126-
else:
127-
raise NotImplementedError
12865

66+
image = cv2.imread(image)
67+
if image is None:
68+
logging.warning(f"Failed to load image: {image}")
69+
return None, None
12970
image_size = image.shape
130-
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
131-
corners, aruco_id, rejected_img_points = aruco.detectMarkers(gray,
132-
aruco_dict,
133-
parameters=aruco_parameters)
134-
71+
aruco_dict = cv2.aruco.getPredefinedDictionary(dict_type)
72+
detector = cv2.aruco.ArucoDetector(aruco_dict, aruco_parameters)
73+
corners, aruco_id, _ = detector.detectMarkers(image)
13574
if aruco_id is None:
13675
return None, None, image_size
137-
138-
if False:
139-
if len(corners) > 0:
140-
141-
# flatten the ArUco IDs list
142-
ids = aruco_id.flatten()
143-
# loop over the detected ArUCo corners
144-
for (markerCorner, markerID) in zip(corners, ids):
145-
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
146-
147-
# extract the marker corners (which are always returned in
148-
# top-left, top-right, bottom-right, and bottom-left order)
149-
corners_plot = markerCorner.reshape((4, 2))
150-
(topLeft, topRight, bottomRight, bottomLeft) = corners_plot
151-
# convert each of the (x, y)-coordinate pairs to integers
152-
topRight = (int(topRight[0]), int(topRight[1]))
153-
bottomRight = (int(bottomRight[0]), int(bottomRight[1]))
154-
bottomLeft = (int(bottomLeft[0]), int(bottomLeft[1]))
155-
topLeft = (int(topLeft[0]), int(topLeft[1]))
156-
157-
# draw the bounding box of the ArUCo detection
158-
cv2.line(image, topLeft, topRight, (0, 255, 0), 25)
159-
cv2.line(image, topRight, bottomRight, (0, 255, 0), 25)
160-
cv2.line(image, bottomRight, bottomLeft, (0, 255, 0), 25)
161-
cv2.line(image, bottomLeft, topLeft, (0, 255, 0), 25)
162-
# compute and draw the center (x, y)-coordinates of the ArUco
163-
# marker
164-
cX = int((topLeft[0] + bottomRight[0]) / 2.0)
165-
cY = int((topLeft[1] + bottomRight[1]) / 2.0)
166-
cv2.circle(image, (cX, cY), 4, (0, 0, 255), 5)
167-
# draw the ArUco marker ID on the image
168-
cv2.putText(image, str(markerID),
169-
(topLeft[0], topLeft[1] - 15), cv2.FONT_HERSHEY_SIMPLEX,
170-
0.5, (0, 255, 0), 10)
171-
width = int(image.shape[1] * 0.3 )
172-
height = int(image.shape[0] * 0.3 )
173-
dim = (width, height)
174-
image = cv2.resize(image, dim)
175-
176-
plt.imshow(image, cmap='gray')
177-
plt.show()
178-
179-
del gray
180-
del image
181-
18276
return corners, aruco_id, image_size

0 commit comments

Comments
 (0)