Giter Site home page Giter Site logo

multical's Introduction

multical

Multi-camera calibration using one or more calibration patterns.

image image

changelog

Install

The software here is presented as a library installable from PyPi pip install multical, and installs a script of the same name multical.

Running multical application

The script named multical is the primary entry point to run the calibration application. It is a wrapper around several subscripts, namely:

usage: multical [-h] {calibrate,intrinsic,boards,show} ...

For command line parameters, check sub-command help e.g. multical calibrate --help

Input formats

The default method is to have folders named separately for each camera, with images having corresponding filenames. For example:

  - cam1
    - image01.jpg
    - image02.jpg
  - cam2
    - image01.jpg
    - image02.jpg

Camera names and image directories can be also specified by manually specifying camera names, and optionally specifying a pattern for the directory structure.

multical calibrate --camera_pattern '{camera}/extrinsic' --cameras cam1,cam2,cam3

By default the current directory is searched, it can be specified with --image_path.

Where {camera} is replaced by the camera names

  - cam1
    - intrinsic
       - image01.jpg
       - image02.jpg
    - extrinsic
       - image01.jpg
       - image02.jpg    
  - cam2
    - intrinsic
       - image01.jpg
       - image02.jpg
    - extrinsic
       - image01.jpg
       - image02.jpg    
    -cam3
    ...

A fixed number of images will be chosen for initial intrinsic calibration (increase for more accuracy at expense of time with --limit_intrinsic).

Outputs

The outputs from multical calibrate are written to the --output_path which by default is the image path unless specified. The name calibration (default) is specified by --name.

  • calibration.json - camera summary, intrinsic parameters, relative camera poses and camera rig poses

  • calibration.log - log file of the calibration history

  • calibration.detections.pkl - cached calibration pattern detections, making repeated calibrations much faster

  • calibration.pkl - serialized workspace containing all the details for visualization, resuming calibration etc.

Calibration targets

Calibration targets supported are currently, charuco boards and aprilgrid boards (as used by Kalibr). Targets are configured by a configuration file with --board and examples can be found in the source tree: example_boards.

It is a good idea to check your expectation against the configuration specified using an image before calibration multical boards --boards my_board.yaml --detect my_image.jpeg,

Visualization of output

To install the libraries needed for running visualization (qtpy, pyvistaqt principly) install the interactive option, pip install multical[interactive] - these may be installed separately depending on your preference (for example with conda).

Visualization can be run by : multical vis --workspace_file calibration.pkl

Library structure

Multical provides a convenient highlevel interface found in multical.workspace which contains most typical useage, from finding images, loading images, initial single camera calibration, board pose extraction, pose initialisation, and finally bundle adjustment optimization and data export.

It is also the best documentation for how to use lower level library features.

FAQ

How do I make a (physical) board pattern?

Here's my workflow for making board images:

multical boards --boards example_boards/charuco_16x22.yaml --paper_size A2 --pixels_mm 10 --write my_images 

Using boards:
charuco_16x22 CharucoBoard {type='charuco', aruco_dict='4X4_1000', aruco_offset=0, size=(16, 22), marker_length=0.01875, square_length=0.025, aruco_params={}}
Wrote my_images/charuco_16x22.png

Then open up images/charuco_16x22.png in gimp and print-to-file (pdf) with the margins set to zero and the paper size set to A2. Print pdf to printer or send to print shop.

Can multical calibrate intrinsic and extrinsic camera parameters together?

Yes - this is the default, the same images will be used for both intrinsic and extrinsic calibration. See below for how to do separate intrinsic and extrinsic calibration.

Can multical calibrate intrinsic parameters separately?

Yes - first calibrate separate intrinsic-only calibration (with images not needing to be corresponding), this will produce a calibration per camera in intrinsic.json.

multical intrinsic --input_path intrinsic_images

Extrinsic-only calibration can then be performed using the known intrinsic parameters with --calibration to specify a prior intrinsic calibration to use, combined with --fix_intrinsic in order to avoid adjusting those parameters.

multical calibrate --input_path extrinsic_images --calibration intrinsic_images/intrinsic.json --fix_intrinsic

How can I diagnose a bad calibration?

  • Check that the boards are detected as expected (see above section on Calibration targets), in particular make sure the dimensions are correct for the pattern (e.g. 8x6 vs. 6x8)

  • Ensure a correct camera model is being used. Note that there are currently no fisheye camera models - feel free to add one!

  • Visualize the result and check that it matches expectations - look for patterns in the errors, is it just with particular frames or cameras? Check the initialization and verify if it is a problem with detecting the pattern or if the bundle adjustment step is causing the issue.

  • Ensure input images are synchronized properly (images not captured at the same time will not calibrate well), or appropriate measures are taken to keep cameras still - for example a tripod.

How can I evaluate the accuracy of a calibration?

  • Reprojection error - this evaluates how well the models can fit the data. Low reprojection error is a good calibration if sufficient quantity and variation of input images are used. If the inputs are too few, the camera models may not be constrained enough to produce a good calibration.

  • Compare a calibration against a different image set, captured with the same cameras. Fix camera parameters with --fix_intrinsic and --fix_camera_poses and calibrate on the alternative image set:

multical calibrate --input_path alternative_images --calibration calibration.json --fix_intrinsic --fix_camera_poses

The reprojection error will be high if the camera parameters and poses don't match the alternative image set well.

Credits

Multical derives much inspiration from the CALICO application, implementing largely the algorithm as presented in the paper "Calibration of Asynchronous Camera Networks: CALICO.".

