diff options
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | Makefile | 2 | ||||
-rwxr-xr-x | merge-fuse-batch | 13 | ||||
-rwxr-xr-x | merge-hdr-wrapper | 4 | ||||
-rw-r--r-- | merge.cc | 131 |
5 files changed, 150 insertions, 2 deletions
@@ -1,4 +1,4 @@ crop merge straighten - +test/ @@ -4,7 +4,7 @@ CFLAGS += `pkg-config --libs opencv` crop: crop.cc g++ $(CFLAGS) crop.cc -o crop -merge: merge.cc +merge: merge.cc cxxopts/src/cxxopts.hpp g++ -std=c++11 $(CFLAGS) merge.cc -o merge straighten: straighten.cc diff --git a/merge-fuse-batch b/merge-fuse-batch new file mode 100755 index 0000000..1f21c55 --- /dev/null +++ b/merge-fuse-batch @@ -0,0 +1,13 @@ +#!/usr/bin/env ruby + +BILDROEHRE=File.dirname(__FILE__) +DIR=ARGV[0] +i = 0 +while line = STDIN.gets + args = line.strip.split.join (" -f #{DIR}") + cmd = "#{BILDROEHRE}/merge -F -o mertens-fused-#{i}.jpg #{args}" + STDERR.write "#{cmd}\n" + `#{cmd}` + i += 1 +end + diff --git a/merge-hdr-wrapper b/merge-hdr-wrapper new file mode 100755 index 0000000..e1b8970 --- /dev/null +++ b/merge-hdr-wrapper @@ -0,0 +1,4 @@ +#!/bin/zsh -x + +exiv2 2016-10-30-15-08-38-dp2m.jpg 2>/dev/null | grep 'Exposure time' | cut -d ':' -f 2 | strips | cut -d " " -f 1 | bc -l + diff --git a/merge.cc b/merge.cc new file mode 100644 index 0000000..a41cfc7 --- /dev/null +++ b/merge.cc @@ -0,0 +1,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; +} + |