/*
 * Copyright (C) 2020, Inria
 * GRAPHDECO research group, https://team.inria.fr/graphdeco
 * All rights reserved.
 *
 * This software is free for non-commercial, research and evaluation use 
 * under the terms of the LICENSE.md file.
 *
 * For inquiries contact sibr@inria.fr and/or George.Drettakis@inria.fr
 */


/*!
@page howto_generate_dataset Dataset Structure and Generation

Most *Projects* take as input a *multi-view dataset*, i.e., a set of images taken using a camera (phone, DSLR, videocamera such as GoPro etc). In almost all cases we assume that a Structure-from-Motion (SfM) algorithm has been run on the input images to generate *calibrated cameras*, and most often a second Multi-View Stereo (MVS) step has been run, to generate a reconstructed 3D mesh. Optionally, we may also use dense depth maps that come from MVS.

In **SIBR** we have a ``native'' dataset format, described below, which was used traditionally for some of the original *Projects*. For most recent projects we have used the commercial tool RealityCapture for SfM/MVS, since it tends to produce the best overall reconstruction quality. In some recent projects (e.g., DeepBlending, or SemanticCars, see @ref projects), we have used *Colmap*, since the dense per-view depth maps are very useful.

As a result, **SIBR** supports two types of dataset natively:

 @li Native **SIBR** datasets, created using the tools described below, from RealityCapture or Colmap.
We provide pre-processing documentation following which you can create SIBR compatible datasets from output of these two SfM/MVS systems:
  - @subpage HowToCapreal
  - @subpage HowToColmap

 @li Native Colmap datasets: we simply create a metadata file the first time the dataset is read.

Different *Projects* often add additional information to their datasets, typically via multiple pre-processing utilities, some general, some specific to the *Project*.
Python scripts designed to process and prepare datasets are provided with each project along with instructions on how to use them in the corresponding documentation.

@section howto_generate_dataset_sibr_format Basic SIBR Dataset Structure and Generation

There are two main ways to generate a dataset for **SIBR**. The first is to use *colmap* (see @ref HowToColmap) to to SfM/MVS, and the second is using the commercial RealityCapture package (see @ref HowToCapreal).

After running <code>colmap</code> **SIBR** can read the dataset natively. In this case the dataset will just contain the <code>colmap</code> directory:
```
\dataset\
\dataset\colmap\
\dataset\colmap\sparse
\dataset\colmap\dataset.db
\dataset\colmap\stereo
\dataset\colmap\stereo\images
\dataset\colmap\stereo\sparse

```
SIBR expects camera calibration to be in <code>colmap\stereo\sparse</code>, and the MVS mesh in <code>colmap\stereo\meshed-delaunay.ply</code>.
Note that in this case, the images *do not have the same size*. Some IBR algorithms (e.g., ULR) can handle this, but others require that the input images all have the same size; this was historically the case for [Chaurasia 13], and **SIBR** handles this natively.

Specifically, we run the <code>colmap2sibr</code> script to generate an **SIBR** dataset.
The basic structure of this **SIBR** dataset is shown below, generated from colmap with texture:
\n

```
\dataset\
\dataset\colmap\
\dataset\sibr_cm\scene_metadata.txt
\dataset\sibr_cm\cameras
\dataset\sibr_cm\meshes
\dataset\sibr_cm\images
\dataset\sibr_cm\cameras\bundle.out
\dataset\sibr_cm\cameras\list_images.txt
\dataset\sibr_cm\images\{img00000000.jpg,...,img000000NN.jpg}
\dataset\sibr_cm\meshes\recon.{ply,obj}
\dataset\capreal\
\dataset\capreal\mesh.ply
\dataset\capreal\texture.png
```

\n

The native **SIBR** directory structure in <code>sibr_cm</code> is as follows. 
The <code>colmap</code> directory contains the colmap reconstruction, with the calibration, depthmap and mesh data.

The <code>capreal</code> directory contains the textured mesh generated by the conversion pipeline.

In the <code>sibr_cm</code> subdirectory:

@li The *cameras* directory contains the calibrated cameras, using the *Bundler* format by default (\ref subsecDataSetFormatsBundle).

@li The *images* directory that contains the undistorted images from the reconstruction and the list images file (\ref subsecDataSetFormatsListImg)

@li The *meshes* directory that contains a *recon.ply* file that is the 3D reconstruction of the scene 
\n


To generate a dataset after following the procedure for RealityCapture (@ref HowToCapreal), you need to perform the following steps:

@li Generate and build the solution to generate executables for preprocessing applications (unless you already have the binary distribution).
@li Go to `install\scripts`
@li Run the python script using 
```
python ibr_preprocess_rc_to_sibr.py -i original_dataset_path -o original_dataset_path\sibr_rc --bin path_to_sibr_bin 
```
@li Specifying the binaries directory is optional. While compiling cmake automatically generates settings file which is parsed by the script to set bin directory.
@li The script calls the distordCrop, cropFromCenter, and clipping_planes app executables; make sure they are up to date.
    - They crop the images to remove the black borders; the --ratio parameter to distordCrop (currently 0.2 (/.5)) sets the percentage of border which can be removed. Images that have larger black borders are removed from the dataset.
    - They also copy the meshes (ply and obj if available) and modifies the bundle.out and list_images.txt to the new values of resolution, and removes the images excluded (the numbers can be found in Dataset\\SibrData\\raw\\excluded_images.txt)
    - Next they compute the clipping planes for each camera corresponding to input images and stores them in a clipping_planes.txt file.
    - Finally, they parse all data to create a scene_metadata.txt file which holds information of the images, clipping planes etc. and is used to create the scene. This file can be manually extended.
@li *[Recommended]* If you do not want to create a copy of the dataset, you can only specify the input directory with -i option. The dataset will be generated within the input directory itself.
\n

The **SIBR** dataset will have the following structure, similar to the case above, but with <code>sibr_rc</code> instead of <code>sibr_cm</code>.

```
\dataset\
\dataset\sibr_rc\scene_metadata.txt
\dataset\sibr_rc\cameras
\dataset\sibr_rc\meshes
\dataset\sibr_rc\images
\dataset\sibr_rc\cameras\bundle.out
\dataset\sibr_rc\cameras\list_images.txt
\dataset\sibr_rc\images\{img000.jpg,...,img0NN.jpg}
\dataset\sibr_rc\meshes\recon.ply
\dataset\sibr_rc\meshes\recon.ply
\dataset\capreal\
\dataset\capreal\textured.obj
\dataset\capreal\textured.mtl
\dataset\capreal\textured_u1_v1.png
```
\n
 \subsection subsecInputDatasetFilesFormats Dataset Files and Formats
\n
 The following sections contain documentation of the various files used in the dataset. Some are inherited from other SfM/MVS solutions.
\subsection subsecMetadataFile The scene_metadata.txt file

Contains the list of images and their resolution as well as the near and far planes for each images.
\n
 \subsection subsecDataSetFormatsBundle The bundle.out file
\n
  Content: [the bundler documentation](http://www.cs.cornell.edu/~snavely/bundler/bundler-v0.4-manual.html) explain all what it contain \n
	 Description: [the output of the bundler](http://www.cs.cornell.edu/~snavely/bundler/bundler-v0.4-manual.html#S6) \n
 Bundle file format is in plain text :\n
 ~~~~~~~~~~~~~{.txt}
 # Bundle file v0.3
 <num_cameras> <num_points>   [two integers]
 <camera1>
 <camera2>
   ...
 <cameraN>
 <point1>
 <point2>
    ...
 <pointM>
 ~~~~~~~~~~~~~
 Where \<camera\> contain :
 ~~~~~~~~~~~~~{.txt}
 <f> <k1> <k2>   [the focal length, followed by two radial distortion coeffs]
 <R>             [a 3x3 matrix representing the camera rotation]
 <t>             [a 3-vector describing the camera translation]
 ~~~~~~~~~~~~~
 And where \<point\> contain :
 ~~~~~~~~~~~~~{.txt}
 <position>      [a 3-vector describing the 3D position of the point]
 <color>         [a 3-vector describing the RGB color of the point]
 <view list>     [a list of views the point is visible in]
 ~~~~~~~~~~~~~


 \subsection subsecDataSetFormatsListImg The list_images.txt file
  Content: It a list of all input images sorted by order it was taken (renamed) with their resolution \n
  Description: If you have [ImageMagick](http://www.imagemagick.org/script/command-line-options.php#format_identify_) you can do : `identify -format "%f %w %h\n" *.jpg` \n
 ~~~~~~~~~~~~~{.txt}
 <%8d.jpg> <width> <height>
 ~~~~~~~~~~~~~
 Example:
 ~~~~~~~~~~~~~{.txt}
 00000000.jpg 2256 1504
 00000001.jpg 2256 1504
 00000002.jpg 2256 1504
 ...
 00000026.jpg 2256 1504
 00000027.jpg 2256 1504
 ~~~~~~~~~~~~~
 */
