Skip to content

IDLabMedia/image-lens-reproject

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

60 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Image Lens Reprojection Tool

GitHub Workflow Status GitHub license GitHub stars

What is lens-reproject?

lens-reproject is a tool to reproject images taken with a known lens to a new lens. The process unprojects every pixel coordinate back to the light ray in spherical coordinates -- with the origin set to the center of projection -- after which it projects the light ray back onto the sensor using the new lens parameters. A variety of lenses is supported:

  • Rectilinear (The default perspective projection lenses).
  • Equisolid (Fisheye)
  • Equidistant (Fisheye)

Prerequisites

On Linux systems, install libjpeg:

sudo apt install libjpeg-turbo8-dev

Build

You will need a C++ compiler and CMake. All other dependencies are included as submodules.

git clone https://github.com/IDLabMedia/image-lens-reproject.git
cd image-lens-reproject
git submodule update --init --recursive
mkdir build && cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
cmake --build . --config Release

You will find the exectable files with the required library files next to in in a bin/ subdirectory.

Updating your local copy from Git

git pull origin main
git submodule update

CLI interface

This program has two ways of being used:

  • through Blender-style JSON configuration files.
  • by manually specifying the lens characteristics on the command line.

Originally, this tool was made to convert images generated by Blender, from one lens type to another. However, as this tool had potential to be used in other contexts, where no configuration files from Blender were available, simpliy specifying which lens-type the input image has directly on the command-line was very desirable. To specify the input image lens-type directly on the command-line, use the --no-configs argument along with --i-... flags under the Input optics section. When using equirectangular panoraminc input images, the --rotation flag might prove useful.

Usage:
  ./bin/reproject [OPTION...]

 Color processing options:
      --exposure EV   Exposure compensation in stops (EV) to brigthen or 
                      darken the pictures. (default: 0.0)
      --reinhard max  Use reinhard tonemapping with given maximum value 
                      (after exposure processing) on the output images. 
                      (default: 1.0)

 Filter files options:
      --filter-prefix prefix  Only include files starting with (default: 
                              "")
      --filter-suffix suffix  Only include files ending with (default: "")

 Input optics.
   These are usually inferred by the config JSONs. When specifying
   --no-configs, lens information needs to be passed through these
   command line options options:
      --i-rectilinear focal_length,sensor_width
                                Input rectilinear images with given 
                                focal_length,sensor_width tuple.
      --i-equisolid focal_length,sensor_width,fov
                                Input equisolid images with given 
                                focal_length,sensor_width,fov tuple.
      --i-equidistant fov       Input equidistant images with given fov 
                                value.
      --i-equirectangular long_min,long_max,lat_min,lat_max (radians)
                                Input equirectangular images with given 
                                longitude min,max and latitude min,max 
                                value or 'full'.

 Input/output options:
      --input-cfg json-file     Input JSON file containing lens and camera 
                                settings of the input images.
      --output-cfg json-file    Output JSON file containing lens and camera 
                                settings of the output images.
      --no-configs width,height
                                Work without reading and writing config 
                                files. Requires you to specify the input 
                                lens through the input-optics flags 
                                (staring with -i-...) and the expected 
                                resolution of the input images here.
  -i, --input-dir file          Input directory containing images to 
                                reproject.
      --single file             A single input file to convert.
  -o, --output-dir file         Output directory to put the reprojected 
                                images.
      --exr                     Output EXR files. Color and depth.
      --png                     Output PNG files. Color only.

 Output optics options:
      --no-reproject            Do not reproject at all.
      --rectilinear focal_length,sensor_width
                                Output rectilinear images with given 
                                focal_length,sensor_width tuple.
      --equisolid focal_length,sensor_width,fov
                                Output equisolid images with given 
                                focal_length,sensor_width,fov tuple.
      --equidistant fov         Output equidistant images with given fov 
                                value.
      --equirectangular longitude_min,longitude_max,latitude_min,latitude_max
                                Output equirectangular images with given 
                                longitude min,max and latitude min,max 
                                value or 'full'.
      --rotation pan, pitch, roll (degrees)
                                Specify a rotation (default: 0.0)

 Runtime options:
      --skip-if-exists    Skip if the output file already exists.
  -j, --parallel threads  Number of parallel images to process. (default: 
                          1)
      --dry-run           Do not actually reproject images. Only produce 
                          config.
  -h, --help              Show help

 Sampling options:
  -s, --samples number          Number of samples per dimension for 
                                interpolating (default: 1)
      --nn                      Nearest neighbor interpolation
      --bl                      Bilinear interpolation
      --bc                      Bicubic interpolation (default)
      --scale percentage        Output scale, as a fraction of the input 
                                size. It is recommended to increase 
                                --samples to prevent aliassing in case you 
                                are downscaling. Eg: --scale 0.5 --samples 
                                2 or --scale 0.33334 --samples 3 or --scale 
                                0.25 --samples 4. Final dimensions are 
                                rounded towards zero. (default: 1.0)
      --output-resolution width,height
                                A fixed output resolution. Overwrites the 
                                behavior of the 'scale' parameter.

