This program demonstrates how to use most features of the pipeline, as well as allowing use of the pipeline itself through execution.
#include <armadillo>
#include <boost/program_options.hpp>
#include <boost/filesystem.hpp>
#include <opencv2/opencv.hpp>
#include <memory>
#include <chrono>
namespace po = boost::program_options;
int main(
int argc,
char** argv)
{
bool show_images;
bool recover_illuminant;
bool recover_dichromatic;
bool process;
bool save = false;
bool keep_time;
bool save_refl;
bool nurbs;
bool filter;
bool quick_mat;
bool calc_error;
int debug;
float ill_alpha;
int ill_patch_size;
int dic_neigh_size;
int dic_gray_thres;
int mat_max_clust;
int mat_abund_num;
float resample;
float mat_temp_max;
float mat_temp_min;
float mat_cool_rate;
float mat_split_th;
std::string filename;
std::string savename;
po::options_description desc("Allowed options");
desc.add_options()
("help,h", "Convey usage information")
("file,f", po::value<std::string>(&filename)->default_value(""), "Path to input file")
("save,o", po::value<std::string>(&savename)->default_value(""), "Path to output file HSZ or HDR (.hdr, .fla, .raw etc)")
("illuminant,i", po::bool_switch(&recover_illuminant), "Perform illuminant recovery")
("dichromatic,d", po::bool_switch(&recover_dichromatic), "Perform dichromatic decompose")
("material,m", po::bool_switch(&recover_materials), "Perform material recovery")
("process,p", po::bool_switch(&process), "Perform whole processing pipeline ( -i -d -m -a)")
("show_images,s", po::bool_switch(&show_images), "Show images")
("print_timing,t", po::bool_switch(&keep_time), "Print timing information (Walltime)")
("no_nurbs,n", po::bool_switch(&nurbs), "Use NURBS when encoding HSZ")
("filter,w", po::bool_switch(&filter), "Filter image before processing")
("quick_mat,q", po::bool_switch(&quick_mat), "Use Fast material clustering method")
("reflectance", po::bool_switch(&save_refl), "Save Reflectance Cube")
("calc_error,e", po::bool_switch(&calc_error), "Calculate and print the RMS Error")
("resample,r", po::value<float>(&resample)->default_value(1.0f), "Resample the image by a factor ( 1 = None, 2 = /2, 4 = /4 etc.)")
("verbosity,v", po::value<int>(&debug)->default_value(2), "Quantity of output desired (0 = none, 5 = max)")
("ill_alpha", po::value<float>(&ill_alpha)->default_value(50.0f), "Illuminant Recovery Alpha value ( > 0, default = 50)")
("ill_patch_size", po::value<int>(&ill_patch_size)->default_value(20), "Illuminant patch size ( > 1, default = 20)")
("dic_size", po::value<int>(&dic_neigh_size)->default_value(5), "Dichromatic Neighbourhood Size ( > 0, default 5)")
("dic_gray_thres", po::value<int>(&dic_gray_thres)->default_value(2), "Dichromatic Gray Threshold ( > 0, default 2)")
("mat_max_clust", po::value<int>(&mat_max_clust)->default_value(20), "Material Recovery Max Clusters ( > 0, default 20)")
("mat_abund_num", po::value<int>(&mat_abund_num)->default_value(5), "Material Abundance per pixel ( > 1, default 5)")
("mat_temp_max", po::value<float>(&mat_temp_max)->default_value(0.02f), "Material Recovery Max Temperature ( > Min Temp, default 0.02)")
("mat_temp_min", po::value<float>(&mat_temp_min)->default_value(0.00025f),"Material Recovery Min Temperature ( < Max Temp, default 0.00025)")
("mat_cool_rate", po::value<float>(&mat_cool_rate)->default_value(0.8f), "Material Recovery Cooling Rate ( <0, default 0.8)")
("mat_split_th", po::value<float>(&mat_split_th)->default_value(-1), "Material Recovery Cluster Split Threshold ( < 0, default cos(5pi / 180))")
;
po::variables_map vm;
po::store(po::parse_command_line(argc, argv, desc), vm);
po::notify(vm);
if (vm.count("help")) {
std::cout << desc << std::endl;
return 0;
}
std::shared_ptr<scyl::input> input;
std::shared_ptr<scyl::output> output;
std::string file_extension = boost::filesystem::extension(filename);
std::string save_extension = boost::filesystem::extension(savename);
if (file_extension.compare(".hsz") == 0 ||
file_extension.compare(".HSZ") == 0)
{
input = std::make_shared<scyl::hsz_input>(filename);
std::cout << "Loaded " << filename << std::endl;
} else if (!file_extension.empty())
{
input = std::make_shared<scyl::hdr_input>(filename);
std::cout << "Loaded " << filename << std::endl;
} else
{
std::cout << "The file you have supplied for input is not supported. Try .hsz or .hdr files." << std::endl;
std::cout << desc << std::endl;
return -1;
}
if (savename != "")
{
if (save_extension.compare(".hsz") == 0 ||
save_extension.compare(".HSZ") == 0)
{
output = std::make_shared<scyl::hsz_output>();
save = true;
} else if (!save_extension.empty())
{
output = std::make_shared<scyl::hdr_output>(save_refl);
save = true;
} else
{
std::cout << "The file you have supplied for out is not supported. Try .hsz or .hdr files." << std::endl;
std::cout << desc << std::endl;
return -1;
}
}
if (save)
{
} else
{
}
if (quick_mat)
{
} else {
}
if (filter)
{
std::cout << "Filtering Image..." << std::endl;
}
if (!(resample < 1.0f + arma::Datum<float>::eps and resample > 1.0f - arma::Datum<float>::eps) and resample > 0.0f)
{
}
if (pipeline.
height() > 1500 || pipeline.
width() > 1500)
{
std::cout << "Image is very large, may take long time and a lot of memory to process" << std::endl << "Use '-r' to resample image smaller" << std::endl;
}
if (process)
{
recover_illuminant = true;
recover_dichromatic = true;
recover_materials = true;
}
std::chrono::time_point<std::chrono::system_clock> begin, end;
std::chrono::duration<float> time_ill = std::chrono::duration<float>(0);
std::chrono::duration<float> time_dic = std::chrono::duration<float>(0);
std::chrono::duration<float> time_mat = std::chrono::duration<float>(0);
begin = std::chrono::system_clock::now();
try
{
if (recover_illuminant)
{
end = std::chrono::system_clock::now();
time_ill = end - begin;
}
if (recover_dichromatic)
{
end = std::chrono::system_clock::now();
time_dic = end - begin;
}
if (recover_materials)
{
end = std::chrono::system_clock::now();
time_mat = end - begin;
}
if (save)
{
std::cout << "Saved " << savename << std::endl;
}
} catch (std::exception & e)
{
std::cout << e.what() << std::endl;
return -1;
}
if (show_images)
{
cv::Mat tmp[3];
arma::fcube
I = pipeline.
I();
cv::Mat showI;
cv::merge(tmp, 3, showI);
cv::namedWindow("I", CV_WINDOW_FREERATIO);
cv::imshow("I", showI);
try
{
std::cout <<
"Recovered Illuminant" << std::endl << pipeline.
illuminant() << std::endl;
} catch (std::exception & e) {}
try
{
tmp2.convertTo(tmp2, CV_8UC1, 255.0);
cv::Mat showM;
cv::applyColorMap(tmp2, showM, cv::COLORMAP_RAINBOW);
cv::namedWindow("Material Map", CV_WINDOW_FREERATIO);
cv::imshow("Material Map", showM);
} catch (std::exception & e) {
std::cout << e.what() << std::endl;
}
try
{
cv::namedWindow("Shading", CV_WINDOW_FREERATIO);
cv::imshow(
"Shading", showg/pipeline.
g().max());
} catch (std::exception & e) {}
cv::waitKey(0);
}
if(keep_time)
{
std::cout << ">-------------------------------------------------------<" << std::endl
<<
"Image: " << filename <<
" (" << pipeline.
height() <<
"x" << pipeline.
width() <<
"x" << pipeline.
bands() <<
")" << std::endl
<< "Illuminant Time: " << time_ill.count() << std::endl
<< "Dichromatic Time: " << time_dic.count() - time_ill.count() << std::endl
<< "Material Time: " << time_mat.count() - time_dic.count() << std::endl
<< "Total Time: " << time_mat.count() << std::endl
<< ">-------------------------------------------------------<" << std::endl;
}
if (calc_error)
{
try
{
reconstructed_I -= pipeline.
I();
float rms = arma::accu(arma::sqrt(arma::square(reconstructed_I)))/reconstructed_I.n_elem;
std::cout <<
"RMS Error: " << rms <<
" (max = " << pipeline.
I().max() <<
"), " << rms/pipeline.
I().max()*100.0 <<
"%" << std::endl;
} catch (std::exception & e) {}
}
return 0;
}