summaryrefslogtreecommitdiff
path: root/merge.cc
blob: a41cfc7ba0df928c7ce38f02d1542c2a14b777f4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#include <iostream>
#include <vector>
#include "opencv2/opencv.hpp"
#include "opencv2/photo/photo.hpp"
#include "cxxopts/src/cxxopts.hpp"

using namespace std;
using namespace cv;

int
load_images(const vector<string> &files, vector<Mat> &images)
{
  for (const auto& f : files) {
    cerr << "reading " << f << endl;
    images.push_back(imread(f, 1));
    if (images.back().empty()) {
      cerr << "failed to read " << f << endl;
      return 1;
    }
  }

  return 0;
}

void
mertens_fusion(vector<Mat> &images, string output)
{
  cerr << "Mertens fusion" << endl;
  Ptr<MergeMertens> merge_mertens = createMergeMertens();
  Mat m;
  merge_mertens->process(images, m);

  cerr << "writing " << output << endl;
  imwrite(output, m * 255);
}

void
hdr(vector<Mat> &images, string output, string algorithm, string tonemap,
    vector<float> times, float gamma)
{
  cerr << "HDR (" << algorithm << "/" << tonemap << ")" << endl;

  Mat response, hdr, ldr;
  Ptr<CalibrateCRF> calibrate;
  Ptr<MergeExposures> merge;
  if (algorithm == "Debevec") {
    calibrate = createCalibrateDebevec();
    merge = createMergeDebevec();
  }
  else
  if (algorithm == "Robertson") {
    calibrate = createCalibrateRobertson();
    merge = createMergeRobertson();
  }
  calibrate->process(images, response, times);
  merge->process(images, hdr, times, response);

  Ptr<Tonemap> map;
  if (tonemap == "Durand") {
    map = createTonemapDurand(gamma);
  } else
  if (tonemap == "Drago") {
    map = createTonemapDrago(gamma);
  } else
  if (tonemap == "Reinhard") {
    map = createTonemapReinhard(gamma);
  } else
  if (tonemap == "Mantiuk") {
    map = createTonemapMantiuk(gamma);
  }
  map->process(hdr, ldr);

  cerr << "writing " << output << endl;
  imwrite(output, ldr * 255);
}


int
main (int argc, char** argv)
{
  cxxopts::Options opt(argv[0], " - Options");
  opt.add_options()
    ("f,files",     "files",                   cxxopts::value<vector<string>>())
    ("F,Mertens",   "Mertens fusion")
    ("D,debevec",   "Debevec HDR")
    ("R,robertson", "Robertson HDR")
    ("w,times",     "times for HDR",           cxxopts::value<vector<float>>())
    ("t,tonemap",   "tonemapping",             cxxopts::value<string>())
    ("g,gamma",     "gamma for HDR",           cxxopts::value<float>())
    ("o,output",    "output file",             cxxopts::value<string>())
    ("O,Output",    "another output file",     cxxopts::value<string>())
    ("p,OUTPUT",    "another output file",     cxxopts::value<string>());

  opt.parse(argc, argv);

  auto& files = opt["f"].as<vector<string>>();
  vector<Mat> images;
  auto do_fusion = opt.count("F");
  bool do_debevec_hdr = opt.count("D");
  bool do_robertson_hdr = opt.count("R");
  bool do_hdr = do_debevec_hdr||do_robertson_hdr;
  vector<float> times = opt["w"].as<vector<float>>();
  float gamma = opt["g"].as<float>();
  cout << gamma << endl;
  if (do_hdr && !opt.count("g"))
    gamma = 1.0;
  string tonemap;
  if (opt.count("t"))
    tonemap = opt["t"].as<string>();
  else
    tonemap = "Durand";
  auto& output = opt["o"].as<string>();
  auto& output1 = opt["O"].as<string>();
  auto& output2 = opt["p"].as<string>();

  if (load_images(files, images) > 0)
    return 1;

  if (do_fusion)
    mertens_fusion(images, output);

  if (do_hdr) {
    if (do_debevec_hdr)
      hdr(images, output1, "Debevec", tonemap, times, gamma);
    if (do_robertson_hdr)
      hdr(images, output2, "Robertson", tonemap, times, gamma);
  }

  return 0;
}