diff --git a/.vscode/settings.json b/.vscode/settings.json index ac967806d9f..257a0d8f4cf 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,7 @@ { "C_Cpp.intelliSenseEngineFallback": "Disabled", "files.associations": { + "*.inl": "cpp", "functional": "cpp", "hash_map": "cpp", "unordered_map": "cpp", @@ -71,6 +72,8 @@ "typeinfo": "cpp", "variant": "cpp", "bit": "cpp", - "compare": "cpp" + "compare": "cpp", + "*.ipp": "cpp", + "valarray": "cpp" } } \ No newline at end of file diff --git a/examples/lytro/calibration_long.lfr b/examples/lytro/calibration_long.lfr new file mode 100644 index 00000000000..30c0b888cc2 Binary files /dev/null and b/examples/lytro/calibration_long.lfr differ diff --git a/src/libs/lightfields/nearest_integration.cpp b/src/libs/lightfields/nearest_integration.cpp index 58eb1bd904f..8dd14d2c4cd 100644 --- a/src/libs/lightfields/nearest_integration.cpp +++ b/src/libs/lightfields/nearest_integration.cpp @@ -22,29 +22,29 @@ IntegrationResult integrate(const lightfields::Samples& samples, const Imath::Ve const float widthf = width; const float heightf = height; - tbb::parallel_for( - tbb::blocked_range(samples.begin(), samples.end()), - [&](const tbb::blocked_range range) { - for(const lightfields::Samples::Sample& sample : range) { - const float target_x = (sample.xy[0] + offset * sample.uv[0]) * x_scale; - const float target_y = (sample.xy[1] + offset * sample.uv[1]) * y_scale; - - if((target_x >= 0.0f) && (target_y >= 0.0f) && (target_x < widthf) && (target_y < heightf)) { - float* color = average.ptr(floor(target_y), floor(target_x)); - uint16_t* n = norm.ptr(floor(target_y), floor(target_x)); - - if(sample.color == lightfields::Samples::kRGB) - for(int a = 0; a < 3; ++a) { - color[a] += sample.value[a]; - ++n[a]; - } - else { - color[sample.color] += sample.value[sample.color]; - ++n[sample.color]; - } - } - } - }); + const tbb::blocked_range range(samples.begin(), samples.end()); + + tbb::parallel_for(range, [&](const tbb::blocked_range range) { + for(const lightfields::Samples::Sample& sample : range) { + const float target_x = (sample.xy[0] + offset * sample.uv[0]) * x_scale; + const float target_y = (sample.xy[1] + offset * sample.uv[1]) * y_scale; + + if((target_x >= 0.0f) && (target_y >= 0.0f) && (target_x < widthf) && (target_y < heightf)) { + float* color = average.ptr(floor(target_y), floor(target_x)); + uint16_t* n = norm.ptr(floor(target_y), floor(target_x)); + + if(sample.color == lightfields::Samples::kRGB) + for(int a = 0; a < 3; ++a) { + color[a] += sample.value[a]; + ++n[a]; + } + else { + color[sample.color] += sample.value[sample.color]; + ++n[sample.color]; + } + } + } + }); tbb::parallel_for(0, average.rows, [&](int y) { for(int x = 0; x < average.cols; ++x) diff --git a/src/libs/lightfields/samples.cpp b/src/libs/lightfields/samples.cpp index ddc2d9d0708..f60d1c51c67 100644 --- a/src/libs/lightfields/samples.cpp +++ b/src/libs/lightfields/samples.cpp @@ -6,7 +6,7 @@ namespace lightfields { -Samples::Samples() { +Samples::Samples(const Imath::V2i& sensor) : m_size(sensor) { } Samples::~Samples() { @@ -65,6 +65,14 @@ Samples::const_iterator Samples::end() const { return m_samples.end(); } +Samples::iterator Samples::begin() { + return m_samples.begin(); +} + +Samples::iterator Samples::end() { + return m_samples.end(); +} + std::size_t Samples::size() const { return m_samples.size(); } @@ -160,6 +168,20 @@ Samples Samples::fromPattern(const Pattern& pattern, const cv::Mat& m) { return result; } +void Samples::resize(std::size_t size) { + m_samples.resize(size); +} + +Samples::Sample& Samples::operator[](std::size_t index) { + assert(index < m_samples.size()); + return m_samples[index]; +} + +const Samples::Sample& Samples::operator[](std::size_t index) const { + assert(index < m_samples.size()); + return m_samples[index]; +} + ///////// std::ostream& operator<<(std::ostream& out, const Samples& f) { diff --git a/src/libs/lightfields/samples.h b/src/libs/lightfields/samples.h index 56584da85b5..c596b152db1 100644 --- a/src/libs/lightfields/samples.h +++ b/src/libs/lightfields/samples.h @@ -23,7 +23,7 @@ class Samples { Imath::V3f value; ///< Sample colour value (only the valid channels are populated) }; - Samples(); + Samples(const Imath::V2i& sensorSize = Imath::V2i(0, 0)); ~Samples(); Samples(const Samples&) = default; @@ -33,10 +33,14 @@ class Samples { Samples& operator=(Samples&&) = default; using const_iterator = std::vector::const_iterator; + using iterator = std::vector::iterator; const_iterator begin() const; const_iterator end() const; + iterator begin(); + iterator end(); + std::size_t size() const; bool empty() const; @@ -49,6 +53,10 @@ class Samples { static Samples fromPattern(const Pattern& p, const cv::Mat& data); + void resize(std::size_t size); + Sample& operator[](std::size_t index); + const Sample& operator[](std::size_t index) const; + private: std::vector m_samples; Imath::V2i m_size; diff --git a/src/plugins/opencv/bspline.h b/src/plugins/opencv/bspline.h index 19267572b4b..fbc2b763508 100644 --- a/src/plugins/opencv/bspline.h +++ b/src/plugins/opencv/bspline.h @@ -10,26 +10,31 @@ namespace opencv { template class BSpline { public: - BSpline(unsigned subdiv, const std::array& min = initArray(0.0), - const std::array& max = initArray(1.0)); + explicit BSpline(const std::array& subdiv = initArray(std::size_t(0))); - void addSample(const std::array& coords, double value); - double sample(const std::array& coords) const; + void addSample(const std::array& coords, float value); + float sample(const std::array& coords) const; + + std::size_t size(unsigned dim) const; bool operator==(const BSpline& b) const; bool operator!=(const BSpline& b) const; private: - static double B(double t, unsigned k); + static float B(float t, unsigned k); template - inline void visit(const std::array& coords, const FN& fn) const; - static std::array initArray(double val); + inline void visit(const std::array& coords, const FN& fn) const; + + template + static std::array initArray(T val); - std::size_t m_subdiv; + std::array m_subdiv; std::vector> m_controls; - std::array m_min, m_max; }; +template +std::ostream& operator<<(std::ostream& out, const BSpline& spline); + } // namespace opencv } // namespace possumwood diff --git a/src/plugins/opencv/bspline.inl b/src/plugins/opencv/bspline.inl index b4b77843d7c..3c651f6e23b 100644 --- a/src/plugins/opencv/bspline.inl +++ b/src/plugins/opencv/bspline.inl @@ -1,3 +1,5 @@ +#include + #include #include "bspline.h" @@ -6,7 +8,7 @@ namespace possumwood { namespace opencv { template -double BSpline::B(double t, unsigned k) { +float BSpline::B(float t, unsigned k) { assert(t >= 0.0 && t <= 1.0); assert(k < 4); @@ -23,101 +25,170 @@ double BSpline::B(double t, unsigned k) { default: return 0.0; } - - // t = t - 0.5; - - // switch(k) { - // case 0: return std::pow(2.0 + t, 3); - // case 1: return 4.0 - 6.0*t*t - 3.0*t*t*t; - // case 2: return 4.0 - 6.0*t*t + 3.0*t*t*t; - // case 3: return std::pow(2.0 - t, 3); - - // default: assert(false); return 0.0; - // } } template -std::array BSpline::initArray(double val) { - std::array result; +template +std::array BSpline::initArray(T val) { + std::array result; result.fill(val); return result; } template -BSpline::BSpline(unsigned subdiv, const std::array& min, const std::array& max) - : m_subdiv(subdiv), m_controls(std::pow(subdiv + 3, DEGREE), std::make_pair(0.0f, 0.0f)), m_min(min), m_max(max) { - assert(subdiv > 0); +BSpline::BSpline(const std::array& subdiv) : m_subdiv(subdiv) { + std::size_t controlCount = 1, baseCount = 1; + for(unsigned d = 0; d < DEGREE; ++d) { + controlCount *= subdiv[d] + 3; + baseCount *= subdiv[d]; + } + + if(baseCount > 0) { + m_controls.reserve(controlCount); + m_controls.resize(controlCount, std::make_pair(0.0f, 0.0f)); + } } +namespace { + +template +struct Visitor { + std::array b_coeffs; + std::array offsets; + std::array subdiv; + FN fn; +}; + +template +struct Visit { + static void visit(const VISITOR& visitor, std::size_t index = 0, float weight = 1.0f) { + index = index * (visitor.subdiv[DIM] + 3) + visitor.offsets[DIM]; + for(std::size_t a = 0; a < 4; ++a) + Visit::visit(visitor, index + a, visitor.b_coeffs[DIM * 4 + a] * weight); + } +}; + +template +struct Visit { + static void visit(const VISITOR& visitor, std::size_t index, float weight) { + index = index * (visitor.subdiv[0] + 3) + visitor.offsets[0]; + for(std::size_t a = 0; a < 4; ++a) + visitor.fn(index + a, weight * visitor.b_coeffs[a]); + } +}; + +} // namespace + template template -void BSpline::visit(const std::array& _coords, const FN& fn) const { - std::array coords = _coords; - std::array offset; +void BSpline::visit(const std::array& _coords, const FN& fn) const { + Visitor data; + + std::array coords = _coords; + data.subdiv = m_subdiv; + data.fn = fn; for(unsigned d = 0; d < DEGREE; ++d) { - coords[d] = (coords[d] - m_min[d]) / (m_max[d] - m_min[d]); + coords[d] += 0.5f; - if(coords[d] < 0.0 || coords[d] > 1.0) { + assert(coords[d] >= 0.0f); + assert(floor(coords[d]) >= 0.0f); + + data.offsets[d] = floor(coords[d]); + + if(data.offsets[d] > m_subdiv[d]) { std::stringstream ss; - ss << "Coordinate #" << d << " out of range - " << _coords[d] << " (expected between " << m_min[d] - << " and " << m_max[d] << ")"; + ss << "Coordinate #" << d << " out of range - " << (_coords[d] - 0.5f) << " (expected between 0.0 and " + << (m_subdiv[d]) << ")"; throw std::runtime_error(ss.str()); } - coords[d] *= (double)m_subdiv; + coords[d] = coords[d] - data.offsets[d]; - const double rounded = std::min(floor(coords[d]), (double)(m_subdiv - 1)); + assert(coords[d] >= 0.0f); + assert(coords[d] < 1.0f); - offset[d] = rounded; - coords[d] = coords[d] - rounded; + assert(data.offsets[d] < m_subdiv[d]); } - const unsigned end = pow(4, DEGREE); - for(unsigned i = 0; i < end; ++i) { - double weight = 1.0; - unsigned j = i; - std::size_t index = 0; + // precompute per-dim b-spline coeficients + for(unsigned d = 0; d < DEGREE; ++d) + for(unsigned a = 0; a < 4; ++a) + data.b_coeffs[d * 4 + a] = B(coords[d], a); - for(unsigned d = 0; d < DEGREE; ++d) { - weight *= B(coords[d], j % 4); - index = index * m_subdiv + j % 4 + offset[d]; + // evaluate the visitor + Visit, DEGREE - 1>::visit(data); +} - j /= 4; - } - assert(index < m_controls.size()); +namespace { - fn(index, weight); +struct AddSample { + std::vector>* m_controls; + float m_value; + + void operator()(std::size_t index, float weight) const { + assert(index < m_controls->size()); + (*m_controls)[index].first += weight * m_value; + (*m_controls)[index].second += weight; } -} +}; + +struct Sample { + const std::vector>* m_controls; + float* m_result; + + void operator()(std::size_t index, float weight) const { + assert(index < m_controls->size()); + + if((*m_controls)[index].second > 0.0f) + (*m_result) += (*m_controls)[index].first / (*m_controls)[index].second * weight; + } +}; + +} // namespace template -void BSpline::addSample(const std::array& coords, double value) { - visit(coords, [&](unsigned index, double weight) { - m_controls[index].first += weight * value; - m_controls[index].second += weight; - }); +void BSpline::addSample(const std::array& coords, float value) { + assert(!m_controls.empty()); + + AddSample add{&m_controls, value}; + visit(coords, add); } template -double BSpline::sample(const std::array& coords) const { - double result = 0; - visit(coords, [&](unsigned index, double weight) { - if(m_controls[index].second > 0.0) - result += m_controls[index].first / m_controls[index].second * weight; - }); +float BSpline::sample(const std::array& coords) const { + if(m_controls.empty()) + return 0.0f; + + float result = 0; + Sample smp{&m_controls, &result}; + visit(coords, smp); + + assert(std::isfinite(result)); return result; } +template +std::size_t BSpline::size(unsigned dim) const { + assert(dim < DEGREE); + return m_subdiv[dim]; +} + template bool BSpline::operator==(const BSpline& b) const { - return m_subdiv == b.m_subdiv && m_controls == b.m_controls && m_min == b.m_min && m_max == b.m_max; + return m_subdiv == b.m_subdiv && m_controls == b.m_controls; } template bool BSpline::operator!=(const BSpline& b) const { - return m_subdiv != b.m_subdiv || m_controls != b.m_controls || m_min != b.m_min || m_max != b.m_max; + return m_subdiv != b.m_subdiv || m_controls != b.m_controls; +} + +template +std::ostream& operator<<(std::ostream& out, const BSpline& spline) { + out << "B-Spline, degree=" << DEGREE; + return out; } } // namespace opencv diff --git a/src/plugins/opencv/bspline_hierarchy.cpp b/src/plugins/opencv/bspline_hierarchy.cpp index b7c6dfe9aae..fcd276960db 100644 --- a/src/plugins/opencv/bspline_hierarchy.cpp +++ b/src/plugins/opencv/bspline_hierarchy.cpp @@ -8,7 +8,7 @@ namespace opencv { BSplineHierarchy::BSplineHierarchy(std::size_t level_count, std::size_t level_offset) { std::size_t level = pow(2, level_offset); for(std::size_t i = 0; i < level_count; ++i) { - m_levels.push_back(BSpline<2>(level)); + m_levels.push_back(BSpline<2>(std::array{{level, level}})); level *= 2; } } @@ -18,10 +18,10 @@ BSpline<2>& BSplineHierarchy::level(std::size_t level) { return m_levels[level]; } -double BSplineHierarchy::sample(double x, double y) const { - double result = 0; +float BSplineHierarchy::sample(float x, float y) const { + float result = 0; for(auto& l : m_levels) - result += l.sample({x, y}); + result += l.sample({x * float(l.size(0)), y * float(l.size(1))}); return result; } diff --git a/src/plugins/opencv/bspline_hierarchy.h b/src/plugins/opencv/bspline_hierarchy.h index b3df2f99164..d9ceff3c0f9 100644 --- a/src/plugins/opencv/bspline_hierarchy.h +++ b/src/plugins/opencv/bspline_hierarchy.h @@ -11,7 +11,7 @@ class BSplineHierarchy { BSpline<2>& level(std::size_t level); - double sample(double x, double y) const; + float sample(float x, float y) const; private: std::vector> m_levels; diff --git a/src/plugins/opencv/datatypes/bspline.h b/src/plugins/opencv/datatypes/bspline.h new file mode 100644 index 00000000000..007e2b95249 --- /dev/null +++ b/src/plugins/opencv/datatypes/bspline.h @@ -0,0 +1,30 @@ +#pragma once + +#include + +#include + +#include "actions/traits.h" + +#include "opencv/bspline.h" + +namespace possumwood { + +template +struct Traits, 3>> { + static constexpr std::array colour() { + return std::array{{0, 1, 0}}; + } +}; + +namespace opencv { + +template +std::ostream& operator<<(std::ostream& out, const std::array, 3>&) { + out << "spline data"; + return out; +} + +} // namespace opencv + +} // namespace possumwood diff --git a/src/plugins/opencv/lightfield_vignetting.cpp b/src/plugins/opencv/lightfield_vignetting.cpp deleted file mode 100644 index b7dc0251c03..00000000000 --- a/src/plugins/opencv/lightfield_vignetting.cpp +++ /dev/null @@ -1,55 +0,0 @@ -#include "lightfield_vignetting.h" - -#include - -#include "bspline.inl" - -namespace possumwood { -namespace opencv { - -LightfieldVignetting::LightfieldVignetting() : m_bspline(1, {{0, 0, -1, -1}}, {{1, 1, 1, 1}}) { - m_bspline.addSample({{0.5, 0.5, 0, 0}}, 1.0f); -} - -LightfieldVignetting::LightfieldVignetting(std::size_t subdiv, const lightfields::Pattern& pattern, - const cv::Mat& image) - : - - m_bspline(subdiv, {{0, 0, -1, -1}}, {{1, 1, 1, 1}}) { - if(image.rows != pattern.sensorResolution()[1] || image.cols != pattern.sensorResolution()[0]) - throw std::runtime_error("Pattern and image resolution doesn't match!"); - - tbb::parallel_for(0, image.rows, [&](int y) { - for(int x = 0; x < image.cols; ++x) { - const lightfields::Pattern::Sample& coord = pattern.sample(Imath::V2i{x, y}); - - const double uv_magnitude_2 = coord.offset[0] * coord.offset[0] + coord.offset[1] * coord.offset[1]; - if(uv_magnitude_2 < 1.0) { - const double xf = (double)x / (double)(image.cols - 1); - const double yf = (double)y / (double)(image.rows - 1); - - m_bspline.addSample({{xf, yf, coord.offset[0], coord.offset[1]}}, image.at(y, x)); - } - } - }); -} - -double LightfieldVignetting::sample(const cv::Vec4f& coord) const { - return m_bspline.sample({{coord[0], coord[1], coord[2], coord[3]}}); -} - -bool LightfieldVignetting::operator==(const LightfieldVignetting& f) const { - return m_bspline == f.m_bspline; -} - -bool LightfieldVignetting::operator!=(const LightfieldVignetting& f) const { - return m_bspline != f.m_bspline; -} - -std::ostream& operator<<(std::ostream& out, const LightfieldVignetting& f) { - out << "(lightfield vigentting data)"; - return out; -} - -} // namespace opencv -} // namespace possumwood diff --git a/src/plugins/opencv/lightfield_vignetting.h b/src/plugins/opencv/lightfield_vignetting.h deleted file mode 100644 index 968876cca47..00000000000 --- a/src/plugins/opencv/lightfield_vignetting.h +++ /dev/null @@ -1,40 +0,0 @@ -#pragma once - -#include - -#include -#include -#include - -#include "bspline.h" -#include "lightfields.h" - -namespace possumwood { -namespace opencv { - -class LightfieldVignetting { - public: - LightfieldVignetting(); - LightfieldVignetting(std::size_t subdiv, const lightfields::Pattern& pattern, const cv::Mat& image); - - double sample(const cv::Vec4f& coord) const; - - bool operator==(const LightfieldVignetting& f) const; - bool operator!=(const LightfieldVignetting& f) const; - - private: - BSpline<4> m_bspline; -}; - -std::ostream& operator<<(std::ostream& out, const LightfieldVignetting& f); - -} // namespace opencv - -template <> -struct Traits { - static constexpr std::array colour() { - return std::array{{1, 0.5, 0}}; - } -}; - -} // namespace possumwood diff --git a/src/plugins/opencv/nodes/lightfields/bspline_to_sequence.cpp b/src/plugins/opencv/nodes/lightfields/bspline_to_sequence.cpp new file mode 100644 index 00000000000..99591390982 --- /dev/null +++ b/src/plugins/opencv/nodes/lightfields/bspline_to_sequence.cpp @@ -0,0 +1,85 @@ +#include + +#include +#include + +#include + +#include "datatypes/bspline.h" + +#include "bspline.inl" +#include "sequence.h" + +namespace { + +dependency_graph::InAttr, 3>> a_bspline; +dependency_graph::InAttr a_xyResolution, a_uvResolution; +dependency_graph::OutAttr a_sequence; + +dependency_graph::State compute(dependency_graph::Values& data) { + const Imath::V2i& xy_res = data.get(a_xyResolution); + const Imath::V2i& uv_res = data.get(a_uvResolution); + + if(uv_res.x < 1 || uv_res.y < 1) + throw std::runtime_error("UV resolution needs to be >= 1"); + + const std::array, 3>& bspline = data.get(a_bspline); + + possumwood::opencv::Sequence seq; + + tbb::parallel_for(0, uv_res.y, [&](int v) { + tbb::parallel_for(0, uv_res.x, [&](int u) { + Imath::V2f uv; + if(uv_res.x > 1) + uv.x = float(u) / (uv_res.x - 1) * float(bspline[0].size(2) - 1); + else + uv.x = float(bspline[0].size(2) - 1) / 2.0f; + + if(uv_res.y > 1) + uv.y = float(v) / (uv_res.y - 1) * float(bspline[0].size(3) - 1); + else + uv.y = float(bspline[0].size(3) - 1) / 2.0f; + + Imath::V2f xy_scale = + Imath::V2f(bspline[0].size(0) - 1, bspline[0].size(1) - 1) / Imath::V2f(data.get(a_xyResolution)); + + cv::Mat m = cv::Mat::zeros(xy_res.y, xy_res.x, CV_32FC3); + + tbb::parallel_for( + tbb::blocked_range2d(0, xy_res.y, 0, xy_res.x), [&](const tbb::blocked_range2d& range) { + for(int y = range.rows().begin(); y != range.rows().end(); ++y) + for(int x = range.cols().begin(); x != range.cols().end(); ++x) { + float* pixel = m.ptr(y, x); + + for(int c = 0; c < 3; ++c) + pixel[c] = bspline[c].sample( + std::array{{(float)x * xy_scale.x, (float)y * xy_scale.y, uv.x, uv.y}}); + } + }); + + seq(u - uv_res.x / 2, v - uv_res.y / 2) = std::move(m); + }); + }); + + data.set(a_sequence, seq); + + return dependency_graph::State(); +} + +void init(possumwood::Metadata& meta) { + meta.addAttribute(a_bspline, "bspline", std::array, 3>(), + possumwood::AttrFlags::kVertical); + meta.addAttribute(a_xyResolution, "xy_resolution", Imath::V2i(100, 100)); + meta.addAttribute(a_uvResolution, "uv_resolution", Imath::V2i(5, 5)); + meta.addAttribute(a_sequence, "sequence", possumwood::opencv::Sequence()); + + meta.addInfluence(a_bspline, a_sequence); + meta.addInfluence(a_xyResolution, a_sequence); + meta.addInfluence(a_uvResolution, a_sequence); + + meta.setCompute(compute); +} + +possumwood::NodeImplementation s_impl("opencv/lightfields/bspline_to_sequence", init); + +} // namespace diff --git a/src/plugins/opencv/nodes/lightfields/integrate_bezier.cpp b/src/plugins/opencv/nodes/lightfields/integrate_bezier.cpp index 5257edbe0ab..c5eb4357725 100644 --- a/src/plugins/opencv/nodes/lightfields/integrate_bezier.cpp +++ b/src/plugins/opencv/nodes/lightfields/integrate_bezier.cpp @@ -21,7 +21,7 @@ dependency_graph::InAttr a_levels, a_offset; dependency_graph::OutAttr a_out; struct Sample { - Imath::V2d target; + Imath::V2f target; float value; }; @@ -37,11 +37,14 @@ dependency_graph::State compute(dependency_graph::Values& data) { std::vector cache[3]; for(auto s : samples) { - if(s.color == lightfields::Samples::kRGB) - for(int c = 0; c < 3; ++c) - cache[c].push_back(Sample{Imath::V2f(s.xy[0] * x_scale, s.xy[1] * y_scale), s.value[c]}); - else - cache[s.color].push_back(Sample{Imath::V2f(s.xy[0] * x_scale, s.xy[1] * y_scale), s.value[s.color]}); + const Imath::V2f pos(s.xy[0] * x_scale, s.xy[1] * y_scale); + if(pos.x >= 0.0f && pos.x <= 1.0f && pos.y >= 0.0f && pos.y <= 1.0f) { + if(s.color == lightfields::Samples::kRGB) + for(int c = 0; c < 3; ++c) + cache[c].push_back(Sample{pos, s.value[c]}); + else + cache[s.color].push_back(Sample{pos, s.value[s.color]}); + } } const std::size_t levels = data.get(a_levels); @@ -58,13 +61,19 @@ dependency_graph::State compute(dependency_graph::Values& data) { tbb::parallel_for(std::size_t(0), cache[c].size(), [&](std::size_t a) { auto& s = cache[c][a]; - spline.addSample({{s.target[0], s.target[1]}}, s.value); + + std::array pos; + pos[0] = s.target[0] * float(spline.size(0)); + pos[1] = s.target[1] * float(spline.size(1)); + + spline.addSample(pos, s.value); }); if(a < levels - 1) tbb::parallel_for(std::size_t(0), cache[c].size(), [&](std::size_t a) { auto& s = cache[c][a]; - s.value -= spline.sample({{s.target[0], s.target[1]}}); + s.value -= + spline.sample({{s.target[0] * float(spline.size(0)), s.target[1] * float(spline.size(1))}}); }); } } @@ -81,7 +90,7 @@ dependency_graph::State compute(dependency_graph::Values& data) { data.set(a_out, possumwood::opencv::Frame(mat)); return dependency_graph::State(); -} +} // namespace void init(possumwood::Metadata& meta) { meta.addAttribute(a_samples, "samples", lightfields::Samples(), possumwood::AttrFlags::kVertical); diff --git a/src/plugins/opencv/nodes/lightfields/integrate_mosaic.cpp b/src/plugins/opencv/nodes/lightfields/integrate_mosaic.cpp index 6c7e7e250b0..6bd3a286592 100644 --- a/src/plugins/opencv/nodes/lightfields/integrate_mosaic.cpp +++ b/src/plugins/opencv/nodes/lightfields/integrate_mosaic.cpp @@ -39,39 +39,39 @@ dependency_graph::State compute(dependency_graph::Values& data) { norms.push_back(cv::Mat::zeros(height, width, CV_16UC3)); } - tbb::parallel_for( - tbb::blocked_range(samples.begin(), samples.end()), - [&](const tbb::blocked_range range) { - for(const lightfields::Samples::Sample& sample : range) { - const double uv_magnitude_2 = sample.uv[0] * sample.uv[0] + sample.uv[1] * sample.uv[1]; - if(uv_magnitude_2 < 1.0) { - float target_x = sample.xy[0] / (float)samples.sensorSize()[0] * (float)width; - float target_y = sample.xy[1] / (float)samples.sensorSize()[1] * (float)height; - - target_x = std::min(target_x, (float)(width - 1)); - target_y = std::min(target_y, (float)(height - 1)); - - target_x = std::max(target_x, 0.0f); - target_y = std::max(target_y, 0.0f); - - int index_x = floor((sample.uv[0] + 1.0) / 2.0 * (float)elements); - int index_y = floor((sample.uv[1] + 1.0) / 2.0 * (float)elements); - - float* color = mats[index_x + elements * index_y].ptr(floor(target_y), floor(target_x)); - uint16_t* n = norms[index_x + elements * index_y].ptr(floor(target_y), floor(target_x)); - - if(sample.color == lightfields::Samples::kRGB) - for(int c = 0; c < 3; ++c) { - color[c] += sample.value[c]; - ++n[c]; - } - else { - color[sample.color] += sample.value[sample.color]; - ++n[sample.color]; - } - } - } - }); + const tbb::blocked_range range(samples.begin(), samples.end()); + + tbb::parallel_for(range, [&](const tbb::blocked_range range) { + for(const lightfields::Samples::Sample& sample : range) { + const double uv_magnitude_2 = sample.uv[0] * sample.uv[0] + sample.uv[1] * sample.uv[1]; + if(uv_magnitude_2 < 1.0) { + float target_x = sample.xy[0] / (float)samples.sensorSize()[0] * (float)width; + float target_y = sample.xy[1] / (float)samples.sensorSize()[1] * (float)height; + + target_x = std::min(target_x, (float)(width - 1)); + target_y = std::min(target_y, (float)(height - 1)); + + target_x = std::max(target_x, 0.0f); + target_y = std::max(target_y, 0.0f); + + int index_x = floor((sample.uv[0] + 1.0) / 2.0 * (float)elements); + int index_y = floor((sample.uv[1] + 1.0) / 2.0 * (float)elements); + + float* color = mats[index_x + elements * index_y].ptr(floor(target_y), floor(target_x)); + uint16_t* n = norms[index_x + elements * index_y].ptr(floor(target_y), floor(target_x)); + + if(sample.color == lightfields::Samples::kRGB) + for(int c = 0; c < 3; ++c) { + color[c] += sample.value[c]; + ++n[c]; + } + else { + color[sample.color] += sample.value[sample.color]; + ++n[sample.color]; + } + } + } + }); std::vector counters(mats.size(), 0); tbb::parallel_for(0u, elements * elements, [&](unsigned index) { diff --git a/src/plugins/opencv/nodes/lightfields/mosaic_to_samples.cpp b/src/plugins/opencv/nodes/lightfields/mosaic_to_samples.cpp new file mode 100644 index 00000000000..f3fc85cb736 --- /dev/null +++ b/src/plugins/opencv/nodes/lightfields/mosaic_to_samples.cpp @@ -0,0 +1,74 @@ +#include + +#include +#include + +#include "lightfields.h" +#include "sequence.h" + +namespace { + +using SeqRange = tbb::blocked_range; + +dependency_graph::InAttr a_sequence; +dependency_graph::OutAttr a_samples; + +dependency_graph::State compute(dependency_graph::Values& data) { + const possumwood::opencv::Sequence& seq = data.get(a_sequence); + + lightfields::Samples samples(Imath::V2i(seq.meta().rows, seq.meta().cols)); + samples.resize(std::size_t(seq.meta().rows) * std::size_t(seq.meta().cols) * seq.size()); + + tbb::task_group tasks; + + std::size_t ctr = 0; + for(auto it = seq.begin(); it != seq.end(); ++it, ++ctr) { + tasks.run([it, &samples, &seq, ctr]() { + Imath::V2f uv(0.0f, 0.0f); + if(seq.max().x != seq.min().x) + uv.x = (float(it->first.x) - seq.min().x) / float(seq.max().x - seq.min().x) * 2.0f - 1.0f; + if(seq.max().y != seq.min().y) + uv.y = (float(it->first.y) - seq.min().y) / float(seq.max().y - seq.min().y) * 2.0f - 1.0f; + + tbb::parallel_for(tbb::blocked_range(0, seq.meta().rows), [&](const tbb::blocked_range& range) { + auto target = + samples.begin() + ctr * seq.meta().rows * seq.meta().cols + range.begin() * seq.meta().cols; + + for(int y = range.begin(); y != range.end(); ++y) + for(int x = 0; x < seq.meta().cols; ++x) { + target->xy.x = (float)x; + target->xy.y = (float)y; + + target->uv = uv; + + target->color = lightfields::Samples::kRGB; + + const float* ptr = it->second.ptr(y, x); + for(int a = 0; a < 3; ++a) + target->value[a] = ptr[a]; + + ++target; + } + }); + }); + } + + tasks.wait(); + + data.set(a_samples, std::move(samples)); + + return dependency_graph::State(); +} + +void init(possumwood::Metadata& meta) { + meta.addAttribute(a_sequence, "sequence"); + meta.addAttribute(a_samples, "samples", lightfields::Samples(), possumwood::AttrFlags::kVertical); + + meta.addInfluence(a_sequence, a_samples); + + meta.setCompute(compute); +} + +possumwood::NodeImplementation s_impl("opencv/lightfields/mosaic_to_samples", init); + +} // namespace diff --git a/src/plugins/opencv/nodes/lightfields/samples_to_bspline.cpp b/src/plugins/opencv/nodes/lightfields/samples_to_bspline.cpp new file mode 100644 index 00000000000..ba3abd4423e --- /dev/null +++ b/src/plugins/opencv/nodes/lightfields/samples_to_bspline.cpp @@ -0,0 +1,108 @@ +#include + +#include +#include + +#include "bspline.inl" +#include "datatypes/bspline.h" +#include "lightfields.h" + +namespace { + +dependency_graph::InAttr a_samples; +dependency_graph::InAttr a_xyRes, a_uvRes; +dependency_graph::OutAttr, 3>> a_bspline; + +dependency_graph::State compute(dependency_graph::Values& data) { + dependency_graph::State state; + + std::array, 3> bspline; + for(int a = 0; a < 3; ++a) + bspline[a] = possumwood::opencv::BSpline<4>( + std::array{{data.get(a_xyRes), data.get(a_xyRes), data.get(a_uvRes), data.get(a_uvRes)}}); + + lightfields::Samples samples = data.get(a_samples); + + if(!samples.empty()) { + const Imath::V2f xy_scale = Imath::V2f(data.get(a_xyRes) - 1, data.get(a_xyRes) - 1) / + Imath::V2f(samples.sensorSize().x - 1, samples.sensorSize().y - 1); + const Imath::V2f uv_scale = Imath::V2f(data.get(a_uvRes) - 1, data.get(a_uvRes) - 1); + + const float xy_lim = data.get(a_xyRes); + const float uv_lim = data.get(a_uvRes); + + std::atomic totalMissed(0); + + // sort the samples based on Y values + tbb::parallel_sort(samples.begin(), samples.end(), + [](const lightfields::Samples::Sample& s1, const lightfields::Samples::Sample& s2) { + return s1.xy.y < s2.xy.y; + }); + + // get the range for each Y "line" + std::vector lineStarts; + int current = 0; + for(auto it = samples.begin(); it != samples.end(); ++it) + if(lineStarts.empty() || floor(it->xy.y) != current) { + lineStarts.push_back(it); + current = floor(it->xy.y); + } + lineStarts.push_back(samples.end()); + + // process samples in pairs - every second pair to be skipped in each phase + for(std::size_t phase = 0; phase < 2; ++phase) { + tbb::parallel_for(std::size_t(0), lineStarts.size() / 4 + 1, [&](std::size_t index) { + std::size_t missed = 0; + for(std::size_t ofs = 0; ofs < 2; ++ofs) { + const std::size_t y = index * 4 + 2 * phase + ofs; + if(y < lineStarts.size() - 1) { + for(auto it = lineStarts[y]; it != lineStarts[y + 1]; ++it) { + auto& s = *it; + + const Imath::V2f xy = s.xy * xy_scale; + const Imath::V2f uv = (s.uv / 2.0 + Imath::V2f(0.5f, 0.5f)) * uv_scale; + + if(xy.x >= 0.0f && xy.x <= xy_lim && xy.y >= 0.0f && xy.y <= xy_lim && uv.x >= 0.0f && + uv.x <= uv_lim && uv.y >= 0.0f && uv.y <= uv_lim) { + if(s.color == lightfields::Samples::kRGB) + for(int a = 0; a < 3; ++a) + bspline[a].addSample(std::array{xy.x, xy.y, uv.x, uv.y}, s.value[a]); + else + bspline[s.color].addSample(std::array{xy.x, xy.y, uv.x, uv.y}, + s.value[s.color]); + } + else + ++missed; + } + } + + totalMissed += missed; + } + }); + } + if(totalMissed > 0) + state.addWarning(std::to_string(totalMissed) + " samples were missed when constructing the b spline."); + } + + data.set(a_bspline, bspline); + + return state; +} + +void init(possumwood::Metadata& meta) { + meta.addAttribute(a_samples, "samples", lightfields::Samples(), possumwood::AttrFlags::kVertical); + meta.addAttribute(a_xyRes, "resolution/xy", 10u); + meta.addAttribute(a_uvRes, "resolution/uv", 10u); + meta.addAttribute(a_bspline, "bspline", std::array, 3>(), + possumwood::AttrFlags::kVertical); + + meta.addInfluence(a_samples, a_bspline); + meta.addInfluence(a_xyRes, a_bspline); + meta.addInfluence(a_uvRes, a_bspline); + + meta.setCompute(compute); +} + +possumwood::NodeImplementation s_impl("opencv/lightfields/samples_to_bspline", init); + +} // namespace diff --git a/src/plugins/opencv/nodes/lightfields/vignetting_create.cpp b/src/plugins/opencv/nodes/lightfields/vignetting_create.cpp deleted file mode 100644 index 9df7c3b8124..00000000000 --- a/src/plugins/opencv/nodes/lightfields/vignetting_create.cpp +++ /dev/null @@ -1,49 +0,0 @@ -#include -#include -#include - -#include - -#include "frame.h" -#include "lightfield_vignetting.h" -#include "lightfields.h" - -namespace { - -dependency_graph::InAttr a_pattern; -dependency_graph::InAttr a_in; -dependency_graph::InAttr a_subdivLevel; -dependency_graph::OutAttr a_vignetting; - -dependency_graph::State compute(dependency_graph::Values& data) { - const lightfields::Pattern pattern = data.get(a_pattern); - - const cv::Mat& in = *data.get(a_in); - - if(in.cols != pattern.sensorResolution()[1] || in.rows != pattern.sensorResolution()[0]) - throw std::runtime_error("Frame and pattern resolution don't match!"); - - possumwood::opencv::LightfieldVignetting vignetting(data.get(a_subdivLevel), pattern, in); - - data.set(a_vignetting, vignetting); - - return dependency_graph::State(); -} - -void init(possumwood::Metadata& meta) { - meta.addAttribute(a_in, "frame", possumwood::opencv::Frame(), possumwood::AttrFlags::kVertical); - meta.addAttribute(a_pattern, "pattern", lightfields::Pattern(), possumwood::AttrFlags::kVertical); - meta.addAttribute(a_subdivLevel, "subdiv_level", 32u); - meta.addAttribute(a_vignetting, "vignetting", possumwood::opencv::LightfieldVignetting(), - possumwood::AttrFlags::kVertical); - - meta.addInfluence(a_pattern, a_vignetting); - meta.addInfluence(a_in, a_vignetting); - meta.addInfluence(a_subdivLevel, a_vignetting); - - meta.setCompute(compute); -} - -possumwood::NodeImplementation s_impl("opencv/lightfields/vignetting_create", init); - -} // namespace diff --git a/src/plugins/opencv/nodes/lightfields/vignetting_mosaic.cpp b/src/plugins/opencv/nodes/lightfields/vignetting_mosaic.cpp deleted file mode 100644 index d1a022333a5..00000000000 --- a/src/plugins/opencv/nodes/lightfields/vignetting_mosaic.cpp +++ /dev/null @@ -1,92 +0,0 @@ -#include -#include -#include -#include - -#include -#include -#include - -#include "frame.h" -#include "lightfield_vignetting.h" -#include "maths/io/vec2.h" -#include "tools.h" - -namespace { - -dependency_graph::InAttr a_vignetting; -dependency_graph::InAttr> a_size; -dependency_graph::InAttr a_elements; -dependency_graph::InAttr a_mode; -dependency_graph::OutAttr a_out; - -dependency_graph::State compute(dependency_graph::Values& data) { - const possumwood::opencv::LightfieldVignetting& vignetting = data.get(a_vignetting); - - const unsigned width = data.get(a_size)[0]; - const unsigned height = data.get(a_size)[1]; - const unsigned elements = data.get(a_elements); - - cv::Mat mat = cv::Mat::zeros(height, width, CV_32FC1); - - if(data.get(a_mode).value() == "XY-UV") { - tbb::parallel_for(0u, height, [&](unsigned y) { - for(unsigned x = 0; x < width; ++x) { - float xf = (float)x / (float)(width) * (float)elements; - float yf = (float)y / (float)(height) * (float)elements; - - float uf = ((floor(xf) + 0.5) / (float)(elements)-0.5) * 2.0; - float vf = ((floor(yf) + 0.5) / (float)(elements)-0.5) * 2.0; - - xf = std::fmod(xf, 1.0f); - yf = std::fmod(yf, 1.0f); - - const double sample = vignetting.sample(cv::Vec4f(xf, yf, uf, vf)); - - mat.at(y, x) = sample; - } - }); - } - else { - tbb::parallel_for(0u, height, [&](unsigned y) { - for(unsigned x = 0; x < width; ++x) { - float uf = (float)x / (float)(width) * (float)elements; - float vf = (float)y / (float)(height) * (float)elements; - - float xf = ((floor(uf) + 0.5) / (float)(elements + 1)); - float yf = ((floor(vf) + 0.5) / (float)(elements + 1)); - - uf = (std::fmod(uf, 1.0f) - 0.5) * 2.0; - vf = (std::fmod(vf, 1.0f) - 0.5) * 2.0; - - const double sample = vignetting.sample(cv::Vec4f(xf, yf, uf, vf)); - - mat.at(y, x) = sample; - } - }); - } - - data.set(a_out, possumwood::opencv::Frame(mat)); - - return dependency_graph::State(); -} - -void init(possumwood::Metadata& meta) { - meta.addAttribute(a_vignetting, "vignetting", possumwood::opencv::LightfieldVignetting(), - possumwood::AttrFlags::kVertical); - meta.addAttribute(a_size, "size", Imath::Vec2(300u, 300u)); - meta.addAttribute(a_elements, "elements", 5u); - meta.addAttribute(a_mode, "mode", possumwood::Enum({"XY-UV", "UV-XY"})); - meta.addAttribute(a_out, "out_frame", possumwood::opencv::Frame(), possumwood::AttrFlags::kVertical); - - meta.addInfluence(a_vignetting, a_out); - meta.addInfluence(a_size, a_out); - meta.addInfluence(a_elements, a_out); - meta.addInfluence(a_mode, a_out); - - meta.setCompute(compute); -} - -possumwood::NodeImplementation s_impl("opencv/lightfields/vignetting_mosaic", init); - -} // namespace diff --git a/src/plugins/opencv/sequence.cpp b/src/plugins/opencv/sequence.cpp index 817540dabcd..eb8250fad8a 100644 --- a/src/plugins/opencv/sequence.cpp +++ b/src/plugins/opencv/sequence.cpp @@ -55,6 +55,10 @@ bool Sequence::hasOneElement() const { return m_sequence.size() == 1; } +std::size_t Sequence::size() const { + return m_sequence.size(); +} + const Imath::V2i& Sequence::min() const { return m_min; } diff --git a/src/plugins/opencv/sequence.h b/src/plugins/opencv/sequence.h index 5fd572c9633..18959a1a91a 100644 --- a/src/plugins/opencv/sequence.h +++ b/src/plugins/opencv/sequence.h @@ -61,6 +61,7 @@ class Sequence final { bool empty() const; bool hasOneElement() const; + std::size_t size() const; const Imath::V2i& min() const; const Imath::V2i& max() const; diff --git a/toolbars/07_lightfields_import/16_filtered_normalization.psw b/toolbars/07_lightfields_import/16_filtered_normalization.psw index 723b8f26bde..7c8921f1f39 100644 --- a/toolbars/07_lightfields_import/16_filtered_normalization.psw +++ b/toolbars/07_lightfields_import/16_filtered_normalization.psw @@ -173,8 +173,8 @@ "blind_data": { "type": "possumwood::NodeData", "value": { - "x": 774.5919189453125, - "y": 1729.139404296875 + "x": 894.02490234375, + "y": 1771.7940673828125 } }, "name": "concat", @@ -188,8 +188,8 @@ "blind_data": { "type": "possumwood::NodeData", "value": { - "x": 828.3179931640625, - "y": 1935.28857421875 + "x": 947.7509765625, + "y": 1977.9432373046875 } }, "name": "convert", @@ -218,8 +218,8 @@ "blind_data": { "type": "possumwood::NodeData", "value": { - "x": 557.2045288085938, - "y": 1138.6041259765625 + "x": 780.1735229492188, + "y": 967.6611938476563 } }, "name": "divide", @@ -229,8 +229,8 @@ "blind_data": { "type": "possumwood::NodeData", "value": { - "x": 813.0813598632813, - "y": 1034.8702392578125 + "x": 1066.2957763671875, + "y": 548.3789672851563 } }, "name": "divide", @@ -262,8 +262,8 @@ "blind_data": { "type": "possumwood::NodeData", "value": { - "x": 744.8676147460938, - "y": 2137.2001953125 + "x": 864.3005981445313, + "y": 2179.854736328125 } }, "name": "zoom", @@ -299,8 +299,8 @@ "blind_data": { "type": "possumwood::NodeData", "value": { - "x": 719.7354125976563, - "y": 1283.47265625 + "x": 927.83984375, + "y": 1084.0281982421875 } }, "name": "median", @@ -313,8 +313,8 @@ "blind_data": { "type": "possumwood::NodeData", "value": { - "x": 990.6098022460938, - "y": 1083.97998046875 + "x": 1225.243408203125, + "y": 597.4886474609375 } }, "name": "mosaic", @@ -324,8 +324,8 @@ "blind_data": { "type": "possumwood::NodeData", "value": { - "x": 865.0340576171875, - "y": 1326.330810546875 + "x": 1073.138427734375, + "y": 1126.8863525390625 } }, "name": "mosaic", @@ -335,8 +335,8 @@ "blind_data": { "type": "possumwood::NodeData", "value": { - "x": 473.5895690917969, - "y": 1014.270263671875 + "x": 581.35791015625, + "y": 1099.74169921875 } }, "name": "mosaic", @@ -346,8 +346,8 @@ "blind_data": { "type": "possumwood::NodeData", "value": { - "x": 844.1182250976563, - "y": 2142.2373046875 + "x": 963.5512084960938, + "y": 2184.891845703125 } }, "connections": [ @@ -646,8 +646,8 @@ "blind_data": { "type": "possumwood::NodeData", "value": { - "x": 981.6162109375, - "y": 1505.60986328125 + "x": 1199.1549072265625, + "y": 1480.01708984375 } }, "name": "resize", @@ -691,8 +691,8 @@ "blind_data": { "type": "possumwood::NodeData", "value": { - "x": 389.6700134277344, - "y": 1155.70166015625 + "x": 638.6520385742188, + "y": 854.6934814453125 } }, "name": "subset", @@ -712,8 +712,8 @@ "ports": { "filename": "/home/martin/gdrive/Coding/possumwood/examples/lytro/tea.lfr", "size": { - "x": 100, - "y": 100 + "x": 30, + "y": 30 }, "zoom": { "in_progress_updates": true, @@ -730,5 +730,5 @@ }, "type": "network", "ui_geometry": "AdnQywADAAAAAAAAAAAAAAAABqoAAAOfAAAAAAAAABQAAAQ6AAACkwAAAAACAAAABqsAAAAAAAAAFwAABqoAAAOf", - "ui_state": "AAAA/wAAAAD9AAAAAgAAAAAAAAI0AAAC+fwCAAAAAfsAAAAKAGcAcgBhAHAAaAEAAAB1AAAC+QAAAJsBAAADAAAAAQAAAagAAAL5/AIAAAAC+wAAABQAcAByAG8AcABlAHIAdABpAGUAcwEAAAB1AAABJwAAAHkBAAAD+wAAAAwAZQBkAGkAdABvAHIBAAABnQAAAdEAAACtAQAAAwAAAs0AAAL5AAAABAAAAAQAAAAIAAAACPwAAAAA" + "ui_state": "AAAA/wAAAAD9AAAAAgAAAAAAAAJrAAAC+fwCAAAAAfsAAAAKAGcAcgBhAHAAaAEAAAB1AAAC+QAAAJsBAAADAAAAAQAAAagAAAL5/AIAAAAC+wAAABQAcAByAG8AcABlAHIAdABpAGUAcwEAAAB1AAABJwAAAHkBAAAD+wAAAAwAZQBkAGkAdABvAHIBAAABnQAAAdEAAACtAQAAAwAAApYAAAL5AAAABAAAAAQAAAAIAAAACPwAAAAA" } \ No newline at end of file diff --git a/toolbars/07_lightfields_import/17_bspline_normalization.psw b/toolbars/07_lightfields_import/17_bspline_normalization.psw new file mode 100644 index 00000000000..6b39f2bd9b1 --- /dev/null +++ b/toolbars/07_lightfields_import/17_bspline_normalization.psw @@ -0,0 +1,538 @@ +{ + "connections": [ + { + "in_node": "mosaic_0", + "in_port": "seq", + "out_node": "bspline_to_sequence_0", + "out_port": "sequence" + }, + { + "in_node": "network_0", + "in_port": "frame", + "out_node": "convert_0", + "out_port": "out_frame" + }, + { + "in_node": "samples_from_metadata_0", + "in_port": "in_frame", + "out_node": "demosaic_0", + "out_port": "out_frame" + }, + { + "in_node": "lytro_lightfield_0", + "in_port": "filename", + "out_node": "input_0", + "out_port": "data" + }, + { + "in_node": "network_0", + "in_port": "zoom", + "out_node": "input_1", + "out_port": "data" + }, + { + "in_node": "demosaic_0", + "in_port": "in_frame", + "out_node": "lytro_lightfield_0", + "out_port": "frame" + }, + { + "in_node": "demosaic_0", + "in_port": "mozaic", + "out_node": "lytro_lightfield_0", + "out_port": "mozaic" + }, + { + "in_node": "samples_from_metadata_0", + "in_port": "metadata", + "out_node": "lytro_lightfield_0", + "out_port": "metadata" + }, + { + "in_node": "convert_0", + "in_port": "in_frame", + "out_node": "mosaic_0", + "out_port": "frame" + }, + { + "in_node": "samples_refocus_0", + "in_port": "in_samples", + "out_node": "samples_from_metadata_0", + "out_port": "samples" + }, + { + "in_node": "samples_to_bspline_0", + "in_port": "samples", + "out_node": "samples_refocus_0", + "out_port": "out_samples" + }, + { + "in_node": "bspline_to_sequence_0", + "in_port": "bspline", + "out_node": "samples_to_bspline_0", + "out_port": "bspline" + } + ], + "description": "### Microlens normalisation using filtered center-view difference\n\nDue to the specific structure of the lens and microlens-array construction of the Lytro camera, the output image contains a complex 4-dimensional vignetting pattern, degrading the quality of the reconstruction.\n\nIn this demo, we use the central view (u,v ~ 0) image as a reference to normalize other views. This will lead to discontinuities due to parallax changes between images - assuming most of the image will contain low-frequency content, we can address these using a simple median filter.\n\nWhile removing the requirement for specific reference images, this approach might introduce low-frequency artifacts due to filtering.", + "name": "network", + "nodes": { + "bspline_to_sequence_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 422.68548583984375, + "y": 962.7109985351563 + } + }, + "name": "bspline_to_sequence", + "ports": { + "uv_resolution": { + "x": 30, + "y": 30 + }, + "xy_resolution": { + "x": 30, + "y": 30 + } + }, + "type": "opencv/lightfields/bspline_to_sequence" + }, + "convert_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 701.1376342773438, + "y": 1216.783935546875 + } + }, + "name": "convert", + "ports": { + "a": 500.0, + "b": 0.0, + "mode": "CV_8U" + }, + "type": "opencv/convert" + }, + "demosaic_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 109.42190551757813, + "y": 227.32159423828125 + } + }, + "name": "demosaic", + "ports": { + "mode": "Basic" + }, + "type": "opencv/demosaic" + }, + "input_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 32.4499626159668, + "y": 87.27973175048828 + } + }, + "name": "filename", + "type": "input" + }, + "input_1": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 635.43701171875, + "y": 1438.3726806640625 + } + }, + "name": "zoom", + "type": "input" + }, + "lytro_lightfield_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 149.00340270996094, + "y": 84.8009262084961 + } + }, + "name": "lytro_lightfield", + "type": "opencv/capture/lytro_lightfield" + }, + "mosaic_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 711.5875854492188, + "y": 1046.2042236328125 + } + }, + "name": "mosaic", + "type": "opencv/sequence/mosaic" + }, + "network_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 734.6876220703125, + "y": 1443.4097900390625 + } + }, + "connections": [ + { + "in_node": "draw_0", + "in_port": "vertex_data", + "out_node": "background_0", + "out_port": "vertex_data" + }, + { + "in_node": "unsigned_1", + "in_port": "in_uniforms", + "out_node": "float_0", + "out_port": "out_uniforms" + }, + { + "in_node": "program_0", + "in_port": "fragment_shader", + "out_node": "fragment_shader_0", + "out_port": "shader" + }, + { + "in_node": "metadata_0", + "in_port": "frame", + "out_node": "input_0", + "out_port": "data" + }, + { + "in_node": "opencv_texture_0", + "in_port": "frame", + "out_node": "input_0", + "out_port": "data" + }, + { + "in_node": "interval_0", + "in_port": "interval", + "out_node": "input_1", + "out_port": "data" + }, + { + "in_node": "float_0", + "in_port": "value", + "out_node": "interval_0", + "out_port": "out" + }, + { + "in_node": "split_vec2u_0", + "in_port": "vec", + "out_node": "metadata_0", + "out_port": "size" + }, + { + "in_node": "viewport_0", + "in_port": "in_uniforms", + "out_node": "opencv_texture_0", + "out_port": "out_uniforms" + }, + { + "in_node": "draw_0", + "in_port": "program", + "out_node": "program_0", + "out_port": "program" + }, + { + "in_node": "unsigned_1", + "in_port": "value", + "out_node": "split_vec2u_0", + "out_port": "x" + }, + { + "in_node": "unsigned_0", + "in_port": "value", + "out_node": "split_vec2u_0", + "out_port": "y" + }, + { + "in_node": "opencv_texture_0", + "in_port": "in_uniforms", + "out_node": "unsigned_0", + "out_port": "out_uniforms" + }, + { + "in_node": "unsigned_0", + "in_port": "in_uniforms", + "out_node": "unsigned_1", + "out_port": "out_uniforms" + }, + { + "in_node": "program_0", + "in_port": "vertex_shader", + "out_node": "vertex_shader_0", + "out_port": "shader" + }, + { + "in_node": "draw_0", + "in_port": "uniforms", + "out_node": "viewport_0", + "out_port": "out_uniforms" + } + ], + "name": "display", + "nodes": { + "background_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 378.49346923828125, + "y": 846.5810546875 + } + }, + "name": "background", + "type": "render/vertex_data/background" + }, + "draw_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 597.115966796875, + "y": 727.212646484375 + } + }, + "name": "draw", + "ports": { + "setup": { + "culling": "ccw" + } + }, + "type": "render/draw" + }, + "float_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 576.15576171875, + "y": -151.2345733642578 + } + }, + "name": "float", + "ports": { + "name": "zoom" + }, + "type": "render/uniforms/float" + }, + "fragment_shader_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 168.25132751464844, + "y": 736.7239990234375 + } + }, + "name": "fragment_shader", + "ports": { + "source": "#version 130 \n \nout vec4 color; \n \nin vec2 uv; \n\nuniform sampler2D image;\n\nvoid main() { \n\tif(uv.x < 0.0 || uv.x > 1.0 || uv.y < 0.0 || uv.y > 1.0)\n\t\tcolor = vec4(0,0,0,1);\n\telse\n\t\tcolor = vec4(texture(image, vec2(uv.x, 1.0-uv.y))); \n} \n" + }, + "type": "render/fragment_shader" + }, + "input_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": -0.9546433091163635, + "y": 258.1717834472656 + } + }, + "name": "frame", + "type": "input" + }, + "input_1": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 391.5198974609375, + "y": -245.0040283203125 + } + }, + "name": "zoom", + "type": "input" + }, + "interval_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 477.1414794921875, + "y": -155.22750854492188 + } + }, + "name": "interval", + "type": "maths/interval" + }, + "metadata_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 165.910888671875, + "y": 117.08377838134766 + } + }, + "name": "opencv_metadata", + "type": "opencv/metadata" + }, + "opencv_texture_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 562.9571533203125, + "y": 428.0434265136719 + } + }, + "name": "opencv_texture", + "ports": { + "mode": "Nearest", + "name": "image" + }, + "type": "render/uniforms/opencv_texture" + }, + "program_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 374.8364562988281, + "y": 625.6016235351563 + } + }, + "name": "program", + "type": "render/program" + }, + "split_vec2u_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 383.22418212890625, + "y": 155.3865966796875 + } + }, + "name": "split_vec2u", + "type": "maths/split_vec2u" + }, + "unsigned_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 570.666015625, + "y": 243.66001892089844 + } + }, + "name": "unsigned height", + "ports": { + "name": "image_height" + }, + "type": "render/uniforms/unsigned" + }, + "unsigned_1": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 567.2022094726563, + "y": 58.09212112426758 + } + }, + "name": "unsigned width", + "ports": { + "name": "image_width" + }, + "type": "render/uniforms/unsigned" + }, + "vertex_shader_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 197.65194702148438, + "y": 524.3696899414063 + } + }, + "name": "vertex_shader", + "ports": { + "source": "#version 130 \n \nin vec3 P; // position attr from the vbo \n \nuniform mat4 iProjection; // projection matrix \nuniform mat4 iModelView; // modelview matrix \n\nuniform uint image_width;\nuniform uint image_height;\nuniform vec2 iResolution;\nuniform float zoom;\n\nout vec2 uv; // uv texturing parameters\n \nvoid main() {\n\t// compute the aspect ratio from image width and height\n\tfloat aspect = float(image_width) / float(image_height);\n\n\t// compute the screen aspect ratio\n\tfloat screen_aspect = iResolution.x / iResolution.y;\n\n\tgl_Position = vec4(P.x, P.y, 0, 1);\n\n\t// UV parameters are just untransformed world-space position\n\tuv = vec2(P/pow(2.0, zoom));\n\tuv.y *= aspect / screen_aspect;\n\tuv += vec2(-iModelView[3][0], -iModelView[3][1]) / zoom;\n\tuv += 0.5;\n} \n" + }, + "type": "render/vertex_shader" + }, + "viewport_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 597.0606079101563, + "y": 600.4863891601563 + } + }, + "name": "viewport", + "type": "render/uniforms/viewport" + } + }, + "type": "network" + }, + "samples_from_metadata_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 134.70880126953125, + "y": 377.3011169433594 + } + }, + "name": "samples_from_metadata", + "ports": { + "correct_gain": true + }, + "type": "opencv/lightfields/samples_from_metadata" + }, + "samples_refocus_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 167.42539978027344, + "y": 569.9113159179688 + } + }, + "name": "samples_refocus", + "ports": { + "uv_offset": 0.0, + "uv_threshold": 1.0, + "xy_scale": 1.0 + }, + "type": "opencv/lightfields/samples_refocus" + }, + "samples_to_bspline_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 420.12237548828125, + "y": 746.4522705078125 + } + }, + "name": "samples_to_bspline", + "ports": { + "resolution/uv": 30, + "resolution/xy": 30 + }, + "type": "opencv/lightfields/samples_to_bspline" + } + }, + "ports": { + "filename": "/home/martin/gdrive/Coding/possumwood/examples/lytro/IMG_0015.lfr", + "zoom": { + "in_progress_updates": true, + "max": 8.0, + "min": 1.0, + "type": "linear", + "value": 1.0 + } + }, + "scene_config": { + "end_time": 5.0, + "fps": 24.0, + "start_time": 0.0 + }, + "type": "network", + "ui_geometry": "AdnQywADAAAAAAAAAAAAAAAABqoAAAOfAAAAAAAAABQAAAQ6AAACkwAAAAACAAAABqsAAAAAAAAAFwAABqoAAAOf", + "ui_state": "AAAA/wAAAAD9AAAAAgAAAAAAAAKHAAAC+fwCAAAAAfsAAAAKAGcAcgBhAHAAaAEAAAB1AAAC+QAAAJsBAAADAAAAAQAAAagAAAL5/AIAAAAC+wAAABQAcAByAG8AcABlAHIAdABpAGUAcwEAAAB1AAABJwAAAHkBAAAD+wAAAAwAZQBkAGkAdABvAHIBAAABnQAAAdEAAACtAQAAAwAAAnoAAAL5AAAABAAAAAQAAAAIAAAACPwAAAAA" +} \ No newline at end of file diff --git a/toolbars/07_lightfields_import/18_mosaic_normalization.psw b/toolbars/07_lightfields_import/18_mosaic_normalization.psw new file mode 100644 index 00000000000..a21b69cbfa2 --- /dev/null +++ b/toolbars/07_lightfields_import/18_mosaic_normalization.psw @@ -0,0 +1,636 @@ +{ + "connections": [ + { + "in_node": "convert_0", + "in_port": "in_frame", + "out_node": "bspline_to_frame_0", + "out_port": "frame" + }, + { + "in_node": "network_0", + "in_port": "frame", + "out_node": "convert_0", + "out_port": "out_frame" + }, + { + "in_node": "samples_from_metadata_0", + "in_port": "in_frame", + "out_node": "demosaic_0", + "out_port": "out_frame" + }, + { + "in_node": "lytro_lightfield_0", + "in_port": "filename", + "out_node": "input_1", + "out_port": "data" + }, + { + "in_node": "network_0", + "in_port": "zoom", + "out_node": "input_2", + "out_port": "data" + }, + { + "in_node": "mosaic_0", + "in_port": "seq", + "out_node": "integrate_mosaic_0", + "out_port": "sequence" + }, + { + "in_node": "mosaic_to_samples_0", + "in_port": "sequence", + "out_node": "integrate_mosaic_0", + "out_port": "sequence" + }, + { + "in_node": "demosaic_0", + "in_port": "in_frame", + "out_node": "lytro_lightfield_0", + "out_port": "frame" + }, + { + "in_node": "demosaic_0", + "in_port": "mozaic", + "out_node": "lytro_lightfield_0", + "out_port": "mozaic" + }, + { + "in_node": "samples_from_metadata_0", + "in_port": "metadata", + "out_node": "lytro_lightfield_0", + "out_port": "metadata" + }, + { + "in_node": "samples_refocus_1", + "in_port": "in_samples", + "out_node": "mosaic_to_samples_0", + "out_port": "samples" + }, + { + "in_node": "samples_refocus_0", + "in_port": "in_samples", + "out_node": "samples_from_metadata_0", + "out_port": "samples" + }, + { + "in_node": "samples_to_bspline_0", + "in_port": "samples", + "out_node": "samples_refocus_0", + "out_port": "out_samples" + }, + { + "in_node": "integrate_mosaic_0", + "in_port": "samples", + "out_node": "samples_refocus_0", + "out_port": "out_samples" + }, + { + "in_node": "integrate_nearest_0", + "in_port": "samples", + "out_node": "samples_refocus_1", + "out_port": "out_samples" + }, + { + "in_node": "bspline_to_frame_0", + "in_port": "bspline", + "out_node": "samples_to_bspline_0", + "out_port": "bspline" + } + ], + "description": "### Microlens normalisation using filtered center-view difference\n\nDue to the specific structure of the lens and microlens-array construction of the Lytro camera, the output image contains a complex 4-dimensional vignetting pattern, degrading the quality of the reconstruction.\n\nIn this demo, we use the central view (u,v ~ 0) image as a reference to normalize other views. This will lead to discontinuities due to parallax changes between images - assuming most of the image will contain low-frequency content, we can address these using a simple median filter.\n\nWhile removing the requirement for specific reference images, this approach might introduce low-frequency artifacts due to filtering.", + "name": "network", + "nodes": { + "bspline_to_frame_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 430.7798156738281, + "y": 991.0454711914063 + } + }, + "name": "bspline_to_frame", + "ports": { + "resolution": { + "x": 1000, + "y": 1000 + }, + "uv": { + "x": 0.0, + "y": 0.0 + } + }, + "type": "opencv/lightfields/bspline_to_frame" + }, + "convert_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 483.8885192871094, + "y": 1218.30224609375 + } + }, + "name": "convert", + "ports": { + "a": 500.0, + "b": 0.0, + "mode": "CV_8U" + }, + "type": "opencv/convert" + }, + "demosaic_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 109.42190551757813, + "y": 227.32159423828125 + } + }, + "name": "demosaic", + "ports": { + "mode": "Basic" + }, + "type": "opencv/demosaic" + }, + "input_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 16.799766540527344, + "y": 811.9969482421875 + } + }, + "name": "size", + "type": "input" + }, + "input_1": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 32.4499626159668, + "y": 87.27973175048828 + } + }, + "name": "filename", + "type": "input" + }, + "input_2": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 422.6103820800781, + "y": 1438.3726806640625 + } + }, + "name": "zoom", + "type": "input" + }, + "integrate_mosaic_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 449.34661865234375, + "y": 479.99298095703125 + } + }, + "name": "integrate_mosaic", + "ports": { + "elements": 9, + "inclusion_ratio": 0.9999899864196777, + "size": { + "x": 250, + "y": 250 + } + }, + "type": "opencv/lightfields/integrate_mosaic" + }, + "integrate_nearest_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 916.3701171875, + "y": 627.6605834960938 + } + }, + "name": "integrate_nearest", + "ports": { + "size": { + "x": 250, + "y": 250 + } + }, + "type": "opencv/lightfields/integrate_nearest" + }, + "lytro_lightfield_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 149.00340270996094, + "y": 84.8009262084961 + } + }, + "name": "lytro_lightfield", + "type": "opencv/capture/lytro_lightfield" + }, + "mosaic_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 780.3589477539063, + "y": 647.4915771484375 + } + }, + "name": "mosaic", + "type": "opencv/sequence/mosaic" + }, + "mosaic_to_samples_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 657.03271484375, + "y": 506.70391845703125 + } + }, + "name": "mosaic_to_samples", + "type": "opencv/lightfields/mosaic_to_samples" + }, + "network_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 521.8609619140625, + "y": 1443.4097900390625 + } + }, + "connections": [ + { + "in_node": "draw_0", + "in_port": "vertex_data", + "out_node": "background_0", + "out_port": "vertex_data" + }, + { + "in_node": "unsigned_1", + "in_port": "in_uniforms", + "out_node": "float_0", + "out_port": "out_uniforms" + }, + { + "in_node": "program_0", + "in_port": "fragment_shader", + "out_node": "fragment_shader_0", + "out_port": "shader" + }, + { + "in_node": "metadata_0", + "in_port": "frame", + "out_node": "input_0", + "out_port": "data" + }, + { + "in_node": "opencv_texture_0", + "in_port": "frame", + "out_node": "input_0", + "out_port": "data" + }, + { + "in_node": "interval_0", + "in_port": "interval", + "out_node": "input_1", + "out_port": "data" + }, + { + "in_node": "float_0", + "in_port": "value", + "out_node": "interval_0", + "out_port": "out" + }, + { + "in_node": "split_vec2u_0", + "in_port": "vec", + "out_node": "metadata_0", + "out_port": "size" + }, + { + "in_node": "viewport_0", + "in_port": "in_uniforms", + "out_node": "opencv_texture_0", + "out_port": "out_uniforms" + }, + { + "in_node": "draw_0", + "in_port": "program", + "out_node": "program_0", + "out_port": "program" + }, + { + "in_node": "unsigned_1", + "in_port": "value", + "out_node": "split_vec2u_0", + "out_port": "x" + }, + { + "in_node": "unsigned_0", + "in_port": "value", + "out_node": "split_vec2u_0", + "out_port": "y" + }, + { + "in_node": "opencv_texture_0", + "in_port": "in_uniforms", + "out_node": "unsigned_0", + "out_port": "out_uniforms" + }, + { + "in_node": "unsigned_0", + "in_port": "in_uniforms", + "out_node": "unsigned_1", + "out_port": "out_uniforms" + }, + { + "in_node": "program_0", + "in_port": "vertex_shader", + "out_node": "vertex_shader_0", + "out_port": "shader" + }, + { + "in_node": "draw_0", + "in_port": "uniforms", + "out_node": "viewport_0", + "out_port": "out_uniforms" + } + ], + "name": "display", + "nodes": { + "background_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 378.49346923828125, + "y": 846.5810546875 + } + }, + "name": "background", + "type": "render/vertex_data/background" + }, + "draw_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 597.115966796875, + "y": 727.212646484375 + } + }, + "name": "draw", + "ports": { + "setup": { + "culling": "ccw" + } + }, + "type": "render/draw" + }, + "float_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 576.15576171875, + "y": -151.2345733642578 + } + }, + "name": "float", + "ports": { + "name": "zoom" + }, + "type": "render/uniforms/float" + }, + "fragment_shader_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 168.25132751464844, + "y": 736.7239990234375 + } + }, + "name": "fragment_shader", + "ports": { + "source": "#version 130 \n \nout vec4 color; \n \nin vec2 uv; \n\nuniform sampler2D image;\n\nvoid main() { \n\tif(uv.x < 0.0 || uv.x > 1.0 || uv.y < 0.0 || uv.y > 1.0)\n\t\tcolor = vec4(0,0,0,1);\n\telse\n\t\tcolor = vec4(texture(image, vec2(uv.x, 1.0-uv.y))); \n} \n" + }, + "type": "render/fragment_shader" + }, + "input_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": -0.9546433091163635, + "y": 258.1717834472656 + } + }, + "name": "frame", + "type": "input" + }, + "input_1": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 391.5198974609375, + "y": -245.0040283203125 + } + }, + "name": "zoom", + "type": "input" + }, + "interval_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 477.1414794921875, + "y": -155.22750854492188 + } + }, + "name": "interval", + "type": "maths/interval" + }, + "metadata_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 165.910888671875, + "y": 117.08377838134766 + } + }, + "name": "opencv_metadata", + "type": "opencv/metadata" + }, + "opencv_texture_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 562.9571533203125, + "y": 428.0434265136719 + } + }, + "name": "opencv_texture", + "ports": { + "mode": "Nearest", + "name": "image" + }, + "type": "render/uniforms/opencv_texture" + }, + "program_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 374.8364562988281, + "y": 625.6016235351563 + } + }, + "name": "program", + "type": "render/program" + }, + "split_vec2u_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 383.22418212890625, + "y": 155.3865966796875 + } + }, + "name": "split_vec2u", + "type": "maths/split_vec2u" + }, + "unsigned_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 570.666015625, + "y": 243.66001892089844 + } + }, + "name": "unsigned height", + "ports": { + "name": "image_height" + }, + "type": "render/uniforms/unsigned" + }, + "unsigned_1": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 567.2022094726563, + "y": 58.09212112426758 + } + }, + "name": "unsigned width", + "ports": { + "name": "image_width" + }, + "type": "render/uniforms/unsigned" + }, + "vertex_shader_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 197.65194702148438, + "y": 524.3696899414063 + } + }, + "name": "vertex_shader", + "ports": { + "source": "#version 130 \n \nin vec3 P; // position attr from the vbo \n \nuniform mat4 iProjection; // projection matrix \nuniform mat4 iModelView; // modelview matrix \n\nuniform uint image_width;\nuniform uint image_height;\nuniform vec2 iResolution;\nuniform float zoom;\n\nout vec2 uv; // uv texturing parameters\n \nvoid main() {\n\t// compute the aspect ratio from image width and height\n\tfloat aspect = float(image_width) / float(image_height);\n\n\t// compute the screen aspect ratio\n\tfloat screen_aspect = iResolution.x / iResolution.y;\n\n\tgl_Position = vec4(P.x, P.y, 0, 1);\n\n\t// UV parameters are just untransformed world-space position\n\tuv = vec2(P/pow(2.0, zoom));\n\tuv.y *= aspect / screen_aspect;\n\tuv += vec2(-iModelView[3][0], -iModelView[3][1]) / zoom;\n\tuv += 0.5;\n} \n" + }, + "type": "render/vertex_shader" + }, + "viewport_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 597.0606079101563, + "y": 600.4863891601563 + } + }, + "name": "viewport", + "type": "render/uniforms/viewport" + } + }, + "type": "network" + }, + "samples_from_metadata_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 134.70880126953125, + "y": 377.3011169433594 + } + }, + "name": "samples_from_metadata", + "ports": { + "correct_gain": true + }, + "type": "opencv/lightfields/samples_from_metadata" + }, + "samples_refocus_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 167.42539978027344, + "y": 569.9113159179688 + } + }, + "name": "samples_refocus", + "ports": { + "uv_offset": 0.0, + "uv_threshold": 1.0, + "xy_scale": 1.0 + }, + "type": "opencv/lightfields/samples_refocus" + }, + "samples_refocus_1": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 1011.342041015625, + "y": 364.912353515625 + } + }, + "name": "samples_refocus", + "ports": { + "uv_offset": -3.0, + "uv_threshold": 1.0, + "xy_scale": 1.0 + }, + "type": "opencv/lightfields/samples_refocus" + }, + "samples_to_bspline_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 420.12237548828125, + "y": 746.4522705078125 + } + }, + "name": "samples_to_bspline", + "ports": { + "resolution/uv": 4, + "resolution/xy": 1000 + }, + "type": "opencv/lightfields/samples_to_bspline" + } + }, + "ports": { + "filename": "/home/martin/gdrive/Coding/possumwood/examples/lytro/tea.lfr", + "zoom": { + "in_progress_updates": true, + "max": 8.0, + "min": 1.0, + "type": "linear", + "value": 1.0 + } + }, + "scene_config": { + "end_time": 5.0, + "fps": 24.0, + "start_time": 0.0 + }, + "type": "network", + "ui_geometry": "AdnQywADAAAAAAAAAAAAAAAABqoAAAOfAAAAAAAAABQAAAQ6AAACkwAAAAACAAAABqsAAAAAAAAAFwAABqoAAAOf", + "ui_state": "AAAA/wAAAAD9AAAAAgAAAAAAAAJjAAAC+fwCAAAAAfsAAAAKAGcAcgBhAHAAaAEAAAB1AAAC+QAAAJsBAAADAAAAAQAAAagAAAL5/AIAAAAC+wAAABQAcAByAG8AcABlAHIAdABpAGUAcwEAAAB1AAABJwAAAHkBAAAD+wAAAAwAZQBkAGkAdABvAHIBAAABnQAAAdEAAACtAQAAAwAAAp4AAAL5AAAABAAAAAQAAAAIAAAACPwAAAAA" +} \ No newline at end of file diff --git a/toolbars/07_lightfields_import/30_naive_refocus.psw b/toolbars/07_lightfields_import/30_naive_refocus.psw index d71b4de29f9..485f649a82e 100644 --- a/toolbars/07_lightfields_import/30_naive_refocus.psw +++ b/toolbars/07_lightfields_import/30_naive_refocus.psw @@ -1,29 +1,11 @@ { "connections": [ - { - "in_node": "concat_0", - "in_port": "in_frame_2", - "out_node": "colormap_0", - "out_port": "out_frame" - }, { "in_node": "network_0", "in_port": "frame", - "out_node": "concat_0", - "out_port": "out_frame" - }, - { - "in_node": "concat_0", - "in_port": "in_frame_1", "out_node": "convert_0", "out_port": "out_frame" }, - { - "in_node": "colormap_0", - "in_port": "in_frame", - "out_node": "convert_1", - "out_port": "out_frame" - }, { "in_node": "samples_from_metadata_0", "in_port": "in_frame", @@ -60,12 +42,6 @@ "out_node": "integrate_nearest_0", "out_port": "out_frame" }, - { - "in_node": "convert_1", - "in_port": "in_frame", - "out_node": "integrate_nearest_0", - "out_port": "correspondence" - }, { "in_node": "samples_refocus_0", "in_port": "uv_offset", @@ -106,35 +82,6 @@ "description": "### Naive refocusing\n\nThe simplest method of lightfields digital refocusing is to directly use the lightfield's equation to determine the target pixel position for each sample, given its position in the lightfield image and its corresponding `u` and `v` values.\n\nWhile very simple and fast, the number of samples for each pixel can vary depending on the bayer pattern and focal distance, often leading to noisy and/or low-resolution results with artifacts.\n\nNg, Ren, et al. [\"Light field photography with a hand-held plenoptic camera.\"](http://www2.ene.unb.br/mylene/PI/refs/lfcamera-150dpi.pdf) Computer Science Technical Report CSTR 2.11 (2005): 1-11.", "name": "network", "nodes": { - "colormap_0": { - "blind_data": { - "type": "possumwood::NodeData", - "value": { - "x": 510.0705871582031, - "y": 1361.0601806640625 - } - }, - "name": "colormap", - "ports": { - "type": "COLORMAP_JET" - }, - "type": "opencv/colormap" - }, - "concat_0": { - "blind_data": { - "type": "possumwood::NodeData", - "value": { - "x": 355.1289367675781, - "y": 1552.659423828125 - } - }, - "name": "concat", - "ports": { - "mode": "Horizontal", - "separation": 0 - }, - "type": "opencv/concat" - }, "convert_0": { "blind_data": { "type": "possumwood::NodeData", @@ -151,22 +98,6 @@ }, "type": "opencv/convert" }, - "convert_1": { - "blind_data": { - "type": "possumwood::NodeData", - "value": { - "x": 500.3787841796875, - "y": 1118.76513671875 - } - }, - "name": "convert", - "ports": { - "a": 2000.0, - "b": 0.0, - "mode": "CV_8U" - }, - "type": "opencv/convert" - }, "demosaic_0": { "blind_data": { "type": "possumwood::NodeData", @@ -266,8 +197,8 @@ "blind_data": { "type": "possumwood::NodeData", "value": { - "x": 407.0784606933594, - "y": 1766.50439453125 + "x": 306.48345947265625, + "y": 1516.0433349609375 } }, "connections": [ @@ -607,13 +538,13 @@ "refocus": { "in_progress_updates": false, "max": 40.0, - "min": -20.0, + "min": -30.0, "type": "linear", - "value": -20.0 + "value": -17.469999313354492 }, "resolution": { - "x": 300, - "y": 300 + "x": 1000, + "y": 1000 } }, "scene_config": { @@ -623,5 +554,5 @@ }, "type": "network", "ui_geometry": "AdnQywADAAAAAAAAAAAAAAAABqoAAAOfAAAAAQAAABkAAANUAAADnQAAAAACAAAABqsAAAAAAAAAFwAABqoAAAOf", - "ui_state": "AAAA/wAAAAD9AAAAAgAAAAAAAAGqAAAC+fwCAAAAAfsAAAAKAGcAcgBhAHAAaAEAAAB1AAAC+QAAAJsBAAADAAAAAQAAAagAAAL5/AIAAAAC+wAAABQAcAByAG8AcABlAHIAdABpAGUAcwEAAAB1AAABGwAAAHkBAAAD+wAAAAwAZQBkAGkAdABvAHIBAAABkQAAAd0AAACtAQAAAwAAA1cAAAL5AAAABAAAAAQAAAAIAAAACPwAAAAA" + "ui_state": "AAAA/wAAAAD9AAAAAgAAAAAAAAGqAAAC+fwCAAAAAfsAAAAKAGcAcgBhAHAAaAEAAAB1AAAC+QAAAJsBAAADAAAAAQAAAagAAAL5/AIAAAAC+wAAABQAcAByAG8AcABlAHIAdABpAGUAcwEAAAB1AAABGAAAAHkBAAAD+wAAAAwAZQBkAGkAdABvAHIBAAABjgAAAeAAAACtAQAAAwAAA1cAAAL5AAAABAAAAAQAAAAIAAAACPwAAAAA" } \ No newline at end of file diff --git a/toolbars/07_lightfields_import/32_naive_debayer.psw b/toolbars/07_lightfields_import/32_naive_debayer.psw index bfb4e3a4c1b..b2d8cbdef26 100644 --- a/toolbars/07_lightfields_import/32_naive_debayer.psw +++ b/toolbars/07_lightfields_import/32_naive_debayer.psw @@ -92,13 +92,13 @@ "blind_data": { "type": "possumwood::NodeData", "value": { - "x": 170.9827117919922, - "y": 912.2037353515625 + "x": 208.91445922851563, + "y": 1215.65771484375 } }, "name": "convert", "ports": { - "a": 255.0, + "a": 300.0, "b": 0.0, "mode": "CV_8U" }, @@ -108,8 +108,8 @@ "blind_data": { "type": "possumwood::NodeData", "value": { - "x": 263.4567565917969, - "y": 63.18764114379883 + "x": 301.3885192871094, + "y": 366.64166259765625 } }, "name": "demosaic", @@ -122,8 +122,8 @@ "blind_data": { "type": "possumwood::NodeData", "value": { - "x": 212.8810577392578, - "y": -102.63021087646484 + "x": 250.81280517578125, + "y": 200.8238067626953 } }, "name": "divide", @@ -136,13 +136,13 @@ "blind_data": { "type": "possumwood::NodeData", "value": { - "x": 141.62109375, - "y": 735.3259887695313 + "x": 179.55284118652344, + "y": 1038.780029296875 } }, "name": "gamma", "ports": { - "gamma": 0.800000011920929, + "gamma": 1.0, "normalization_coef": 1.0 }, "type": "opencv/gamma" @@ -151,8 +151,8 @@ "blind_data": { "type": "possumwood::NodeData", "value": { - "x": 31.595443725585938, - "y": 414.2547607421875 + "x": 69.5271987915039, + "y": 717.7088012695313 } }, "name": "refocus", @@ -162,8 +162,8 @@ "blind_data": { "type": "possumwood::NodeData", "value": { - "x": 0.9047244191169739, - "y": 617.7826538085938 + "x": 38.83647537231445, + "y": 921.2366943359375 } }, "name": "resolution", @@ -173,8 +173,8 @@ "blind_data": { "type": "possumwood::NodeData", "value": { - "x": 161.65542602539063, - "y": 596.8433837890625 + "x": 199.58717346191406, + "y": 900.2974243164063 } }, "name": "integrate_nearest", @@ -184,8 +184,8 @@ "blind_data": { "type": "possumwood::NodeData", "value": { - "x": 180.2030487060547, - "y": 404.56298828125 + "x": 218.13479614257813, + "y": 708.0170288085938 } }, "name": "interval", @@ -195,13 +195,13 @@ "blind_data": { "type": "possumwood::NodeData", "value": { - "x": 363.2323913574219, - "y": -233.33145141601563 + "x": 401.1641540527344, + "y": 70.12255859375 } }, "name": "lytro_lightfield", "ports": { - "filename": "$EXAMPLES/lytro/calibration.lfr" + "filename": "$EXAMPLES/lytro/calibration_long.lfr" }, "type": "opencv/capture/lytro_lightfield" }, @@ -209,8 +209,8 @@ "blind_data": { "type": "possumwood::NodeData", "value": { - "x": 107.2108383178711, - "y": -233.62271118164063 + "x": 145.14259338378906, + "y": 69.831298828125 } }, "name": "lytro_lightfield", @@ -223,8 +223,8 @@ "blind_data": { "type": "possumwood::NodeData", "value": { - "x": 181.19161987304688, - "y": 1103.0897216796875 + "x": 219.1233673095703, + "y": 1406.543701171875 } }, "connections": [ @@ -532,14 +532,14 @@ "blind_data": { "type": "possumwood::NodeData", "value": { - "x": 291.0875549316406, - "y": 218.84217834472656 + "x": 329.0193176269531, + "y": 522.2962036132813 } }, "name": "samples_from_metadata", "ports": { - "correct_gain": true, - "scale_compensation": 1.0 + "correct_gain": false, + "scale_compensation": 0.9990000128746033 }, "type": "opencv/lightfields/samples_from_metadata" }, @@ -547,8 +547,8 @@ "blind_data": { "type": "possumwood::NodeData", "value": { - "x": 325.108154296875, - "y": 392.1058044433594 + "x": 363.0399169921875, + "y": 695.559814453125 } }, "name": "samples_refocus", @@ -562,14 +562,14 @@ "ports": { "refocus": { "in_progress_updates": false, - "max": 30.0, + "max": 40.0, "min": -30.0, "type": "linear", - "value": -23.760000228881836 + "value": -21.670000076293945 }, "resolution": { - "x": 500, - "y": 500 + "x": 1000, + "y": 1000 } }, "scene_config": { @@ -579,5 +579,5 @@ }, "type": "network", "ui_geometry": "AdnQywADAAAAAAAAAAAAAAAABqoAAAOfAAAAAQAAABkAAANUAAADnQAAAAACAAAABqsAAAAAAAAAFwAABqoAAAOf", - "ui_state": "AAAA/wAAAAD9AAAAAgAAAAAAAAH2AAAC+fwCAAAAAfsAAAAKAGcAcgBhAHAAaAEAAAB1AAAC+QAAAJsBAAADAAAAAQAAA40AAAL5/AIAAAAC+wAAABQAcAByAG8AcABlAHIAdABpAGUAcwEAAAB1AAABSgAAAHkBAAAD+wAAAAwAZQBkAGkAdABvAHIBAAABwAAAAa4AAACtAQAAAwAAASYAAAL5AAAABAAAAAQAAAAIAAAACPwAAAAA" + "ui_state": "AAAA/wAAAAD9AAAAAgAAAAAAAAFCAAAC+fwCAAAAAfsAAAAKAGcAcgBhAHAAaAEAAAB1AAAC+QAAAJsBAAADAAAAAQAAAhAAAAL5/AIAAAAC+wAAABQAcAByAG8AcABlAHIAdABpAGUAcwEAAAB1AAABRgAAAHkBAAAD+wAAAAwAZQBkAGkAdABvAHIBAAABvAAAAbIAAACtAQAAAwAAA1cAAAL5AAAABAAAAAQAAAAIAAAACPwAAAAA" } \ No newline at end of file diff --git a/toolbars/07_lightfields_import/36_bezier_refocus.psw b/toolbars/07_lightfields_import/36_bezier_refocus.psw index c217d8db935..828ec181134 100644 --- a/toolbars/07_lightfields_import/36_bezier_refocus.psw +++ b/toolbars/07_lightfields_import/36_bezier_refocus.psw @@ -6,6 +6,18 @@ "out_node": "convert_0", "out_port": "out_frame" }, + { + "in_node": "divide_0", + "in_port": "in_frame_1", + "out_node": "demosaic_0", + "out_port": "out_frame" + }, + { + "in_node": "divide_0", + "in_port": "in_frame_2", + "out_node": "demosaic_1", + "out_port": "out_frame" + }, { "in_node": "samples_from_metadata_0", "in_port": "in_frame", @@ -37,11 +49,17 @@ "out_port": "out" }, { - "in_node": "divide_0", - "in_port": "in_frame_2", + "in_node": "demosaic_1", + "in_port": "in_frame", "out_node": "lytro_lightfield_0", "out_port": "frame" }, + { + "in_node": "demosaic_1", + "in_port": "mozaic", + "out_node": "lytro_lightfield_0", + "out_port": "mozaic" + }, { "in_node": "samples_from_metadata_0", "in_port": "metadata", @@ -49,11 +67,17 @@ "out_port": "metadata" }, { - "in_node": "divide_0", - "in_port": "in_frame_1", + "in_node": "demosaic_0", + "in_port": "in_frame", "out_node": "lytro_lightfield_1", "out_port": "frame" }, + { + "in_node": "demosaic_0", + "in_port": "mozaic", + "out_node": "lytro_lightfield_1", + "out_port": "mozaic" + }, { "in_node": "samples_refocus_0", "in_port": "in_samples", @@ -74,24 +98,52 @@ "blind_data": { "type": "possumwood::NodeData", "value": { - "x": 188.5601043701172, - "y": 766.9078979492188 + "x": 234.9210968017578, + "y": 1365.3861083984375 } }, "name": "convert", "ports": { - "a": 255.0, - "b": 0.0, + "a": 330.0, + "b": -10.0, "mode": "CV_8U" }, "type": "opencv/convert" }, + "demosaic_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 106.38545227050781, + "y": 183.65252685546875 + } + }, + "name": "demosaic", + "ports": { + "mode": "Basic" + }, + "type": "opencv/demosaic" + }, + "demosaic_1": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 371.29473876953125, + "y": 199.8055419921875 + } + }, + "name": "demosaic", + "ports": { + "mode": "Basic" + }, + "type": "opencv/demosaic" + }, "divide_0": { "blind_data": { "type": "possumwood::NodeData", "value": { - "x": 190.12985229492188, - "y": -222.81106567382813 + "x": 236.4908447265625, + "y": 375.6672058105469 } }, "name": "divide", @@ -104,13 +156,13 @@ "blind_data": { "type": "possumwood::NodeData", "value": { - "x": 158.6298370361328, - "y": 575.129638671875 + "x": 204.99082946777344, + "y": 1173.60791015625 } }, "name": "gamma", "ports": { - "gamma": 0.800000011920929, + "gamma": 1.0, "normalization_coef": 1.0 }, "type": "opencv/gamma" @@ -119,8 +171,8 @@ "blind_data": { "type": "possumwood::NodeData", "value": { - "x": -17.64237403869629, - "y": 166.61537170410156 + "x": 28.718618392944336, + "y": 765.0936279296875 } }, "name": "refocus", @@ -130,8 +182,8 @@ "blind_data": { "type": "possumwood::NodeData", "value": { - "x": 168.61422729492188, - "y": 350.9989318847656 + "x": 214.9752197265625, + "y": 949.4771728515625 } }, "name": "integrate_bezier", @@ -149,8 +201,8 @@ "blind_data": { "type": "possumwood::NodeData", "value": { - "x": 93.39353942871094, - "y": 153.0003662109375 + "x": 139.75453186035156, + "y": 751.4786376953125 } }, "name": "interval", @@ -160,13 +212,13 @@ "blind_data": { "type": "possumwood::NodeData", "value": { - "x": 338.4512939453125, - "y": -385.1968688964844 + "x": 396.119384765625, + "y": 27.521846771240234 } }, "name": "lytro_lightfield", "ports": { - "filename": "$EXAMPLES/lytro/calibration.lfr" + "filename": "$EXAMPLES/lytro/calibration_long.lfr" }, "type": "opencv/capture/lytro_lightfield" }, @@ -174,8 +226,8 @@ "blind_data": { "type": "possumwood::NodeData", "value": { - "x": 100.88335418701172, - "y": -398.96856689453125 + "x": 108.47713470458984, + "y": 34.749080657958984 } }, "name": "lytro_lightfield", @@ -188,8 +240,8 @@ "blind_data": { "type": "possumwood::NodeData", "value": { - "x": 195.9407196044922, - "y": 993.0398559570313 + "x": 242.3017120361328, + "y": 1591.51806640625 } }, "connections": [ @@ -497,14 +549,14 @@ "blind_data": { "type": "possumwood::NodeData", "value": { - "x": 216.73272705078125, - "y": -41.242637634277344 + "x": 263.0937194824219, + "y": 557.2356567382813 } }, "name": "samples_from_metadata", "ports": { - "correct_gain": true, - "scale_compensation": 1.0 + "correct_gain": false, + "scale_compensation": 0.9990000128746033 }, "type": "opencv/lightfields/samples_from_metadata" }, @@ -512,8 +564,8 @@ "blind_data": { "type": "possumwood::NodeData", "value": { - "x": 229.85321044921875, - "y": 149.68637084960938 + "x": 276.2142028808594, + "y": 748.1646118164063 } }, "name": "samples_refocus", @@ -530,7 +582,7 @@ "max": 40.0, "min": -40.0, "type": "linear", - "value": -22.479999542236328 + "value": -20.959999084472656 } }, "scene_config": { @@ -540,5 +592,5 @@ }, "type": "network", "ui_geometry": "AdnQywADAAAAAAAAAAAAAAAABqoAAAOfAAAAAQAAABkAAANUAAADnQAAAAACAAAABqsAAAAAAAAAFwAABqoAAAOf", - "ui_state": "AAAA/wAAAAD9AAAAAgAAAAAAAAJPAAAC+fwCAAAAAfsAAAAKAGcAcgBhAHAAaAEAAAB1AAAC+QAAAJsBAAADAAAAAQAAAagAAAL5/AIAAAAC+wAAABQAcAByAG8AcABlAHIAdABpAGUAcwEAAAB1AAABmgAAAHkBAAAD+wAAAAwAZQBkAGkAdABvAHIBAAACEAAAAV4AAACtAQAAAwAAArIAAAL5AAAABAAAAAQAAAAIAAAACPwAAAAA" + "ui_state": "AAAA/wAAAAD9AAAAAgAAAAAAAAGqAAAC+fwCAAAAAfsAAAAKAGcAcgBhAHAAaAEAAAB1AAAC+QAAAJsBAAADAAAAAQAAAagAAAL5/AIAAAAC+wAAABQAcAByAG8AcABlAHIAdABpAGUAcwEAAAB1AAABlAAAAHkBAAAD+wAAAAwAZQBkAGkAdABvAHIBAAACCgAAAWQAAACtAQAAAwAAA1cAAAL5AAAABAAAAAQAAAAIAAAACPwAAAAA" } \ No newline at end of file diff --git a/toolbars/08_lightfields_depth/84_bezier_lightfield.psw b/toolbars/08_lightfields_depth/84_bezier_lightfield.psw new file mode 100644 index 00000000000..40c2aad283d --- /dev/null +++ b/toolbars/08_lightfields_depth/84_bezier_lightfield.psw @@ -0,0 +1,1551 @@ +{ + "connections": [ + { + "in_node": "convert_0", + "in_port": "in_sequence", + "out_node": "bspline_to_sequence_0", + "out_port": "sequence" + }, + { + "in_node": "override_0", + "in_port": "override", + "out_node": "convert_0", + "out_port": "out_sequence" + }, + { + "in_node": "float_1", + "in_port": "in_uniforms", + "out_node": "float_0", + "out_port": "out_uniforms" + }, + { + "in_node": "network_0", + "in_port": "input", + "out_node": "float_1", + "out_port": "out_uniforms" + }, + { + "in_node": "float_3", + "in_port": "in_uniforms", + "out_node": "float_2", + "out_port": "out_uniforms" + }, + { + "in_node": "network_1", + "in_port": "input", + "out_node": "float_3", + "out_port": "out_uniforms" + }, + { + "in_node": "network_2", + "in_port": "input", + "out_node": "float_4", + "out_port": "out_uniforms" + }, + { + "in_node": "interval_0", + "in_port": "interval", + "out_node": "input_0", + "out_port": "data" + }, + { + "in_node": "interval_1", + "in_port": "interval", + "out_node": "input_1", + "out_port": "data" + }, + { + "in_node": "interval_2", + "in_port": "interval", + "out_node": "input_2", + "out_port": "data" + }, + { + "in_node": "override_0", + "in_port": "use_override", + "out_node": "input_3", + "out_port": "data" + }, + { + "in_node": "network_4", + "in_port": "sequence", + "out_node": "integrate_mosaic_0", + "out_port": "sequence" + }, + { + "in_node": "network_4", + "in_port": "sample_count", + "out_node": "integrate_mosaic_0", + "out_port": "sample_count" + }, + { + "in_node": "float_0", + "in_port": "value", + "out_node": "interval_0", + "out_port": "out" + }, + { + "in_node": "float_2", + "in_port": "value", + "out_node": "interval_0", + "out_port": "out" + }, + { + "in_node": "float_4", + "in_port": "value", + "out_node": "interval_0", + "out_port": "out" + }, + { + "in_node": "float_1", + "in_port": "value", + "out_node": "interval_1", + "out_port": "out" + }, + { + "in_node": "float_3", + "in_port": "value", + "out_node": "interval_2", + "out_port": "out" + }, + { + "in_node": "split_vec2u_0", + "in_port": "vec", + "out_node": "metadata_0", + "out_port": "size" + }, + { + "in_node": "samples_refocus_0", + "in_port": "in_samples", + "out_node": "network_3", + "out_port": "samples" + }, + { + "in_node": "override_0", + "in_port": "input", + "out_node": "network_4", + "out_port": "out_sequence" + }, + { + "in_node": "float_0", + "in_port": "in_uniforms", + "out_node": "opencv_texture_sequence_0", + "out_port": "out_uniforms" + }, + { + "in_node": "float_2", + "in_port": "in_uniforms", + "out_node": "opencv_texture_sequence_1", + "out_port": "out_uniforms" + }, + { + "in_node": "float_4", + "in_port": "in_uniforms", + "out_node": "opencv_texture_sequence_2", + "out_port": "out_uniforms" + }, + { + "in_node": "opencv_texture_sequence_2", + "in_port": "sequence", + "out_node": "override_0", + "out_port": "output" + }, + { + "in_node": "subset_0", + "in_port": "in_seq", + "out_node": "override_0", + "out_port": "output" + }, + { + "in_node": "subset_1", + "in_port": "in_seq", + "out_node": "override_0", + "out_port": "output" + }, + { + "in_node": "metadata_0", + "in_port": "sequence", + "out_node": "override_0", + "out_port": "output" + }, + { + "in_node": "integrate_mosaic_0", + "in_port": "samples", + "out_node": "samples_refocus_0", + "out_port": "out_samples" + }, + { + "in_node": "samples_to_bspline_0", + "in_port": "samples", + "out_node": "samples_refocus_0", + "out_port": "out_samples" + }, + { + "in_node": "bspline_to_sequence_0", + "in_port": "bspline", + "out_node": "samples_to_bspline_0", + "out_port": "bspline" + }, + { + "in_node": "unsigned_0", + "in_port": "value", + "out_node": "split_vec2u_0", + "out_port": "x" + }, + { + "in_node": "unsigned_1", + "in_port": "value", + "out_node": "split_vec2u_0", + "out_port": "y" + }, + { + "in_node": "opencv_texture_sequence_0", + "in_port": "sequence", + "out_node": "subset_0", + "out_port": "out_seq" + }, + { + "in_node": "opencv_texture_sequence_1", + "in_port": "sequence", + "out_node": "subset_1", + "out_port": "out_seq" + }, + { + "in_node": "unsigned_1", + "in_port": "in_uniforms", + "out_node": "unsigned_0", + "out_port": "out_uniforms" + }, + { + "in_node": "opencv_texture_sequence_0", + "in_port": "in_uniforms", + "out_node": "unsigned_1", + "out_port": "out_uniforms" + }, + { + "in_node": "opencv_texture_sequence_1", + "in_port": "in_uniforms", + "out_node": "unsigned_1", + "out_port": "out_uniforms" + }, + { + "in_node": "opencv_texture_sequence_2", + "in_port": "in_uniforms", + "out_node": "unsigned_1", + "out_port": "out_uniforms" + }, + { + "in_node": "unsigned_0", + "in_port": "in_uniforms", + "out_node": "viewport_0", + "out_port": "out_uniforms" + } + ], + "description": "### 4D Lightfields Visualisation\n\nA lightfield slices visualisation (2D image synthesis) from a Lytro input containing samples from a full 4D lightfield.\n\nThe lightfield is first resampled into a uniform grid (mosaic), any missing data is inpainted, and then transferred onto the GPU as a stack of textures. Each image is a sharp narrow-base (and noisy) version of the scene with a small offset. The resulting base image is then synthesized by additively layering each image in the mosaic, with X-Y offset based on its U-V coordinate and the \"refocus\" parameter. This is just another method of rendering a lightfield.", + "name": "network", + "nodes": { + "bspline_to_sequence_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 78.2313461303711, + "y": 685.0294189453125 + } + }, + "name": "bspline_to_sequence", + "ports": { + "uv_resolution": { + "x": 9, + "y": 9 + }, + "xy_resolution": { + "x": 600, + "y": 600 + } + }, + "type": "opencv/lightfields/bspline_to_sequence" + }, + "convert_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 367.5743713378906, + "y": 758.3499755859375 + } + }, + "name": "convert", + "ports": { + "a": 255.0, + "b": 0.0, + "mode": "CV_8U" + }, + "type": "opencv/sequence/convert" + }, + "float_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 1881.6285400390625, + "y": 1597.8311767578125 + } + }, + "name": "float", + "ports": { + "name": "offset" + }, + "type": "render/uniforms/float" + }, + "float_1": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 1880.3060302734375, + "y": 1821.1212158203125 + } + }, + "name": "float", + "ports": { + "name": "position" + }, + "type": "render/uniforms/float" + }, + "float_2": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 2495.452880859375, + "y": 1464.9610595703125 + } + }, + "name": "float", + "ports": { + "name": "offset" + }, + "type": "render/uniforms/float" + }, + "float_3": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 2496.739990234375, + "y": 1656.9407958984375 + } + }, + "name": "float", + "ports": { + "name": "position" + }, + "type": "render/uniforms/float" + }, + "float_4": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 1290.416259765625, + "y": 1598.4827880859375 + } + }, + "name": "float", + "ports": { + "name": "offset" + }, + "type": "render/uniforms/float" + }, + "input_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 910.6004028320313, + "y": 1506.4107666015625 + } + }, + "name": "refocus", + "type": "input" + }, + "input_1": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 1528.0572509765625, + "y": 1829.4351806640625 + } + }, + "name": "x_position", + "type": "input" + }, + "input_2": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 2144.4912109375, + "y": 1665.2547607421875 + } + }, + "name": "y_position", + "type": "input" + }, + "input_3": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 740.703125, + "y": 1064.7860107421875 + } + }, + "name": "use_bezier", + "type": "input" + }, + "integrate_mosaic_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 342.2331848144531, + "y": 490.0981140136719 + } + }, + "name": "integrate_mosaic", + "ports": { + "elements": 9, + "inclusion_ratio": 0.5, + "size": { + "x": 300, + "y": 300 + } + }, + "type": "opencv/lightfields/integrate_mosaic" + }, + "interval_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 1037.4981689453125, + "y": 1493.9434814453125 + } + }, + "name": "REFOCUS_VALUE", + "type": "maths/interval" + }, + "interval_1": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 1684.0360107421875, + "y": 1835.7283935546875 + } + }, + "name": "X_POSITION", + "type": "maths/interval" + }, + "interval_2": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 2300.47021484375, + "y": 1671.5479736328125 + } + }, + "name": "Y_POSITION", + "type": "maths/interval" + }, + "metadata_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 1232.7850341796875, + "y": 467.2181396484375 + } + }, + "name": "metadata", + "type": "opencv/sequence/metadata" + }, + "network_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 1875.7998046875, + "y": 2017.8482666015625 + } + }, + "connections": [ + { + "in_node": "draw_0", + "in_port": "vertex_data", + "out_node": "cgal_0", + "out_port": "vertex_data" + }, + { + "in_node": "program_0", + "in_port": "fragment_shader", + "out_node": "fragment_shader_0", + "out_port": "shader" + }, + { + "in_node": "draw_0", + "in_port": "uniforms", + "out_node": "input_0", + "out_port": "data" + }, + { + "in_node": "cgal_0", + "in_port": "mesh", + "out_node": "network_0", + "out_port": "mesh" + }, + { + "in_node": "draw_0", + "in_port": "program", + "out_node": "program_0", + "out_port": "program" + }, + { + "in_node": "program_0", + "in_port": "vertex_shader", + "out_node": "vertex_shader_0", + "out_port": "shader" + } + ], + "name": "x_samples", + "nodes": { + "cgal_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 73.14808654785156, + "y": 2103.364501953125 + } + }, + "name": "cgal", + "ports": { + "p_attr_name": "P" + }, + "type": "render/vertex_data/cgal" + }, + "draw_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 326.27069091796875, + "y": 1748.695068359375 + } + }, + "name": "draw", + "ports": { + "setup": { + "culling": "none" + } + }, + "type": "render/draw" + }, + "fragment_shader_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": -97.7811508178711, + "y": 1758.5509033203125 + } + }, + "name": "fragment_shader", + "ports": { + "source": "#version 130 \n \nout vec4 color; \n \nin vec2 uv; \n\nuniform float offset;\nuniform sampler2DArray image;\nuniform uint image_count;\n\nuniform float position;\n\nvoid main() { \n\tfloat uv_offs = 0.001*offset*round((uv.y-0.5)*float(image_count));\n\tfloat uvx = uv.x+uv_offs;\n\n\tif(uvx < 0.0 || uvx > 1.0)\n\t\tdiscard;\n\n\tcolor = texture(image, vec3(uvx, position, floor(uv.y*float(image_count))));\n} \n" + }, + "type": "render/fragment_shader" + }, + "input_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 286.94366455078125, + "y": 1573.087646484375 + } + }, + "name": "input", + "type": "input" + }, + "network_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 68.30218505859375, + "y": 1896.60595703125 + } + }, + "name": "quad", + "ports": { + "axis/primary": { + "x": 1.0, + "y": 0.0, + "z": 0.0 + }, + "axis/secondary": { + "x": 0.0, + "y": 1.0, + "z": 0.0 + }, + "origin": { + "x": 9.349278684567253e-09, + "y": 4.583226887267179e-41, + "z": 8.654956218379084e-07 + } + }, + "source": "$NODES/cgal/primitives/quad.psw", + "type": "network" + }, + "program_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 103.99114990234375, + "y": 1647.083984375 + } + }, + "name": "program", + "type": "render/program" + }, + "vertex_shader_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": -73.1933822631836, + "y": 1545.8521728515625 + } + }, + "name": "vertex_shader", + "ports": { + "source": "#version 130 \n \nin vec3 P; // position attr from the vbo \n \nuniform mat4 iProjection; // projection matrix \nuniform mat4 iModelView; // modelview matrix \n\nuniform float position;\n\nout vec2 uv; // uv texturing parameters\n\nuniform uint image_width;\nuniform uint image_height;\n \nvoid main() {\n\tfloat aspect = float(image_width) / float(image_height);\n\n\tvec3 pos = (P - 0.5) * 10.0;\n\tfloat z_scale = 10;\n\n\tif(aspect < 1.0)\n\t\tpos.x *= aspect;\n\telse\n\t\tz_scale /= aspect;\n\n\tgl_Position = iProjection * iModelView* vec4(pos.x, P.y, (position-0.5) * z_scale, 1);\n\n\tuv = P.xy;\n} \n" + }, + "type": "render/vertex_shader" + } + }, + "type": "network" + }, + "network_1": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 2493.5048828125, + "y": 1853.6678466796875 + } + }, + "connections": [ + { + "in_node": "draw_0", + "in_port": "vertex_data", + "out_node": "cgal_0", + "out_port": "vertex_data" + }, + { + "in_node": "program_0", + "in_port": "fragment_shader", + "out_node": "fragment_shader_0", + "out_port": "shader" + }, + { + "in_node": "draw_0", + "in_port": "uniforms", + "out_node": "input_0", + "out_port": "data" + }, + { + "in_node": "cgal_0", + "in_port": "mesh", + "out_node": "network_0", + "out_port": "mesh" + }, + { + "in_node": "draw_0", + "in_port": "program", + "out_node": "program_0", + "out_port": "program" + }, + { + "in_node": "program_0", + "in_port": "vertex_shader", + "out_node": "vertex_shader_0", + "out_port": "shader" + } + ], + "name": "y_samples", + "nodes": { + "cgal_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 73.14808654785156, + "y": 2103.364501953125 + } + }, + "name": "cgal", + "ports": { + "p_attr_name": "P" + }, + "type": "render/vertex_data/cgal" + }, + "draw_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 326.27069091796875, + "y": 1748.695068359375 + } + }, + "name": "draw", + "ports": { + "setup": { + "culling": "none" + } + }, + "type": "render/draw" + }, + "fragment_shader_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": -97.7811508178711, + "y": 1758.5509033203125 + } + }, + "name": "fragment_shader", + "ports": { + "source": "#version 130 \n \nout vec4 color; \n \nin vec2 uv; \n\nuniform float offset;\nuniform sampler2DArray image;\nuniform uint image_count;\n\nuniform float position;\n\nvoid main() { \n\tfloat uv_offs = 0.001*offset*round((uv.y-0.5)*float(image_count));\n\tfloat uvx = uv.x+uv_offs;\n\n\tif(uvx < 0.0 || uvx > 1.0)\n\t\tdiscard;\n\n\tcolor = texture(image, vec3(position, uvx, floor(uv.y*float(image_count))));\n} \n" + }, + "type": "render/fragment_shader" + }, + "input_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 286.94366455078125, + "y": 1573.087646484375 + } + }, + "name": "input", + "type": "input" + }, + "network_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 68.30218505859375, + "y": 1896.60595703125 + } + }, + "name": "quad", + "ports": { + "axis/primary": { + "x": 1.0, + "y": 0.0, + "z": 0.0 + }, + "axis/secondary": { + "x": 0.0, + "y": 1.0, + "z": 0.0 + }, + "origin": { + "x": 9.349278684567253e-09, + "y": 4.583226887267179e-41, + "z": 8.654956218379084e-07 + } + }, + "source": "$NODES/cgal/primitives/quad.psw", + "type": "network" + }, + "program_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 103.99114990234375, + "y": 1647.083984375 + } + }, + "name": "program", + "type": "render/program" + }, + "vertex_shader_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": -73.1933822631836, + "y": 1545.8521728515625 + } + }, + "name": "vertex_shader", + "ports": { + "source": "#version 130 \n \nin vec3 P; // position attr from the vbo \n \nuniform mat4 iProjection; // projection matrix \nuniform mat4 iModelView; // modelview matrix \n\nuniform float position;\n\nout vec2 uv; // uv texturing parameters\n\nuniform uint image_width;\nuniform uint image_height;\n \nvoid main() {\n\tfloat aspect = float(image_width) / float(image_height);\n\n\tvec3 pos = (P - 0.5) * 10.0;\n\tfloat z_scale = 10;\n\n\tif(aspect > 1.0)\n\t\tpos.x /= aspect;\n\telse\n\t\tz_scale *= aspect;\n\n\tgl_Position = iProjection * iModelView * vec4((position-0.5) * z_scale, P.y, pos.x, 1);\n\n\tuv = P.xy;\n} \n" + }, + "type": "render/vertex_shader" + } + }, + "type": "network" + }, + "network_2": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 1292.98583984375, + "y": 1798.9659423828125 + } + }, + "connections": [ + { + "in_node": "draw_0", + "in_port": "vertex_data", + "out_node": "cgal_0", + "out_port": "vertex_data" + }, + { + "in_node": "program_0", + "in_port": "fragment_shader", + "out_node": "fragment_shader_0", + "out_port": "shader" + }, + { + "in_node": "draw_0", + "in_port": "uniforms", + "out_node": "input_0", + "out_port": "data" + }, + { + "in_node": "cgal_0", + "in_port": "mesh", + "out_node": "network_0", + "out_port": "mesh" + }, + { + "in_node": "draw_0", + "in_port": "program", + "out_node": "program_0", + "out_port": "program" + }, + { + "in_node": "program_0", + "in_port": "vertex_shader", + "out_node": "vertex_shader_0", + "out_port": "shader" + } + ], + "name": "base_quad", + "nodes": { + "cgal_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 184.77627563476563, + "y": 1637.9688720703125 + } + }, + "name": "cgal", + "ports": { + "p_attr_name": "P" + }, + "type": "render/vertex_data/cgal" + }, + "draw_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 437.89886474609375, + "y": 1283.299560546875 + } + }, + "name": "draw", + "ports": { + "setup": { + "culling": "ccw" + } + }, + "type": "render/draw" + }, + "fragment_shader_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 12.57609748840332, + "y": 1295.697265625 + } + }, + "name": "fragment_shader", + "ports": { + "source": "#version 460\n \nin vec2 uv; \n\nuniform float offset;\n\nuniform sampler2DArray image;\nuniform uint image_count;\nuniform ivec2 image_indices[69];\n\nout vec4 color;\n\nvoid main() { \n\tcolor = vec4(0,0,0,1);\n\tfor(uint a=0u; a= 0.0 && coord.x <= 1.0 && coord.y >= 0.0 && coord.y <= 1.0)\n\t\t\tcolor.rgb = color.rgb + vec4(texture(image, \n\t\t\t\tvec3(coord.x, coord.y, float(a))\n\t\t\t)).rgb; \n\t}\n\tcolor /= image_count;\n} \n" + }, + "type": "render/fragment_shader" + }, + "input_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 395.7015380859375, + "y": 1144.8916015625 + } + }, + "name": "input", + "type": "input" + }, + "network_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 179.9303741455078, + "y": 1431.21044921875 + } + }, + "name": "quad", + "ports": { + "axis/primary": { + "x": 1.0, + "y": 0.0, + "z": 0.0 + }, + "axis/secondary": { + "x": 0.0, + "y": 1.0, + "z": 0.0 + }, + "origin": { + "x": 9.349278684567253e-09, + "y": 4.583226887267179e-41, + "z": 8.654956218379084e-07 + } + }, + "source": "$NODES/cgal/primitives/quad.psw", + "type": "network" + }, + "program_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 215.6193389892578, + "y": 1181.6884765625 + } + }, + "name": "program", + "type": "render/program" + }, + "vertex_shader_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 38.434810638427734, + "y": 1080.4566650390625 + } + }, + "name": "vertex_shader", + "ports": { + "source": "#version 460\n \nin vec3 P;\n \nuniform mat4 iProjection;\nuniform mat4 iModelView;\n\nuniform uint image_width;\nuniform uint image_height;\n\nout vec2 uv;\n \nvoid main() {\n\tfloat aspect = float(image_width) / float(image_height);\n\n\tvec3 pos = (P-0.5) * 10;\n\tif(aspect > 1.0)\n\t\tpos.y /= aspect;\n\telse\n\t\tpos.x *= aspect;\n\n\tgl_Position = iProjection * iModelView* vec4(-pos.x, 0.01, pos.y, 1);\n\n\t// UV parameters are just untransformed world-space position\n\tuv = vec2(P);\n} \n" + }, + "type": "render/vertex_shader" + } + }, + "type": "network" + }, + "network_3": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 230.28460693359375, + "y": 83.65266418457031 + } + }, + "connections": [ + { + "in_node": "divide_0", + "in_port": "in_frame_1", + "out_node": "demosaic_0", + "out_port": "out_frame" + }, + { + "in_node": "divide_0", + "in_port": "in_frame_2", + "out_node": "demosaic_1", + "out_port": "out_frame" + }, + { + "in_node": "override_0", + "in_port": "override", + "out_node": "divide_0", + "out_port": "out_frame" + }, + { + "in_node": "override_0", + "in_port": "input", + "out_node": "divide_1", + "out_port": "out_frame" + }, + { + "in_node": "override_0", + "in_port": "use_override", + "out_node": "input_0", + "out_port": "data" + }, + { + "in_node": "lytro_lightfield_0", + "in_port": "filename", + "out_node": "input_1", + "out_port": "data" + }, + { + "in_node": "divide_1", + "in_port": "in_frame_1", + "out_node": "lytro_lightfield_0", + "out_port": "frame" + }, + { + "in_node": "demosaic_0", + "in_port": "in_frame", + "out_node": "lytro_lightfield_0", + "out_port": "frame" + }, + { + "in_node": "demosaic_0", + "in_port": "mozaic", + "out_node": "lytro_lightfield_0", + "out_port": "mozaic" + }, + { + "in_node": "divide_1", + "in_port": "in_frame_2", + "out_node": "lytro_lightfield_1", + "out_port": "frame" + }, + { + "in_node": "demosaic_1", + "in_port": "in_frame", + "out_node": "lytro_lightfield_1", + "out_port": "frame" + }, + { + "in_node": "demosaic_1", + "in_port": "mozaic", + "out_node": "lytro_lightfield_1", + "out_port": "mozaic" + }, + { + "in_node": "samples_from_metadata_0", + "in_port": "metadata", + "out_node": "lytro_lightfield_1", + "out_port": "metadata" + }, + { + "in_node": "samples_from_metadata_0", + "in_port": "in_frame", + "out_node": "override_0", + "out_port": "output" + }, + { + "in_node": "output_0", + "in_port": "data", + "out_node": "samples_from_metadata_0", + "out_port": "samples" + } + ], + "name": "load_lightfield", + "nodes": { + "demosaic_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 218.5477294921875, + "y": 672.5836791992188 + } + }, + "name": "demosaic", + "ports": { + "mode": "Basic" + }, + "type": "opencv/demosaic" + }, + "demosaic_1": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 375.8585205078125, + "y": 673.0797729492188 + } + }, + "name": "demosaic", + "ports": { + "mode": "Basic" + }, + "type": "opencv/demosaic" + }, + "divide_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 249.8140869140625, + "y": 1017.0228881835938 + } + }, + "name": "divide", + "ports": { + "scale": 1000.0 + }, + "type": "opencv/maths/divide" + }, + "divide_1": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 544.0096435546875, + "y": 471.5848083496094 + } + }, + "name": "divide", + "ports": { + "scale": 1000.0 + }, + "type": "opencv/maths/divide" + }, + "input_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 497.0662841796875, + "y": 1297.089599609375 + } + }, + "name": "demosaic", + "type": "input" + }, + "input_1": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 261.7222900390625, + "y": 122.18209075927734 + } + }, + "name": "filename", + "type": "input" + }, + "lytro_lightfield_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 452.3363037109375, + "y": 123.17302703857422 + } + }, + "name": "lytro_lightfield", + "type": "opencv/capture/lytro_lightfield" + }, + "lytro_lightfield_1": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 642.0682373046875, + "y": 126.19127655029297 + } + }, + "name": "lytro_lightfield", + "ports": { + "filename": "$EXAMPLES/lytro/calibration.lfr" + }, + "type": "opencv/capture/lytro_lightfield" + }, + "output_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 1220.0177001953125, + "y": 1573.125244140625 + } + }, + "name": "samples", + "type": "output" + }, + "override_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 813.5855712890625, + "y": 1125.25927734375 + } + }, + "name": "override", + "type": "override" + }, + "samples_from_metadata_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 1025.96044921875, + "y": 1376.213623046875 + } + }, + "name": "samples_from_metadata", + "ports": { + "correct_gain": false, + "scale_compensation": 0.9990000128746033 + }, + "type": "opencv/lightfields/samples_from_metadata" + } + }, + "ports": { + "demosaic": true, + "filename": "$EXAMPLES/lytro/road.lfr" + }, + "type": "network" + }, + "network_4": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 555.2000122070313, + "y": 591.7935791015625 + } + }, + "connections": [ + { + "in_node": "threshold_0", + "in_port": "in_frame", + "out_node": "convert_0", + "out_port": "out_sequence" + }, + { + "in_node": "output_0", + "in_port": "data", + "out_node": "convert_1", + "out_port": "out_sequence" + }, + { + "in_node": "convert_1", + "in_port": "in_sequence", + "out_node": "inpaint_0", + "out_port": "out_Sequence" + }, + { + "in_node": "inpaint_0", + "in_port": "Sequence", + "out_node": "input_0", + "out_port": "data" + }, + { + "in_node": "convert_0", + "in_port": "in_sequence", + "out_node": "input_1", + "out_port": "data" + }, + { + "in_node": "inpaint_0", + "in_port": "mask", + "out_node": "threshold_0", + "out_port": "out_frame" + } + ], + "name": "inpaint_missing_samples", + "nodes": { + "convert_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": -1400.7911376953125, + "y": 1434.1104736328125 + } + }, + "name": "convert", + "ports": { + "a": 255.0, + "b": 0.0, + "mode": "CV_8U" + }, + "type": "opencv/sequence/convert" + }, + "convert_1": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": -941.2281494140625, + "y": 1455.388916015625 + } + }, + "name": "convert", + "ports": { + "a": 255.0, + "b": 0.0, + "mode": "CV_8U" + }, + "type": "opencv/sequence/convert" + }, + "inpaint_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": -1097.9031982421875, + "y": 1455.5091552734375 + } + }, + "name": "inpaint", + "ports": { + "method": "INPAINT_NS", + "radius": 5.0 + }, + "type": "opencv/sequence/inpaint" + }, + "input_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": -1591.5013427734375, + "y": 1291.9991455078125 + } + }, + "name": "sequence", + "type": "input" + }, + "input_1": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": -1606.0390625, + "y": 1405.0703125 + } + }, + "name": "sample_count", + "type": "input" + }, + "output_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": -730.7496948242188, + "y": 1541.3681640625 + } + }, + "name": "out_sequence", + "type": "output" + }, + "threshold_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": -1245.6099853515625, + "y": 1506.4544677734375 + } + }, + "name": "threshold", + "ports": { + "max_val": 255.0, + "threshold": 127.0, + "type": "THRESH_BINARY_INV", + "use_otsu": false, + "use_triangle": false + }, + "type": "opencv/sequence/threshold" + } + }, + "type": "network" + }, + "opencv_texture_sequence_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 1810.7177734375, + "y": 1314.0816650390625 + } + }, + "name": "opencv_texture_sequence", + "ports": { + "mode": "Linear", + "name": "image" + }, + "type": "render/uniforms/opencv_texture_sequence" + }, + "opencv_texture_sequence_1": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 2421.932861328125, + "y": 1245.1949462890625 + } + }, + "name": "opencv_texture_sequence", + "ports": { + "mode": "Linear", + "name": "image" + }, + "type": "render/uniforms/opencv_texture_sequence" + }, + "opencv_texture_sequence_2": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 1222.8216552734375, + "y": 1311.4171142578125 + } + }, + "name": "opencv_texture_sequence", + "ports": { + "mode": "Linear", + "name": "image" + }, + "type": "render/uniforms/opencv_texture_sequence" + }, + "override_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 876.85693359375, + "y": 964.2711181640625 + } + }, + "name": "override", + "type": "override" + }, + "samples_refocus_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 222.62530517578125, + "y": 251.88296508789063 + } + }, + "name": "samples_refocus", + "ports": { + "uv_offset": 0.0, + "uv_threshold": 1.0, + "xy_scale": 1.0 + }, + "type": "opencv/lightfields/samples_refocus" + }, + "samples_to_bspline_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 83.31591033935547, + "y": 479.10333251953125 + } + }, + "name": "samples_to_bspline", + "ports": { + "resolution/uv": 15, + "resolution/xy": 300 + }, + "type": "opencv/lightfields/samples_to_bspline" + }, + "split_vec2u_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 1392.630126953125, + "y": 467.882080078125 + } + }, + "name": "split_vec2u", + "type": "maths/split_vec2u" + }, + "subset_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 1634.0533447265625, + "y": 1266.7996826171875 + } + }, + "name": "subset", + "ports": { + "range/x": { + "x": -50, + "y": 50 + }, + "range/y": { + "x": 0, + "y": 0 + } + }, + "type": "opencv/sequence/subset" + }, + "subset_1": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 2259.7216796875, + "y": 1225.7244873046875 + } + }, + "name": "subset", + "ports": { + "range/x": { + "x": 0, + "y": 0 + }, + "range/y": { + "x": -50, + "y": 50 + } + }, + "type": "opencv/sequence/subset" + }, + "unsigned_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 1552.8760986328125, + "y": 357.48193359375 + } + }, + "name": "unsigned width", + "ports": { + "name": "image_width" + }, + "type": "render/uniforms/unsigned" + }, + "unsigned_1": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 1550.1810302734375, + "y": 559.4735107421875 + } + }, + "name": "unsigned height", + "ports": { + "name": "image_height" + }, + "type": "render/uniforms/unsigned" + }, + "viewport_0": { + "blind_data": { + "type": "possumwood::NodeData", + "value": { + "x": 1575.7003173828125, + "y": 218.634033203125 + } + }, + "name": "viewport", + "type": "render/uniforms/viewport" + } + }, + "ports": { + "refocus": { + "in_progress_updates": true, + "max": 5.0, + "min": -5.0, + "type": "linear", + "value": 2.2100000381469727 + }, + "use_bezier": true, + "x_position": { + "in_progress_updates": true, + "max": 1.0, + "min": 0.0, + "type": "linear", + "value": 0.29600000381469727 + }, + "y_position": { + "in_progress_updates": true, + "max": 1.0, + "min": 0.0, + "type": "linear", + "value": 0.7480000257492065 + } + }, + "scene_config": { + "end_time": 5.0, + "fps": 24.0, + "start_time": 0.0 + }, + "type": "network", + "ui_geometry": "AdnQywADAAAAAAAAAAAAAAAABqoAAAOfAAAAAAAAABQAAASlAAACnAAAAAACAAAABqsAAAAAAAAAFwAABqoAAAOf", + "ui_state": "AAAA/wAAAAD9AAAAAgAAAAAAAAKKAAAC+fwCAAAAAfsAAAAKAGcAcgBhAHAAaAEAAAB1AAAC+QAAAJsBAAADAAAAAQAAAagAAAL5/AIAAAAC+wAAABQAcAByAG8AcABlAHIAdABpAGUAcwEAAAB1AAABPQAAAHkBAAAD+wAAAAwAZQBkAGkAdABvAHIBAAABswAAAbsAAACtAQAAAwAAAncAAAL5AAAABAAAAAQAAAAIAAAACPwAAAAA" +} \ No newline at end of file