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
// Copyright (c) 2012-2017 VideoStitch SAS
// Copyright (c) 2018 stitchEm
#include "libvideostitch/imageMergerFactory.hpp"
#include "core1/arrayImageMerger.hpp"
#include "core1/checkerboardImageMerger.hpp"
#include "core1/diffImageMerger.hpp"
#include "core1/exposureDiffImageMerger.hpp"
#include "core1/gradientImageMerger.hpp"
#include "core1/laplacianImageMerger.hpp"
#include "core1/stackImageMerger.hpp"
#include "core1/noblendImageMerger.hpp"
#include "coredepth/sphereSweepMerger.hpp"
#include "libvideostitch/logging.hpp"
#include "libvideostitch/parse.hpp"
#include <cassert>
#include <mutex>
#include <iostream>
namespace VideoStitch {
namespace Core {
const std::vector<std::string>& ImageMergerFactory::availableMergers() {
static std::vector<std::string> availableMergers;
// Lazily fill in the list of mergers. TODO: use a better, macro-based, registration pattern.
static std::mutex mutex;
{
std::unique_lock<std::mutex> lock(mutex);
if (availableMergers.empty()) {
#ifndef VS_OPENCL
availableMergers.push_back("laplacian");
#endif
availableMergers.push_back("gradient");
availableMergers.push_back("noblendv1");
availableMergers.push_back("diff");
availableMergers.push_back("exposure_diff");
availableMergers.push_back("checkerboard");
availableMergers.push_back("array");
availableMergers.push_back("stack");
availableMergers.push_back("sphere_sweep");
}
}
return availableMergers;
}
Potential<ImageMergerFactory> ImageMergerFactory::createMergerFactory(const Ptv::Value& value) {
// Make sure value is an object.
if (!Parse::checkType("ImageMergerFactory", value, Ptv::Value::OBJECT)) {
return {Origin::Stitcher, ErrType::InvalidConfiguration,
"Invalid type for 'ImageMergerFactory' configuration, expected object"};
}
std::string type;
if (Parse::populateString("ImageMergerFactory", value, "type", type, false) == Parse::PopulateResult_WrongType) {
return {Origin::Stitcher, ErrType::InvalidConfiguration,
"Invalid type for 'ImageMergerFactory' configuration, expected string"};
}
if (type == "laplacian") {
return LaplacianImageMerger::Factory::parse(value);
} else if (type == "gradient") {
return GradientImageMerger::Factory::parse(value);
} else if (type == "noblendv1") {
return Potential<ImageMergerFactory>(new NoBlendImageMerger::Factory());
} else if (type == "diff") {
return Potential<ImageMergerFactory>(new DiffImageMerger::Factory());
} else if (type == "exposure_diff") {
return Potential<ImageMergerFactory>(new ExposureDiffImageMerger::Factory());
} else if (type == "checkerboard") {
return CheckerboardImageMerger::Factory::parse(value);
} else if (type == "array") {
return Potential<ImageMergerFactory>(new ArrayImageMerger::Factory());
} else if (type == "stack") {
return Potential<ImageMergerFactory>(new StackImageMerger::Factory());
} else if (type == "sphere_sweep") {
return Potential<ImageMergerFactory>(new SphereSweepMerger::Factory());
} else {
return {Origin::Stitcher, ErrType::InvalidConfiguration, "Unknown merger type: '" + type + "'"};
}
}
Potential<PanoMerger> ImageMergerFactory::createDepth(const PanoDefinition& /* pano */) const {
return {Origin::Stitcher, ErrType::ImplementationError, "ImageMergerFactory does not implement pano merging."};
};
bool ImageMergerFactory::equal(const ImageMergerFactory& other) const { return hash() == other.hash(); }
uint32_t ImageMergerFactory::getBlockAlignment() const { return ImageMerger::CudaBlockSize; }
namespace {
/**
* A merger factory that cannot instanciate a merger. This can be useful when creating a merger without stitchers.
*/
class ImpotentMergerFactory : public ImageMergerFactory {
public:
virtual Potential<ImageMerger> create(const PanoDefinition& /*pano*/, ImageMapping& /*fromIm*/,
const ImageMerger* /*to*/, bool) const {
return Status{Origin::Stitcher, ErrType::ImplementationError, "Cannot create impotent merger"};
}
virtual ~ImpotentMergerFactory() {}
Ptv::Value* serialize() const { return NULL; }
virtual CoreVersion version() const { return Impotent; }
virtual ImageMergerFactory* clone() const { return new ImpotentMergerFactory(); }
virtual std::string hash() const { return "impotentMerger"; }
};
} // namespace
Potential<ImageMergerFactory> ImageMergerFactory::newImpotentMergerFactory() {
return Potential<ImageMergerFactory>(new ImpotentMergerFactory);
}
} // namespace Core
} // namespace VideoStitch