Configuration JSON

The configuration JSON files required in the input of the CLI interface are flexible. The application will read in the JSON, extract the lens information from the "camera", "resolution", and "sensor_size" keys in the JSON root object, rewrite the values of those keys to match the new settings, and finally write out the updated JSON to a new file. This way, all custom information is left untouched and it is more easy to integrate it in other pipelines and systems.

The "camera" object in the root object follows the Blender camera settings structure. This is not always the clearest, but we chose it as we work a lot with Blender and it was straightforward to export the camera and lens information straight from Blender. Next we show the different lens configuration templates for the JSON file:

rectilinear

{
  "camera": {
    "focal_length": 36.0,
    "lens_unit": "MILLIMETERS",
    "projection_matrix": [
      [ 2.0, 0.0, 0.0, 0.0 ],
      [ 0.0, 2.0, 0.0, 0.0 ],
      [ 0.0, 0.0, 0.0, 0.0 ],
      [ 0.0, 0.0, 0.0, 1.0 ]
    ],
    "type": "PERSP"
  },
  "resolution": [ 2048, 2048 ],
  "sensor_size": [ 36.0, 36.0 ]
}

(Note that more elements may be present in the root object, as the tool just ignores them, but will copy them over to the output JSON.)

equidistant

{
  "camera": {
    "type": "PANO",
    "panorama_type": "FISHEYE_EQUIDISTANT",
    "fisheye_fov": 3.1415927410125732
  },
  "resolution": [ 2048, 2048 ],
  "sensor_size": [ 36.0, 36.0 ]
}

Note: This lens is not expressed by a focal length. Instead the lens perfectly fits a circle of projection on the sensor. The equidistant lens is only specified by a field of view (fov).

equisolid

{
  "camera": {
    "type": "PANO",
    "panorama_type": "FISHEYE_EQUISOLID",
    "lens": 12.5,
    "fisheye_fov": 3.1415927410125732
  },
  "resolution": [ 2048, 2048 ],
  "sensor_size": [ 36.0, 36.0 ]
}

Note: lens is the focal length of the lens, expressed in the same unit as the sensor_size element (typically millimeters). The naming is taken from Blender.

License

See the LICENSE file.

Credits

To cite this paper:

@inproceedings{courteaux2022silvr,
 title = {{SILVR: A Synthetic Immersive Large-Volume Plenoptic Dataset}},
 author = {Courteaux, Martijn and Artois, Julie and De Pauw, Stijn and Lambert, Peter and Van Wallendael, Glenn},
 year = {2022},
 doi = {10.1145/3524273.3532890},
 publisher = {Association for Computing Machinery},
 url = {https://doi.org/10.1145/3524273.3532890},
 address = {New York, NY, USA},
 month = {jun},
 numpages = {6},
 isbn = {978-1-4503-9283-9/22/06},
 booktitle = {13th ACM Multimedia Systems Conference (MMSys '22)},
 location = {Athlone, Ireland}
}