Skip to content

Commit

Permalink
Add instructions and 'double fisheye' support
Browse files Browse the repository at this point in the history
  • Loading branch information
raboof committed May 25, 2017
1 parent 4ec4689 commit 1a328d6
Show file tree
Hide file tree
Showing 6 changed files with 7,069 additions and 0 deletions.
49 changes: 49 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Dual Fisheye to Equirectangular Projection Mapping

Many '360' camera's, such as the [dokicam](http://dokicam.com/), consist of 2
fish-eye camera's.

## Why DIY?

Those camera's typically come with desktop software or apps
to manipulate the images and for example share to facebook.

It's fun to explore doing this without relying on the official software.

## Storage

The dokicam stores its photos and videos on its memory card in JPG and MP4
format, easily accessible via USB storage without even removing the card.

## Projection conversion

Those images and video's show the 'double fish-eye' nature of the device.
Services like Facebook, however require, require 306 imagery to be mapped
using the Equirectangular Projection. This can be achieved with `ffmpeg`
using 2 'mapping files' for your image type.

## Mapping generation

I did not find a suitable mapping for my camera online. However I did find
`projection.c` by Floris Sluiter which could generate such mapping files
for single-fisheye sources, and modified it to support double-fisheye.

Compile the generator code:

gcc -o projection projection.c -lm

Create mapping files for video and photo's:

./projection -x xmap_dokicam_video.pgm -y ymap_dokicam_video.pgm -h 1440 -w 2880 -r 1440 -c 2880 -b 35 -m double
./projection -x xmap_dokicam.pgm -y ymap_dokicam.pgm -h 2048 -w 4096 -r 2048 -c 4096 -b 75 -m double

## Usage

Once you have created (or downloaded) the mapping files, use them with ffmpeg:

ffmpeg -i photo.jpg -i xmap_dokicam.pgm -i ymap_dokicam.pgm -filter_complex remap out.jpg
ffmpeg -i movie.mp4 -i xmap_dokicam_video.pgm -i ymap_dokicam_video.pgm -filter_complex remap out.mp4

For images, add exif metadata to help e.g. Facebook understand this is 360:

exiftool -ProjectionType="equirectangular" out.jpg
24 changes: 24 additions & 0 deletions projection.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ typedef struct double3{

enum CameraMode {
FRONT,
DOUBLE,
FRONT235,
BACK,
UP,
Expand Down Expand Up @@ -161,6 +162,9 @@ configuration parse_options(int argc, char **argv){
else if (strcmp(optarg, "thetas") == 0)
{
po.mode = THETAS;
} else if (strcmp(optarg, "double") == 0)
{
po.mode = DOUBLE;
}
/* more else if clauses */
else /* default: */
Expand Down Expand Up @@ -188,6 +192,7 @@ configuration parse_options(int argc, char **argv){
if(verbose_flag){
switch(po.mode){
case FRONT: printf("Camera: Front proj\n"); break;
case DOUBLE: printf("Camera: Double fisheye proj\n"); break;
case FRONT235: printf("Camera: Front 235 proj\n"); break;
case DOWN: printf("Camera: Down proj\n"); break;
case SAMSUNG_GEAR_360: printf("Camera: samsung_gear_360\n"); break;
Expand Down Expand Up @@ -318,6 +323,24 @@ void gen_front_maps(configuration cfg,int** image_x,int** image_y ){
}
}

void gen_double_maps(configuration cfg, int** image_x, int** image_y) {
int x,y;
// width of a 'single' fisheye in the input, uncropped
int single_width = cfg.width / 2;
int single_cols = cfg.cols / 2;

for (y = 0; y<cfg.rows;y++){
for (x = 0; x < cfg.cols; x++){
int xcrop = x < single_cols ? single_cols + cfg.crop : cfg.crop;
int single_x = x % single_cols;
double2 o = evaluatePixel_Front((double2){((double)single_x/((double)single_cols)) * ((single_width)-(2*cfg.crop)),
((double)y/(double)cfg.rows) * ((cfg.height) -(2*cfg.crop))},
(double2){(single_width)-(2*cfg.crop), cfg.height-(2*cfg.crop)});
image_x[y][x] = (int)round(o.x)+xcrop;
image_y[y][x] = (int)round(o.y)+cfg.crop;
}
}
}

int
main (int argc, char **argv)
Expand All @@ -339,6 +362,7 @@ main (int argc, char **argv)

switch(cfg.mode){
case FRONT: gen_front_maps(cfg,image_x,image_y); break;
case DOUBLE: gen_double_maps(cfg, image_x, image_y); break;
/* case FRONT235: gen_front235_maps(cfg,image_x,image_y); break;
case DOWN: gen_down_maps(cfg,image_x,image_y); break;
case SAMSUNG_GEAR_360: gen_samsung_gear_360_maps(cfg,image_x,image_y); break;
Expand Down
2,053 changes: 2,053 additions & 0 deletions xmap_dokicam.pgm

Large diffs are not rendered by default.

1,445 changes: 1,445 additions & 0 deletions xmap_dokicam_video.pgm

Large diffs are not rendered by default.

2,053 changes: 2,053 additions & 0 deletions ymap_dokicam.pgm

Large diffs are not rendered by default.

Loading

0 comments on commit 1a328d6

Please sign in to comment.