VR180 image converter¶
Documentation: https://vr180-convert.readthedocs.io
Source Code: https://github.com/34j/vr180-convert
Simple VR180 image converter on top of OpenCV and NumPy.
Installation¶
Install this via pip (or your favourite package manager):
pipx install vr180-convert
Usage¶
Simply run the following command to convert 2 fisheye images to a SBS equirectangular VR180 image:
v1c lr left.jpg right.jpg
left.jpg |
right.jpg |
Output |
|---|---|---|
|
|
|
If left and right image paths are the same, the image is divided into two halves (left and right, SBS) and processed as if they were separate images.
Advanced usage¶
Automatic image search¶
If one of left or right image path is a directory, the program will search for the closest image (in terms of creation time) in the other directory.
v1c lr left.jpg right_dir
v1c lr left_dir right.jpg
Since clocks on cameras may not be very accurate in some cases, it is recommended to check how quickly the clocks of the two cameras shift, and synchronize the clocks before shooting.
However, it can be adjusted by specifying --time-calib option.
v1c lr left.jpg right_dir --time-calib 1 # the clock of the right camera is 1 second faster / ahead
v1c lr left_dir right.jpg --time-calib 1 # the clock of the right camera is 1 second faster / ahead
Radius estimation¶
The radius of the non-black area of the input image is assumed by counting black pixels by default, but it would be better to specify it manually to get stable results:
v1c lr left.jpg right.jpg --radius 1000
v1c lr left.jpg right.jpg --radius max # min(width, height) / 2
Calibration¶
Rotation matching using the least-squares method can be performed by clicking corresponding points that can be regarded as infinitely far away from the camera.
Using AKAZE as a feature matcher:
v1c lr left.jpg right.jpg --automatch fm
Since matching by AKAZE involves false detections, matching points with high loss are considered outliers, and the least-squares method is repeated multiple times to remove them. Checking if the image should be swapped using feature matching might be theoretically possible but not implemented.
See Also¶
Manually specifying the corresponding points using the GUI:
v1c lr left.jpg right.jpg --automatch gui
Manually specifying the corresponding points using the CLI:
v1c lr left.jpg right.jpg --automatch "0,0;0,0;1,1;1,1" # left_x1,left_y1;right_x1,right_y1;...
Please also refer to the Documentation for mathematical details.
Anaglyph¶
--merge option (which exports as anaglyph image) can be used to check if the calibration is successful by checking if the infinitely far points are overlapped.
v1c lr left.jpg right.jpg --automatch gui --merge
Swap¶
If the camera is mounted upside down, you can simply use the --swap option without changing the transformer or other parameters:
v1c lr left.jpg right.jpg --swap
Or the image can be simply swapped using the swap command:
v1c swap rl.jpg
in case one notices that the left and right images are swapped after the conversion.
Saving match visualization¶
When using --automatch fm, the match visualization can be saved by specifying --savematch.
The match image is saved alongside the output with a .match suffix.
v1c lr left.jpg right.jpg --automatch fm --savematch
Custom conversion model¶
You can also specify the conversion model by adding Python code directly to the --transformer option:
v1c lr left.jpg right.jpg --transformer 'EquirectangularEncoder() * Euclidean3DRotator(from_rotation_vector([0, np.pi / 4, 0])) * FisheyeDecoder("equidistant")'
The expression is evaluated and used as the remapper chain, overriding the default pipeline.
Please refer to the API documentation for the available transformers and their parameters.
For from_rotation_vector, please refer to the numpy-quaternion documentation.
Single image conversion¶
To convert a single image, use v1c s instead.
Running commands for all images in a directory¶
find left_dir -type f -name '*.jpg' -exec v1c lr {} right_dir --automatch fm --radius max --time-calib 0 --out-path out \;
Help¶
For more information, please refer to the help or API documentation:
v1c --help
Usage as a library¶
For more complex transformations, it is recommended to create your own Remapper.
Note that the transformation is applied in inverse order (new[(x, y)] = old[transform(x, y)], e.g. to decode orthographic fisheye images, transform_polar should be arcsin(theta), not sin(theta).)
from typing import Any
from array_api.latest import Array
from vr180_convert.remapper.polar_roll import PolarRollRemapper
from vr180_convert.remapper.equidistant import EquirectangularEncoder
from vr180_convert.remapper.fisheye import FisheyeDecoder
class MyRemapper(PolarRollRemapper):
def transform_polar(
self, theta: Array, roll: Array, **kwargs: Any
) -> tuple[Array, Array]:
return theta**0.98 + theta**1.01, roll
transformer = EquirectangularEncoder() * MyRemapper() * FisheyeDecoder("equidistant")
Tips¶
How to determine which image is left or right¶
Left |
Right |
|
|---|---|---|
Subject Orientation |
Right |
Left |
Film Color |
\({\color{red}\text{Red}}\) |
\({\color{blue}\text{Blue}}\) |
Anaglyph Color |
\({\color{blue}\text{Blue}}\) |
\({\color{red}\text{Red}}\) |
In a SBS image, the subject is oriented toward the center.
How to edit images¶
This program cannot read RAW files. To deal with white-outs, etc., it is required to process each image with a program such as Photoshop, Lightroom, RawTherapee, Darktable, etc.
However, this is so exhaustive, so it is recommended to take the images with JPEG format with care to avoid overexposure and to match the settings of the two cameras, then convert them with this program and edit the converted images.
Example of editing in RawTherapee (Light editing)
Rank the left images in RawTherapee.
Use this program to convert the images.
Edit the converted images in RawTherapee.
Example of editing in Photoshop (Exquisite editing)
Rank the left images in RawTherapee or Lightroom.
Open left image as a Smart Object
LRaw.Add right image as a Smart Object
RRaw.Make minimal corrections just to match the exposure using
Camera Raw Filter.Make each Smart Object into Smart Objects (
L,R) again and do any image-dependent processing, such as removing the background.Make both images into a single Smart Object (
P) and process them as a whole.Export as a PNG file.
Hide the other Smart Object (
LorR) (created in step 3) in the Smart ObjectP(created in step 4) and save the Smart ObjectP, then export as a PNG file.Use this program to convert the images.
Contributors ✨¶
Thanks goes to these wonderful people (emoji key):
This project follows the all-contributors specification. Contributions of any kind welcome!
Credits¶
This package was created with Copier and the browniebroke/pypackage-template project template.
Project Info
- Changelog
- Math
- vr180_convert package
- vr180_convert.remapper package
AutoDenormalizeRemapperDenormalizeRemapperEquirectangularDecoder()EquirectangularEncoderEuclidean3DRemapperEuclidean3DRotatorFisheyeDecoder()FisheyeEncoderInverseRemapperMatchResultMultiRemapperNormalizeRemapperPerEyeRotatorPolarRollRemapperPolynomialScalerRectilinearDecoder()RectilinearEncoderRemapperBaseRemapperTransformerRotationMatchRemapperUnfitErrorZoomRemapperequidistant_from_3d()equidistant_to_3d()feature_match_points()rotation_match()rotation_match_robust()- Submodules
- vr180_convert.remapper.base module
- vr180_convert.remapper.denormalize module
- vr180_convert.remapper.equidistant module
- vr180_convert.remapper.euclidean module
- vr180_convert.remapper.feature_match module
- vr180_convert.remapper.fisheye module
- vr180_convert.remapper.inverse module
- vr180_convert.remapper.normalize module
- vr180_convert.remapper.polar_roll module
- vr180_convert.remapper.polynomial_roll module
- vr180_convert.remapper.radius module
- vr180_convert.remapper.rectilinear module
- vr180_convert.remapper.rotation_match module
- vr180_convert.remapper.transformer module
- vr180_convert.remapper.zoom module

