libcamera v0.7.2 Supporting cameras in Linux since 2019

Loading...
Searching...
No Matches
interpolator.h
Go to the documentation of this file.
1/* SPDX-License-Identifier: LGPL-2.1-or-later */
2/*
3 * Copyright (C) 2024, Paul Elder <paul.elder@ideasonboard.com>
4 *
5 * Helper class for interpolating maps of objects
6 */
7
8#pragma once
9
10#include <algorithm>
11#include <cmath>
12#include <map>
13#include <string>
14#include <tuple>
15
16#include <libcamera/base/log.h>
17
18#include "libcamera/internal/value_node.h"
19
20 namespace libcamera {
21
22 LOG_DECLARE_CATEGORY(Interpolator)
23
24 namespace ipa {
25
26 template<typename T>
27 class Interpolator
28{
29 public:
30 Interpolator() = default;
31 Interpolator(const std::map<unsigned int, T> &data)
32 : data_(data)
33 {
34 }
35 Interpolator(std::map<unsigned int, T> &&data)
36 : data_(std::move(data))
37 {
38 }
39
40 ~Interpolator() = default;
41
42 int readYaml(const ValueNode &yaml,
43 const std::string &key_name,
44 const std::string &value_name)
45 {
46 data_.clear();
47 lastInterpolatedKey_.reset();
48
49 if (yaml.isEmpty())
50 return -ENOENT;
51
52 if (!yaml.isList()) {
53 LOG(Interpolator, Error) << "yaml object must be a list";
54 return -EINVAL;
55 }
56
57 for (const auto &value : yaml.asList()) {
58 unsigned int ct = std::stoul(value[key_name].get<std::string>(""));
59 std::optional<T> data =
60 value[value_name].get<T>();
61 if (!data) {
62 return -EINVAL;
63 }
64
65 data_[ct] = *data;
66 }
67
68 if (data_.size() < 1) {
69 LOG(Interpolator, Error) << "Need at least one element";
70 return -EINVAL;
71 }
72
73 return 0;
74 }
75
76 void setData(std::map<unsigned int, T> &&data)
77 {
78 data_ = std::move(data);
79 lastInterpolatedKey_.reset();
80 }
81
82 const std::map<unsigned int, T> &data() const
83 {
84 return data_;
85 }
86
87 const T &getInterpolated(unsigned int key)
88 {
89 ASSERT(data_.size() > 0);
90
91 if (lastInterpolatedKey_.has_value() &&
92 *lastInterpolatedKey_ == key)
93 return lastInterpolatedValue_;
94
95 auto it = data_.lower_bound(key);
96
97 if (it == data_.begin())
98 return it->second;
99
100 if (it == data_.end())
101 return std::prev(it)->second;
102
103 if (it->first == key)
104 return it->second;
105
106 auto it2 = std::prev(it);
107 double lambda = (key - it2->first) / static_cast<double>(it->first - it2->first);
108 interpolate(it2->second, it->second, lastInterpolatedValue_, lambda);
109 lastInterpolatedKey_ = key;
110
111 return lastInterpolatedValue_;
112 }
113
114 void interpolate(const T &a, const T &b, T &dest, double lambda)
115 {
116 dest = a * (1.0 - lambda) + b * lambda;
117 }
118
119 private:
120 std::map<unsigned int, T> data_;
121 T lastInterpolatedValue_;
122 std::optional<unsigned int> lastInterpolatedKey_;
123};
124
125} /* namespace ipa */
126
127} /* namespace libcamera */
libcamera::ValueNode
A class representing a tree structure of values.
Definition value_node.h:27
libcamera::ValueNode::isEmpty
bool isEmpty() const
Return whether the ValueNode is an empty.
Definition value_node.h:199
libcamera::ValueNode::asList
ListAdapter asList()
Wrap a list ValueNode in an adapter that exposes iterators.
Definition value_node.h:230
libcamera::ValueNode::isList
bool isList() const
Return whether the ValueNode is a list.
Definition value_node.h:191
libcamera::ipa::Interpolator
Class for storing, retrieving, and interpolating objects.
Definition interpolator.h:28
libcamera::ipa::Interpolator::getInterpolated
const T & getInterpolated(unsigned int key)
Retrieve an interpolated value for the given key.
Definition interpolator.h:87
libcamera::ipa::Interpolator::Interpolator
Interpolator(const std::map< unsigned int, T > &data)
Construct an interpolator from a map of objects.
Definition interpolator.h:31
libcamera::ipa::Interpolator::setData
void setData(std::map< unsigned int, T > &&data)
Set the internal map.
Definition interpolator.h:76
libcamera::ipa::Interpolator::Interpolator
Interpolator()=default
Construct an empty interpolator.
libcamera::ipa::Interpolator::data
const std::map< unsigned int, T > & data() const
Access the internal map.
Definition interpolator.h:82
libcamera::ipa::Interpolator::readYaml
int readYaml(const ValueNode &yaml, const std::string &key_name, const std::string &value_name)
Initialize an Interpolator instance from yaml.
Definition interpolator.h:42
libcamera::ipa::Interpolator::Interpolator
Interpolator(std::map< unsigned int, T > &&data)
Construct an interpolator from a map of objects.
Definition interpolator.h:35
libcamera::ipa::Interpolator::interpolate
void interpolate(const T &a, const T &b, T &dest, double lambda)
Interpolate between two instances of T.
Definition interpolator.h:114
log.h
Logging infrastructure.
LOG_DECLARE_CATEGORY
#define LOG_DECLARE_CATEGORY(name)
Declare a category of log messages.
Definition log.h:51
LOG
#define LOG(category, severity)
Log a message.
Definition log.h:155
ASSERT
#define ASSERT(condition)
Abort program execution if assertion fails.
Definition log.h:159
libcamera::ipa
The IPA (Image Processing Algorithm) namespace.
Definition af.cpp:58
libcamera
Top-level libcamera namespace.
Definition backtrace.h:17
value_node.h
Data structure to manage tree of values.