A number abstractions and ideas found in Anipose lib have been very useful, and expanded upon. Small snippets of code have been used around initialisation of relative poses which proved more robust in most cases than the least-squares method used in CALICO.

As with aniposelib, the scipy nonlinear optimizer scipy.optimize.least_squares forms the basis for the bundle adjustment algorithm in this work.

OpenCV provides many useful algorithms used heavily here, for detecting calibration boards, initialization of camera parameters and camera lens distortion models.

TODO/Incomplete parts

  • Make the buttons on the UI operational to be a complete application rather than just a visualzer
  • Extend apriltags2_ethz to pass through tag dictionaries other than the default t36h11
  • Make the error display grid on the right hand tab use the tolerance slider and adapt color depending on metric
  • Continuous time rolling shutter camera model
  • Add ability to calibrate with cameras which have no overlap (using hand-eye AX = ZB initialization method)

Author

Oliver Batchelor [email protected]

multical's People

Contributors

ardiya avatar demul avatar maara-fieldtrip avatar nznobody avatar oliver-batchelor avatar patrykterechowicz avatar shreychowdhary avatar slovak194 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

multical's Issues

example data

Hi, @saulzar :
Thank you for your good work, this is very good for multi camera calibration. Can you provide a example dataset? This will more people follow you work.

Thank you, sincerely
Chang Chen

Fisheye camera models

Hi!

Note that there are currently no fisheye camera models - feel free to add one!

I have a willingness to look into that. Will it only require modifications to multical/camera.py?

Best regards,
Alex

(-5:Bad argument) in function 'calibrateCamera'

when I run calibrate.py, it shows:
`points.corners, image_size, None, None, criteria=criteria, flags=flags)
cv2.error: OpenCV(4.5.5) 👎 error: (-5:Bad argument) in function 'calibrateCamera'

Overload resolution failed:

  • Can't parse 'imagePoints'. Sequence item with index 0 has a wrong type
  • Can't parse 'imagePoints'. Sequence item with index 0 has a wrong type`

