Tutorial¶
The code shown below lies in source files in `this https://github.com/abhishekbajpayee/openfv-samples`_ repository. In addition, all data used in these tutorials can be found in `this https://github.com/abhishekbajpayee/openfv-sample-data`_ repository.
Calibration Tutorial¶
This tutorial details a sample that utilizes the
multiCamCalibration
class to calibrate a set of
cameras. The source code discussed in this tutorial is in the
calibrate.cpp
file in the samples
folder in the openfv
root.
Firstly, we include the std_include.h
file. This include all the
requires standard libraries that openfv
depends on. Generally,
this will be the first line in any code that uses openfv
. As an
alternative, once can also individually include the libraries included
by this file.
#include "std_include.h"
We then proceed to include the required openfv
headers for this
sample.
#include "calibration.h"
#include "tools.h"
Here, we include the calibration.h
and tools.h
files. The
tools.h
header defines the init_logging
function that we later
call inside our main
function. We then proceed to
define the use of the cv
and std
namespaces. Alternatively,
one can call the respective functions using cv::
and std::
and
so on.
using namespace cv;
using namespace std;
Since we already have the gflags
library installed, we will
utilize the functionality it provides to make life easy for ourselves
and define some command line flags that we can pass to our final
executable to modify code behavior.
// Defining command line flags to use
DEFINE_string(path, "../temp/", "Calibration path");
DEFINE_int32(hgrid, 5, "Horizontal grid size");
DEFINE_int32(vgrid, 5, "Horizontal grid size");
DEFINE_double(gridsize, 5, "Physical grid size");
DEFINE_bool(ref, false, "Refractive flag");
DEFINE_bool(mtiff, false, "Multipage tiff flag");
DEFINE_int32(skip, 1, "Frames to skip");
DEFINE_bool(show_corners, false, "Show detected corners");
Explain flags here?
We then define a main
function and the first things we do inside
this function are - parse the command line flags and initialize
logging via the glog
library. All openfv
code generates logs
and redirects output via the glog
library. As a result, it is
recommended that this must be called prior to utilizing any openfv
code.
int main(int argc, char** argv) {
// Parsing flags
google::ParseCommandLineFlags(&argc, &argv, true);
init_logging(argc, argv);
}
We then add a few more lines of code to our main
function. We call
the multiCamCalibration
constructor using the data that
will be passed to the code through the command line flags defined
earlier and then run the calibration process. The fourth argument to
the constructor being 1
indicates that the easy or dummy mode will
be used.
// Uses dummy mode
multiCamCalibration calibration(FLAGS_path, Size(FLAGS_hgrid, FLAGS_vgrid), FLAGS_gridsize, FLAGS_ref, 1, FLAGS_mtiff, FLAGS_skip, FLAGS_show_corners);
calibration.run();
We then the last few lines to our main
function to show some
output once the code finishes running.
LOG(INFO)<<"Done!";
return 1;
The final function that we end up with looks like:
int main(int argc, char** argv) {
// Parsing flags
google::ParseCommandLineFlags(&argc, &argv, true);
init_logging(argc, argv);
// Uses dummy mode
multiCamCalibration calibration(FLAGS_path, Size(FLAGS_hgrid, FLAGS_vgrid), FLAGS_ref, 1, FLAGS_mtiff, FLAGS_skip, FLAGS_show_corners);
calibration.run();
LOG(INFO)<<"DONE!";
return 1;
}
In order to build this executable, you can navigate to the samples
directory in the openfv
root and execute the following lines at
the terminal.
$ mkdir bin
$ cd bin
$ cmake ..
$ make calibrate
You might have to specify certain include and library
directories when building the makefile
using cmake
as:
$ cmake -D CUDA_INC_DIR /path/to/cuda -D [other paths] ...
The paths that might need to be specified are:
CUDA_INC_DIR
: Path to CUDA include directory (default/usr/local/cuda/include
)PYTHON_INC_DIR
: Path to the Python include directory (default/usr/include/python2.7
)PYTHON_LIBS
: Path to Python library (default/usr/lib/libpython2.7.so
)EIGEN_INC_DIR
: Path to Eigen include directory (default/usr/include/eigen3
)OFV_INC_DIR
: Path to OpenFV include directory (exampleopenfv/include
)OFV_LIB_DIR
: Path to OpenFV libraries (exampleopenfv/bin/lib
)
You can now run the calibration code by executing:
$ ./calibrate --path /path/to/openfv-sample-data/pinhole_calibration_data/ --hgrid 6 --vgrid 5
The default values for the rest of the command line flags will be used
since the dataset in pinhole_calibration_data
is not refractive,
has physical grid size of 5 mm and contains data in jpg files. The
code will ask you to enter the center camera number and the image
number to use in order to define the origin. If
everything goes as anticipated, this should calibrate well and
write the results to an output file. The final reprojection error
should ideally be of the order of 1 or less (the lesser the better).
Refocusing Tutorial¶
This tutorial details a sample that utilizes saRefocus
to
refocus images from a camera array. The source code discussed in this
tutorial is in the refocus.cpp
file in the samples
folder in
the openfv
root.
We first include openfv.h
which includes all headers required for
an openfv
project.
#include "openfv.h"
We then define the use of the cv
and std
namespaces.
using namespace cv;
using namespace std;
Define command line variables .
DEFINE_bool(live, false, "live refocusing");
DEFINE_bool(fhelp, false, "show config file options");
DEFINE_bool(dump_stack, false, "dump stack");
DEFINE_string(save_path, "", "stack save path");
DEFINE_string(config_file, "", "config file path");
DEFINE_double(zmin, -10, "zmin");
DEFINE_double(zmax, 10, "zmax");
DEFINE_double(dz, 0.1, "dz");
DEFINE_double(thresh, 0, "thresholding level");
We define our main
function, parse command line flags and
initialize glog
logging.
int main(int argc, char** argv) {
google::ParseCommandLineFlags(&argc, &argv, true);
google::InitGoogleLogging(argv[0]);
FLAGS_logtostderr=1;
}
Next, we define a refocus_settings
variable to store the settings
from our refocus config file, and call the saRefocus
constructor.
refocus_settings settings;
parse_refocus_settings(FLAGS_config_file, settings, FLAGS_fhelp);
saRefocus refocus(settings);
We then check if the user specified for this to be a live-refocusing session, and if so whether or not a GPU is to be used in computation.
if (FLAGS_live) {
if (settings.use_gpu) {
refocus.GPUliveView();
} else {
refocus.CPUliveView();
}
}
Lastly, if the user has specified to dump_stack
, and if so we
initializeGPU
and dump the stack in accordance with the defined
command line variables.
if (FLAGS_dump_stack) {
refocus.initializeGPU();
refocus.dump_stack(FLAGS_save_path, FLAGS_zmin, FLAGS_zmax, FLAGS_dz, FLAGS_thresh, "tif");
}
Our final main
function:
int main(int argc, char** argv) {
google::ParseCommandLineFlags(&argc, &argv, true);
google::InitGoogleLogging(argv[0]);
FLAGS_logtostderr=1;
refocus_settings settings;
parse_refocus_settings(FLAGS_config_file, settings, FLAGS_fhelp);
saRefocus refocus(settings);
if (FLAGS_live) {
if (settings.use_gpu) {
refocus.GPUliveView();
} else {
refocus.CPUliveView();
}
}
if (FLAGS_dump_stack) {
refocus.initializeGPU();
refocus.dump_stack(FLAGS_save_path, FLAGS_zmin, FLAGS_zmax, FLAGS_dz, FLAGS_thresh, "tif");
}
return 1;
}
Once we compile and build this source file, we can use it as:
$ ./refocus --config_file <path to config file>
Here is a sample image of a refocused image: