/kubi

a fast and flexible cubemap generator

Primary LanguagePythonMIT LicenseMIT

kubi logo

kubi is a fast and flexible cubemap generator based on libvips

Install

pip install git+https://github.com/indus/kubi.git

Requirements

Description

kubi can convert equirectangular images into a variety of common layouts. All image formats supported by vips (JPEG, PNG, TIFF, WEBP, HEIF, ...) can be used for input and output. With the DZ format of libvips it is even possible to create tiled images of the cubefaces.
When used with a glob pattern for multiple input files, kubi generates an index file once and reuses it while processing all matched images. This can lead to a significant speedup.

Usage

  • all options

kubi -h
  • basic usage

kubi [-s <size>] [-l {row,column,crossL,crossR,crossH}] srcfile [dstfile]
none row column
none row column
crossL crossR crossH
crossL crossR crossH
  • tiled cubemaps

kubi -s 2048 -co tile_size=512 -co depth=onetile -co overlap=0 -co layout=google -co suffix=.jpg[Q=75] -f r l u d f b srcfile dstfile.dz
argument explanation
-s 2048 every cubeface has an overall size of 2048px
-co tile_size=512 every cubeface gets split into tiles with a size of 512px (≙ 3 levels)
-co depth=onetile stop tiling with onetile (vips default is one pixel!)
-co overlap=0 tiles should have an overlap of 0px (vips default is one pixel!)
-co layout=google use the google folder/file layout (options are dz, zoomify, google, iiif)
-co suffix=.jpg[Q=75] tiles should be JPEG with a quality of 75
-f r l u d f b defined suffixes r(ight), l(eft), u(p), ...
srcfile the input file; could be a glob pattern
dstfile.dz the output folder name; use .dz extension for tiles

With some fiddling the file and folder structure could be made compatiple to 360° image viewers.
The above would work with Marzipano:

Marzipano.ImageUrlSource.fromString("<some_path>/dstfile_{f}/{z}/{y}/{x}.jpg");

Benchmark

system: CPU: i7-6700 CPU @ 3.40GHz, 4 cores; MEM: 64GB; OS: Win 10

single input file

input: equirectangular image with 4096x2048px
output: cubemap with a cross layout

face size 1024px 2048px 4096px
kubi 0.9s 1.6s 4.7s
py360convert 2.6s 8.6s 32.2s
any others ? - - -

single input file - tiled output

input: equirectangular image with 4096x2048px
output: cubemap as seperate tiles

face size 1024px 2048px 4096px
kubi 0.9s 1.3s 3.1s
panorama_windows.exe 1.5s 4.7s 16.9s
any others ? - - -

multiple input files

If only a few cubemaps are needed, performance is probably of minor concern. But with kubi it should also be possible to process thousands of animation frames in a reasonable time:

input: multiple equirectangular images with 4096x2048px
output: multiple cubemaps with a cross layout and a face size of 2048px

count total time time per cubemap
1 1.7s 1.7s
2 2.6s 1.3s
3 3.5s 1.2s
5 5.2s 1.0s
10 9.9s 1.0s
20 18.5s 0.9s

Transforms

In addition to regular cubemaps, two optimized mappings can be generated:

Both transforms are univariate and therefore very easy to implement. They both significantly reduce the distortion of the cubemap and thus optimize the pixel yield. However, support in other tools and libraries is rather scarce.

error ltr: regular cubemap, EAC, OTC
area error_area
distance error_distance

To ensure the correct representation of a transformed cubemap, the reverse transformation must be performed at some point. The following example shows this for the OTC transformation in a fragment shader.

//FRAGMENT SHADER for OTC

vec3 n = vNormal.xyz; // or vPosition

n /= max(max(abs(n.x),abs(n.y)),abs(n.z));
n = atan(n * tan(0.8687));

gl_FragColor = textureCube(otcSampler, n);