when I run
print(np.array(points.object_points).shape

it shows:
(12,114,3)

Confused about commands running multiple cameras with multiple patterns for both intrinsic & extrinsic

Hi,

Currently, i am using 2 camera with 2 boards (different) for calibration. When i tried to calibrate the camera using following cmd

multical calibrate --boards charuco_multiple.yaml --cameras cam1 cam2 --camera_pattern 'data/{camera}'

i am getting following error.

line 15, in find_image_files
return [filename for filename in natsorted(os.listdir(filepath))
FileNotFoundError: [WinError 3] The system cannot find the path specified: ".\'data/cam1'"

My folder structure is

image

It would be great if you can help me with right cmd that i need to use to calibrate the 2 cameras (and generate intrinsic and extrinsic).

PS: i was able to to run intrisic camera calibration (could you also let me know, what cmd & folder structure needs to be used for do the extrinsic with fixed intrinsic)

Thank you in advance!!!

Problems when using multiple sets of images with multiple patterns

Hello,

I successfully ran multiple cameras with a single set of images. i.e.,

multical calibrate --cameras h0 h1 h2 h3 r05 r08 r22 r47
- cam1
     - im0.png
- cam2
     - im0.png
- cam3
     - im0.png
- cam4
     - im0.png

, where the five boards are generated from cube_10x10.yaml config. The cost converges to 5.0243e+02, the RMS is below 1, and the visualization looks good.
image

However, after I changed how the boards are placed and took multiple sets of images, things get worse. (The cameras are static.)

multical calibrate --cameras h0 h1 h2 h3 r05 r08 r22 r47
- cam1
     - im0.png
     - im1.png
- cam2
     - im0.png
     - im1.png
- cam3
     - im0.png
     - im1.png
- cam4
     - im0.png
     - im1.png

The cost is around 8e+7, and the RMS is larger than 100. The visualization does not look good.

image

However, I'm pretty sure that the detections are good. For example,
image

So it looks like that there are some problems in the optimization process, when there are multiple sets of images. How can I diagnose what's going wrong?

Best wishes,

installation on windows 10

The installation using pip fails on windows 10

The dependency "apriltags2-ethz" produce an error when using "pip install multical"

(opencv4) PS C:> pip install multical
Collecting multical
Downloading multical-0.1.2.1.tar.gz (47 kB)
|████████████████████████████████| 47 kB 378 kB/s
Requirement already satisfied: numpy in c:\virtualenvs\opencv4\lib\site-packages (from multical) (1.19.3)
Requirement already satisfied: scipy in c:\virtualenvs\opencv4\lib\site-packages (from multical) (1.4.1)
Requirement already satisfied: matplotlib in c:\virtualenvs\opencv4\lib\site-packages (from multical) (3.3.2)
Requirement already satisfied: opencv-python>=4.2.0.0 in c:\virtualenvs\opencv4\lib\site-packages (from multical) (4.4.0.44)
Requirement already satisfied: opencv-contrib-python in c:\virtualenvs\opencv4\lib\site-packages (from multical) (4.4.0.44)
Collecting natsort
Downloading natsort-7.1.1-py3-none-any.whl (35 kB)
Collecting cached-property
Downloading cached_property-1.5.2-py2.py3-none-any.whl (7.6 kB)
Collecting py-structs>=0.2.1
Downloading py-structs-0.2.3.tar.gz (6.4 kB)
ERROR: Could not find a version that satisfies the requirement apriltags2-ethz (from multical) (from versions: none)
ERROR: No matching distribution found for apriltags2-ethz (from multical)

Is apriltags2-ethz package available only for Linux?

Is it possible to use multical without apriltags2-ethz?

save board error

multical version: 0.2.0
command:
multical boards --boards example_boards/charuco_16x22.yaml --paper_size A2 --pixels_mm 10 --write_images
usage: multical [-h] {calibrate,intrinsic,boards,vis} ...
multical: error: unrecognized arguments: --write_images

Overlap area of camera

Does the extrinsic calibration work for two horizontally layout cameras with only about 15% of overlap width?

cv2.error: OpenCV(4.5.3) -1: error: (-5:Bad argument) in function 'drawMarker'

  • Update: I use opencv-python 4.1.2.30, opencv-contrib-python 4.1.2.30 and it fixed this problem, hope this helps.
    ——————————————————————————————————————————
  • Question: Which is the recommended version of opencv-python?
  • Description: I used opencv-python 4.5.3 to run the following command:
    multical boards --boards myboards.yaml --detect my_image.png
    and got an error as the title:

error: (-5:Bad argument) in function 'drawMarker'
Overload resolution failed:
Can't parse 'position'. Sequence item with index 0 has a wrong type
Can't parse 'position'. Sequence item with index 0 has a wrong type

  • Addition: I try adding the following code at line22 of display.py to fix the error:
    corner = corner.astype('int32')
    although it works, the checked result of boards got some wrong points.
    2021-10-13 16-37-41 screenShot

AttributeError: module 'numpy' has no attribute 'int'.

Hi!

Does not work with newer Numpy.

np.int was a deprecated alias for the builtin int. To avoid this error in existing code, use int by itself. Doing this will not modify any behavior and is safe. When replacing np.int, you may wish to use e.g. np.int64 or np.int 32 to specify the precision. If you wish to review your current use, check the release note link for additional information.
The aliases was originally deprecated in NumPy 1.20; for more details and guidance see the original release note at:
https://numpy.org/devdocs/release/1.20.0-notes.html#deprecations

The error appears here:
https://github.com/oliver-batchelor/multical/blob/af1fddaab43d8622c043a5d2eef56cbe74e48299/multical/board/common.py#LL16C1-L17C1

Best regards,
Alex

Error while visualising the calibration results

Im getting below error while visualising the results. Please help

home/shashireddy/.local/lib/python3.10/site-packages/pyvista/utilities/helpers.py:507: UserWarning: Points is not a float type. This can cause issues when transforming or applying filters. Casting to np.float32. Disable this by passing force_float=False.
warnings.warn(
Traceback (most recent call last):
File "/home/shashireddy/.local/bin/multical", line 8, in
sys.exit(cli())
File "/home/shashireddy/.local/lib/python3.10/site-packages/multical/app/multical.py", line 28, in cli
run_with(Multical)
File "/home/shashireddy/.local/lib/python3.10/site-packages/multical/config/arguments.py", line 73, in run_with
return program.app.execute()
File "/home/shashireddy/.local/lib/python3.10/site-packages/multical/app/multical.py", line 24, in execute
return self.command.execute()
File "/home/shashireddy/.local/lib/python3.10/site-packages/multical/app/calibrate.py", line 21, in execute
calibrate(self)
File "/home/shashireddy/.local/lib/python3.10/site-packages/multical/app/calibrate.py", line 44, in calibrate
visualize_ws(ws)
File "/home/shashireddy/.local/lib/python3.10/site-packages/multical/app/vis.py", line 32, in visualize_ws
visualizer.visualize(ws)
File "/home/shashireddy/.local/lib/python3.10/site-packages/multical/interface/visualizer.py", line 29, in visualize
vis.update_workspace(workspace)
File "/home/shashireddy/.local/lib/python3.10/site-packages/multical/interface/visualizer.py", line 206, in update_workspace
self.update_frame()
File "/home/shashireddy/.local/lib/python3.10/site-packages/multical/interface/visualizer.py", line 49, in f
return func(self, *args, **kwargs)
File "/home/shashireddy/.local/lib/python3.10/site-packages/multical/interface/visualizer.py", line 54, in f
return func(self)
File "/home/shashireddy/.local/lib/python3.10/site-packages/multical/interface/visualizer.py", line 273, in update_frame
self.update_image()
File "/home/shashireddy/.local/lib/python3.10/site-packages/multical/interface/visualizer.py", line 49, in f
return func(self, *args, **kwargs)
File "/home/shashireddy/.local/lib/python3.10/site-packages/multical/interface/visualizer.py", line 54, in f
return func(self)
File "/home/shashireddy/.local/lib/python3.10/site-packages/multical/interface/visualizer.py", line 300, in update_image
annotated_image = annotate_image(self.workspace, self.calibration,
File "/home/shashireddy/.local/lib/python3.10/site-packages/multical/interface/viewer_image.py", line 150, in annotate_image
add_reprojections(scene, detections, projected, inliers, workspace.boards, valid_boards, options)
File "/home/shashireddy/.local/lib/python3.10/site-packages/multical/interface/viewer_image.py", line 104, in add_reprojections
marker_font.setPixelSize(options.marker_size * 0.75)
TypeError: setPixelSize(self, int): argument 1 has unexpected type 'float'

3D calibration object

Are 3D calibration objects supported?
In the TODO section you wrote “Add ability to calibrate with cameras which have no overlap (using hand-eye AX = ZB initialization method)”. Does that mean I cannot calibrate my cameras with e.g. a calibration cube like shown in the Calico paper? I have a use case where the cameras have very large angles relative to each other. That means, that I cannot use a simple board-based calibration object and need a 3D calibration object. Does your implementation support that?

Board.py documentation

Hi @oliver-batchelor @ardiya , thanks for your good work on the project . Please can you provide a documentation on the methods exposed by Board.py , this is required to add custom calibration pattern. documentation about the format of the method parameters and also the format of the expected return object. Thanks

Question Regarding Parameter Notation

What is the explicit usage of the rotation matrix, intrinsics matrix, translation vector, and distortion parameters? For example, let us denote the intrinsics matrix, rotation matrix, translation vector as camera A as K, R, and t respectively. Is the proper camera matrix calculation K[R | t] or K[R^{-1} | R^{-1}t]? Furthermore, how do you transform from the world frame to another camera frame properly? Given world frame coordinates for an object, X, is the transformation to the camera frame RX + t, R(X + t), R^{-1}(X +t), etc...? Also, which distortion parameters correspond to tangential and radial distortion etc...?

Confuse about commands running multiple cameras with multiple patterns

I tried to run single camera with single calibration pattern successfully with the following command

multical calibrate --boards aprilgrid_6x6.yaml --cameras cam1 --camera_pattern 'data/{camera}'

I put my calibration image into

- data
  - cam1
     - im0.png
     - im1.png
     - im2.png
     - ...

The yaml file is

boards:
  aprilgrid_9x9:
    _type_: 'aprilgrid'
    size: [6, 6]
    tag_family: t36h11 # ['t16h5', 't25h7', 't25h9', 't36h11']
    tag_length: 0.06
    tag_spacing: 0.3

    min_rows: 2
    min_points: 12

Now I want to extend to two cameras, two patterns
I change the data folder as the following, assume in each image I have two patterns can be seen

- data
  - cam1
     - im0.png
     - im1.png
     - im2.png
     - ...
   - cam2
     - im0.png
     - im1.png
     - im2.png
     - ...     

Yaml file aprilgrid_multiple.yaml

boards:
  aprilgrid_0:
    _type_: 'aprilgrid'
    tag_length: 0.07
    tag_spacing: 0.25
    size: [6, 6]
    start_id: 0
    min_rows: 2
    min_points: 12
  aprilgrid_1:
    _type_: 'aprilgrid'
    tag_length: 0.07
    tag_spacing: 0.25
    size: [6, 6]
    start_id: 48 # Start from different ID on different board
    min_rows: 2
    min_points: 12

From the instruction in the Readme and my understanding, I should run the commands as following

multical calibrate --boards aprilgrid_multiple.yaml --cameras cam1,cam2 --camera_pattern 'data/{camera}'

However, this command shows error

....
[Errno 2] No such file or directory: './data/cam1,cam2'

Looks it tries to look for a folder names cam1,cam2 instead of cam1 and cam2. Is this a bug or do I misunderstand how to input multiple cameras?
Another question is, I am not sure how the library can distinguish two patterns in the image. I assume the start_id in the yaml file is used know different patterns but does that mean we should write an ID (like 0, 48) name on the pattern? Sorry, this question may sound naive but I am indeed not sure if it can just automatically detect two patterns and won't mix them up.
Thanks in advance

No module named 'apriltags_eth'

Hi

After pip install multical, the module 'apriltags_eth' still cannot be found. Searching 'apriltags_eth' online gives nothing suitable. Please refer to multical/board/aprtilgrid_detector.py Line 1 for more details.

Looking forward to your reply, thank you!

Unknown board type: checkerboard

assert False, f"unknown board type: {config.type}, options are (charuco | aprilgrid | checkerboard)"
AssertionError: unknown board type: checkerboard, options are (charuco | aprilgrid | checkerboard)

when running this command : multical boards --boards checkerboard_8x5.yaml --detect foldercameras/cam1/0_3256_1.jpg

ValueError: setting an array element with a sequence. The requested array has an inhomogeneous shape after 1 dimensions. The detected shape was (7,) + inhomogeneous part.

Hi, when running my calibration, I getting the following output and error. Does this mean that my calibration images aren't good enough or is there something more?

INFO - Using boards:
INFO - charuco_10x10_0 CharucoBoard {type='charuco', aruco_dict='4X4_1000', aruco_offset=0, size=(4, 6), num_ids=12, marker_length=0.12, square_length=0.15, aruco_params={'adaptiveThreshWinSizeMax': 200, 'adaptiveThreshWinSizeStep': 50}}
INFO - Found camera directories ['cam1'] with 8 matching images
INFO - Loading images..
100%|████████████████████████████████████████████| 8/8 [00:00<00:00, 197.26it/s]
INFO - Loaded 8 images
INFO - {'cam1': (1280, 1024)}
INFO - Loaded detections from ./calibration.detections.pkl
INFO - Detected point counts:
INFO - Total: 91, cameras: {'cam1': 91}, Boards: {'charuco_10x10_0': 91}
INFO - Calibrating single cameras..
Traceback (most recent call last):
File "/home/lyh/.local/bin/multical", line 8, in
sys.exit(cli())
File "/home/lyh/.local/lib/python3.8/site-packages/multical/app/multical.py", line 28, in cli
run_with(Multical)
File "/home/lyh/.local/lib/python3.8/site-packages/multical/config/arguments.py", line 73, in run_with
return program.app.execute()
File "/home/lyh/.local/lib/python3.8/site-packages/multical/app/multical.py", line 24, in execute
return self.command.execute()
File "/home/lyh/.local/lib/python3.8/site-packages/multical/app/calibrate.py", line 21, in execute
calibrate(self)
File "/home/lyh/.local/lib/python3.8/site-packages/multical/app/calibrate.py", line 37, in calibrate
initialise_with_images(ws, boards, camera_images, args.camera, args.runtime)
File "/home/lyh/.local/lib/python3.8/site-packages/multical/config/workspace.py", line 31, in initialise_with_images
ws.calibrate_single(camera_opts.distortion_model,
File "/home/lyh/.local/lib/python3.8/site-packages/multical/workspace.py", line 171, in calibrate_single
self.cameras, errs = calibrate_cameras(
File "/home/lyh/.local/lib/python3.8/site-packages/multical/camera.py", line 223, in calibrate_cameras
return transpose_lists(pool.starmap(f, zip(points, image_sizes)))
File "/usr/lib/python3.8/multiprocessing/pool.py", line 372, in starmap
return self._map_async(func, iterable, starmapstar, chunksize).get()
File "/usr/lib/python3.8/multiprocessing/pool.py", line 771, in get
raise self._value
File "/usr/lib/python3.8/multiprocessing/pool.py", line 125, in worker
result = (True, func(*args, **kwds))
File "/usr/lib/python3.8/multiprocessing/pool.py", line 51, in starmapstar
return list(itertools.starmap(args[0], args[1]))
File "/home/lyh/.local/lib/python3.8/site-packages/multical/camera.py", line 79, in calibrate
points.object_points=np.array(points.object_points, dtype=np.float32)
ValueError: setting an array element with a sequence. The requested array has an inhomogeneous shape after 1 dimensions. The detected shape was (7,) + inhomogeneous part.

KeyError: 'num_points'

Hi, when running my calibration, I getting the following output and error. Does this mean that my calibration images aren't good enough or is there something more?

INFO - Using boards:
INFO - charuco_8x10 CharucoBoard {type='charuco', aruco_dict='4X4_1000', aruco_offset=0, size=(8, 10), num_ids=40, marker_length=0.00325, square_length=0.004, aruco_params={}}
INFO - Found camera directories ['cam1', 'cam2', 'cam4'] with 55 matching images
INFO - Loading images..
100%|█████████████████████████████████████████████████████████████████████████████████| 165/165 [00:00<00:00, 1299.79it/s]
INFO - Loaded 165 images
INFO - {'cam1': (664, 510), 'cam2': (728, 544), 'cam4': (720, 540)}
INFO - Detecting boards..
100%|██████████████████████████████████████████████████████████████████████████████████| 165/165 [00:00<00:00, 707.23it/s]
INFO - Writing detection cache to ./calibration.detections.pkl
INFO - Detected point counts:
INFO - Total: 1455, cameras: {'cam1': 459, 'cam2': 560, 'cam4': 436}, Boards: {'charuco_8x10': 1455}
INFO - Calibrating single cameras..
INFO - Calibrated cam1, with RMS=0.38
INFO - Camera {'dist': array([[-0.1682,  1.0735,  0.0128, -0.007 ,  0.0496]]),
        'image_size': (664, 510),
        'intrinsic': array([[1178.1721,    0.    ,  310.0039],
              [   0.    , 1169.6104,  292.7193],
              [   0.    ,    0.    ,    1.    ]])}
INFO -
INFO - Calibrated cam2, with RMS=0.34
INFO - Camera {'dist': array([[-0.5028,  5.7458,  0.0125,  0.0042, -1.0467]]),
        'image_size': (728, 544),
        'intrinsic': array([[1709.053 ,    0.    ,  355.7551],
              [   0.    , 1688.38  ,  231.7347],
              [   0.    ,    0.    ,    1.    ]])}
INFO -
INFO - Calibrated cam4, with RMS=0.35
INFO - Camera {'dist': array([[  0.0941, -10.6645,   0.002 ,   0.0032, 131.8718]]),
        'image_size': (720, 540),
        'intrinsic': array([[1154.8022,    0.    ,  360.2282],
              [   0.    , 1150.0286,  249.2311],
              [   0.    ,    0.    ,    1.    ]])}
INFO -
INFO - Pose counts:
INFO - Total: 35, cameras: {'cam1': 10, 'cam2': 14, 'cam4': 11}, Boards: {'charuco_8x10': 35}
INFO - Overlaps by camera:
INFO - [[  0.  23.  49.]
        [ 23.   0. 105.]
        [ 49. 105.   0.]]
INFO - Selected master 2 and pairs [(2, 1), (2, 0)]
INFO - Estimate transform axis=0, pair (2, 1), inliers 4/4
INFO - RMS (frobius): 0.0212 (0.0212) (deg): 0.8584 (0.8584) (trans): 0.0039 (0.0039)
INFO - [[ 0.8263  0.2279  0.5151 -0.0936]
        [-0.0982  0.9588 -0.2667  0.0498]
        [-0.5546  0.1698  0.8146  0.1328]
        [ 0.      0.      0.      1.    ]]
INFO - Estimate transform axis=0, pair (2, 0), inliers 2/2
INFO - RMS (frobius): 0.0056 (0.0056) (deg): 0.2253 (0.2253) (trans): 0.0006 (0.0006)
INFO - [[ 0.688   0.3996  0.6058 -0.0898]
        [-0.6566  0.6984  0.285  -0.0503]
        [-0.3092 -0.5938  0.7429  0.063 ]
        [ 0.      0.      0.      1.    ]]
INFO - Overlaps by board:
INFO - [[0.]]
INFO - Selected master 0 and pairs []
/home/labuser/.local/lib/python3.8/site-packages/scipy/cluster/vq.py:136: RuntimeWarning: Some columns have standard deviation zero. The values of these columns will not change.
  warnings.warn("Some columns have standard deviation zero. "
Traceback (most recent call last):
  File "/home/labuser/.local/bin/multical", line 8, in <module>
    sys.exit(cli())
  File "/home/labuser/.local/lib/python3.8/site-packages/multical/app/multical.py", line 28, in cli
    run_with(Multical)
  File "/home/labuser/.local/lib/python3.8/site-packages/multical/config/arguments.py", line 73, in run_with
    return program.app.execute()
  File "/home/labuser/.local/lib/python3.8/site-packages/multical/app/multical.py", line 24, in execute
    return self.command.execute()
  File "/home/labuser/.local/lib/python3.8/site-packages/multical/app/calibrate.py", line 21, in execute
    calibrate(self)
  File "/home/labuser/.local/lib/python3.8/site-packages/multical/app/calibrate.py", line 37, in calibrate
    initialise_with_images(ws, boards, camera_images, args.camera, args.runtime)
  File "/home/labuser/.local/lib/python3.8/site-packages/multical/config/workspace.py", line 37, in initialise_with_images
    ws.initialise_poses(
  File "/home/labuser/.local/lib/python3.8/site-packages/multical/workspace.py", line 201, in initialise_poses
    pose_init = tables.initialise_poses(self.pose_table,
  File "/home/labuser/.local/lib/python3.8/site-packages/multical/tables.py", line 367, in initialise_poses
    times = relative_between_n(expanded, board_relative, axis=1, inv=True)
  File "/home/labuser/.local/lib/python3.8/site-packages/multical/tables.py", line 336, in relative_between_n
    return Table.stack(relative_poses)
  File "/home/labuser/.local/lib/python3.8/site-packages/structs/numpy.py", line 48, in stack
    return Table.from_structs(structs)
  File "/home/labuser/.local/lib/python3.8/site-packages/structs/numpy.py", line 31, in from_structs
    struct_lists = transpose_structs(structs)
  File "/home/labuser/.local/lib/python3.8/site-packages/structs/struct.py", line 398, in transpose_structs
    d = {key: [d[key] for d in structs] for key in elem.keys()}
  File "/home/labuser/.local/lib/python3.8/site-packages/structs/struct.py", line 398, in <dictcomp>
    d = {key: [d[key] for d in structs] for key in elem.keys()}
  File "/home/labuser/.local/lib/python3.8/site-packages/structs/struct.py", line 398, in <listcomp>
    d = {key: [d[key] for d in structs] for key in elem.keys()}
  File "/home/labuser/.local/lib/python3.8/site-packages/structs/struct.py", line 78, in __getitem__
    return self._entries[index]
KeyError: 'num_points'

3D View not rendering?

Ran the visualizer but ended up with a blank 3D View:
Calibration seems okay with logs

Function evaluations 4, initial cost 8.5464e+03, final cost 8.3858e+03, first-order optimality 1.69e+03. Adjust_outliers end: reprojection RMS=1.267 (1.994), n=10455 (10583), quantiles=[ 0.0041 0.4507 0.7859 1.2893 104.1417]

image

How to cite this repo

Hi,

We used this repo to help us calibrate and would like to cite this repo for a paper. Do you have a citation I should use?

Thanks

Board creation - pixel / mm accuracy

multical boards --boards example_boards/charuco_16x22.yaml --paper_size A2 --pixels_mm 10 --write my_images
this creates an image where the black squares are 248x248 pixel. when using gimp to create the pdf and then print it, the squares are not 25x25 mm on the paper logically. when using
multical boards --boards example_boards/charuco_16x22.yaml --paper_size A2 --pixels_mm 10 --margin_mm 0 --write my_images
the black squares are 250x250 pixel and have the correct size on paper.

after having a quick look at the code, i think the margin_mm parameters are not forcefully set to 0 when specifying a paper_size. but i did not really invest a lot of effort and thoughts into debugging. maybe you quickly have an idea, whats going on here:)

Command 'multical' not found

I install the library by pip install multical. Installation is successful and no error shows. However, I run the command multical calibrate --help in the terminal, it shows Command 'multical' not found. I tried to install again with pip install multical it shows every package is there. I am using Ubuntu20.04, not in the Conda environment

Requirement already satisfied: multical in ./.local/lib/python3.8/site-packages (0.2.0)
Requirement already satisfied: numpy-quaternion in ./.local/lib/python3.8/site-packages (from multical) (2021.11.4.15.26.3)
Requirement already satisfied: opencv-contrib-python>=4.2.0.0 in ./.local/lib/python3.8/site-packages (from multical) (4.5.5.62)
Requirement already satisfied: cached-property in ./.local/lib/python3.8/site-packages (from multical) (1.5.2)
Requirement already satisfied: natsort in ./.local/lib/python3.8/site-packages (from multical) (8.1.0)
...

Also, it would be helpful if you can provide some sample data to test the system. I tried to download the dataset in the Calico but not sure if it can be used here.

api changes in opencv-contrib-python

newer version of opencv-contrib-python do not work on marker board creation using apriltags, I had to do a

pip install "opencv-contrib-python<4.7"

to get it working

How to setup the development environment in Pycharm on windows? (ImportError: cannot import name 'open' from 'builtins' (unknown location))

In windows,
In pycharm,
I configured the project to run in anaconda env with python 3.7:

Error log:


C:\Users\Alexis\anaconda3\envs\multical_py37\python.exe C:/workspace/multical/multical/app/multical.py
Fatal Python error: init_sys_streams: can't initialize sys standard streams
Traceback (most recent call last):
  File "C:\workspace\multical\multical\io\__init__.py", line 1, in <module>
  File "C:\workspace\multical\multical\io\detections.py", line 3, in <module>
  File "C:\workspace\multical\multical\__init__.py", line 1, in <module>
  File "C:\workspace\multical\multical\board\__init__.py", line 1, in <module>
  File "C:\Users\Alexis\anaconda3\envs\multical_py37\lib\dataclasses.py", line 5, in <module>
  File "C:\Users\Alexis\anaconda3\envs\multical_py37\lib\inspect.py", line 40, in <module>
  File "C:\Users\Alexis\anaconda3\envs\multical_py37\lib\linecache.py", line 11, in <module>
  File "C:\Users\Alexis\anaconda3\envs\multical_py37\lib\tokenize.py", line 27, in <module>
ImportError: cannot import name 'open' from 'builtins' (unknown location)

360 rig calibration

Hi, example shows all cameras sees all boards at same time.

Will it work for 360rig setup?
Cameras has 10% overlap.

photo1659817100

Could you expand the calibrate targets for checkerboard?

  • Question:
    Thanks for your wonderful work, I have seen that Calibration targets supported are currently, charuco boards and aprilgrid boards (as used by Kalibr). However, I only have checkerboard. If I want to use checkerboard to calibrate my camera, what function should I add for getting the correct returned Value of instantiate_board(config)?

  • Error: unknown board type: checkerboard, options are (charuco | aprilgrid | checkerboard)"
    File "/home/mbh/multical-master/multical/board/init.py", line 73
    def instantiate_board(config): if config._type_ == "charuco": schema = OmegaConf.structured(CharucoConfig) return CharucoBoard(aruco_params=aruco_params, **merge_schema(config, schema)) elif config._type_ == "aprilgrid": schema = OmegaConf.structured(AprilConfig) return AprilGrid(**merge_schema(config, schema)) else: assert False, f"unknown board type: {config._type_}, options are (charuco | aprilgrid | checkerboard)"

Why CV_CALIB_RATIONAL_MODEL retrun 14dists?

I set CV_CALIB_RATIONAL_MODEL to calibrate camera intrinsic. It should return 8 dists, but it returned 14 dists.
"dist": [ [ 1.6882872979375039, 0.7100160805799322, 0.00010055999275340188, -0.00018035565662707703, 0.02914737855085187, 2.036165624580906, 1.2176621380356765, 0.1571804399748461, 0.001207744485796259, -7.648238339836564e-05, 9.209301693082023e-05, -2.97926602796916e-05, -0.0016266455550039238, 0.0030809749056845137 ] ]

Macos get an Error that module 'os' has no attribute 'sched_getaffinity'

Hi @saulzar

I test you multical on macos catalina, get some following Errors :

Traceback (most recent call last):
  File "/Users/bytedance/anaconda3/bin/multical", line 3, in <module>
    from multical.app import arguments
  File "/Users/bytedance/anaconda3/lib/python3.8/site-packages/multical/__init__.py", line 19, in <module>
    __all__ = import_submodules(__name__).keys()                        
  File "/Users/bytedance/anaconda3/lib/python3.8/site-packages/multical/__init__.py", line 13, in import_submodules
    return {
  File "/Users/bytedance/anaconda3/lib/python3.8/site-packages/multical/__init__.py", line 14, in <dictcomp>
    name: importlib.import_module(name)
  File "/Users/bytedance/anaconda3/lib/python3.8/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "/Users/bytedance/anaconda3/lib/python3.8/site-packages/multical/camera.py", line 213, in <module>
    def undistort_images(images, cameras, j=len(os.sched_getaffinity(0)), chunksize=4):
AttributeError: module 'os' has no attribute 'sched_getaffinity'

It seems like that the method os.sched_getaffinity is only available for linux distributions.

Is there some way to replace this funciotn ?

Dependency package version bag

1: Seems the py-structs disable the old import version

from structs.struct import struct

Not sure what the new version is. To deal with this bug, we can only install the lower py-structs version like 0.2.7

2: New opencv version (>4.7.0) for charuco board detection has changed. Use opencv version < 4.6.0.66 to solve this bug.

different camera intrinsic model

Hi, for my case, can the project support calibrate the intrinsics with different camera models? for example, one camera is with pinhole model and the other is with fisheye model?

Can't evaluate accuracy of a calibration

I performed the calibration of 3 câmeras without any problems, and now I'm trying to evaluate the accuracy of the calibration with a new set of images. Initially I followed the instructions setting the input_path as alt (the folder with new set of images), but I got the following error:

$ multical calibrate --boards charuco_16x22.yaml --input_path alt --calibration calibration.json --fix_intrinsic --fix_camera_poses
usage: multical [-h] {calibrate,intrinsic,boards,vis} ...
multical: error: unrecognized arguments: --input_path alt

So I figured the argument was wrong, once that input_path is not a listed argument: in $ multical calibrate --help.

So I tried using this command multical calibrate --boards charuco_16x22.yaml --image_path alt --calibration calibration.json --fix_intrinsic --fix_camera_poses which gave me a set of errors like these (one for each image):

Traceback (most recent call last):
  File "/home/jessica/.local/lib/python3.10/site-packages/multical/threading.py", line 21, in __call__
    result = self.__callable(*args, **kwargs)
  File "/home/jessica/.local/lib/python3.10/site-packages/multical/image/detect.py", line 14, in load_image
    assert path.isfile(filename), f"load_image: file {filename} does not exist"
AssertionError: load_image: file /alt/alt/cam0/image01.jpg does not exist

The function is looking for the images in the alt/alt/ folder, but I specified alt. In the error above, the right path would be alt/cam0/image01.jpg. It looks like a bug to me.

It seem that new version of vtk(vtk==9.2) crashes with pyqt5.

It seem that new version of vtk(vtk==9.2) crashes with pyqt5.
I have usually run the visualization script(multical vis) on Docker container and have never experienced any problem on that environment.
But recently, when I made new Docker image to update multical for my custom update on multical, the visualization script(multical vis) crashed.
multical_vis_crash_vtk9 2

So I carefully went over the version difference between the previous images and the new image, and finally figured out that the new version of vtk(vtk==9.2) is the problem!
Downgrading vtk to 9.1.0 solves the visualization crash!

The bad calibration results really frustrate me ;)

Hi oliver!
I'm using multical for intrinsic/extrinsic calibration for my camera system.
It consist of 5 cameras.
The rig of my camera system looks like this picture.

뉴비리그

뉴비리그1

When visualizing my result with multical-vis, The relative poses between cameras looks reasonable(looks similar with mechanical design), at least with the naked eye.

But when i try to validate my calibration with the method below, it always give me bad results.
Let me explain my validation method.

  1. I triangulate the marker corners with cam1, cam2 stereo pair, and cam3, cam4 stereo pair.
  2. and transform them into cam0's coordinate.
  3. As a result, I can get aligned point clouds. The point clouds from left stereo pair(cam1, cam2) are marked with red. and The point clouds from right stereo pair are marked with blue.
  4. If the calibration was successful, The red and blud point clouds must be aligned well, and must look like that they are on the same plane.

But my result, the point clouds from each stereo pair are not aligned well. they do not look like on the same plane!

뉴비리그2
The Triangulation Result.
뉴비리그3
뉴비리그4
뉴비리그5

236
cam0
236
cam1
236
cam2
236
cam3
236
cam4

And It was noted that the point clouds triangulated from center area of image look clear and planar, but the point clouds triangulated from edge area of image look very very noisy.

You can checkout my triangulation script and the sample data on my github repo
It simply just have dependencies such that "apriltags_eth", "numpy" and "pptk(Point Cloud Visualizer)". I tested it on python3.6

and I'll send you the full calibration data(images) and target configuration to your e-mail.
you can just reproduce it with

  1. "multical calibrate --cameras cam0 cam1 cam2 cam3 cam4 --image_path MY_FULL_DATA_PATH --board MY_TARGET_PATH --limit_intrinsic 1000 --limit_images 1000"
  2. and try my own validation process i describe above using my github repo
  3. you can observe bad calibration results

I carefully researched about this calibration fail case about more than 2 month. and couldn't get any improvement at all. It really frustrate me and It have been driving me mad....! please help me! oliver senpai!

Differences between json and camera param table

The relative camera pose that is described in the JSON (R and T) is not identical to the extrinsic matrix that is displayed in the camera param viewer in the GUI. What is the difference between the camera pose JSON and the extrinsic matrix? Even when I set them in the GUI to have the same reference camera, the parameters are different.

I was able to replicate the parameters JSON by taking the camera pose from the pkl file and then multiplied by the inverse of the reference camera. However, I have been unable to figure out how the extrinsic matrix is being calculated.

TypeError issue when attempting to view layer "Detected poses"

Hello,

thanks for your great work! Whenever i try viewing the "Detected poses" layer in the interface, the software crashes with the following error:

Traceback (most recent call last):
File "C:\ProgramData\Miniconda3\envs\multical2\lib\site-packages\multical\interface\visualizer.py", line 49, in f return func(self, *args, **kwargs)
File "C:\ProgramData\Miniconda3\envs\multical2\lib\site-packages\multical\interface\visualizer.py", line 54, in f return func(self)
File "C:\ProgramData\Miniconda3\envs\multical2\lib\site-packages\multical\interface\visualizer.py", line 301, in update_image
layer_name, state, options=options)
File "C:\ProgramData\Miniconda3\envs\multical2\lib\site-packages\multical\interface\viewer_image.py", line 159, in annotate_image
points = camera.project(board.points, pose.poses),
TypeError: project() takes 2 positional arguments but 3 were given

Viewing the other layers works well. Any help? @oliver-batchelor Thanks in advance!

Windows 10 Installation problem

Running python -m multicam yields:

No module named multical.main; 'multical' is a package and cannot be directly executed

Installed through pip install multical

Environment:

  • virtualenv
  • python3.8

Problem with running visualization: Could not load the Qt platform plugin "xcb" in "" even though it was found.

Hello,
I did the calibration and everything seems to work fine. However I can't get the visualization to work. I installed multical[visualization] but when I run it, I get the following error:

qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in "" even though it was found.
This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.

Available platform plugins are: eglfs, linuxfb, minimal, minimalegl, offscreen, vnc, wayland-egl, wayland, wayland-xcomposite-egl, wayland-xcomposite-glx, webgl, xcb.

I tried uninstalling and reinstalling all kind of packages but the error remains. Anybody who experienced something similar or who has an idea how I could fix this?
OS: Ubuntu 20.04.

Thank you in advance!

Detecting boards.. stuck

Hi,

I tried to run the calibration.
But the Detecting boards progress bar seem to be stuck.

Any ideas ?
Thanks

Screen Shot 2022-11-09 at 13 52 14

No points could be detected in the image

Hi,
when i try to run this project, the images I entered didn't detect any points,here are some screenshots, can someone help me with this issues, Thanks in advance!
The command which i used is :multical boards --boards example_boards/aprilgrid_9x9.yaml --detect cam0/image01.jpg

The output result which i get is:
30d74513bf8e24799b9a73653307dfe8 png

missing dependency

Does this library require PyTorch?

I got this when running the multical command

File "C:\virtualEnvs\opencv4\lib\site-packages\structs\torch.py", line 5, in <module>
    import torch
ModuleNotFoundError: No module named 'torch'

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.