libcamera  v0.3.1+12-19bbca3c
Supporting cameras in Linux since 2019
matrix_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 matrices
6  */
7 
8 #pragma once
9 
10 #include <algorithm>
11 #include <map>
12 #include <string>
13 #include <tuple>
14 
15 #include <libcamera/base/log.h>
16 
18 
19 #include "matrix.h"
20 
21 namespace libcamera {
22 
23 LOG_DECLARE_CATEGORY(MatrixInterpolator)
24 
25 namespace ipa {
26 
27 #ifndef __DOXYGEN__
28 template<typename T, unsigned int R, unsigned int C,
29  std::enable_if_t<std::is_arithmetic_v<T>> * = nullptr>
30 #else
31 template<typename T, unsigned int R, unsigned int C>
32 #endif /* __DOXYGEN__ */
34 {
35 public:
37  {
38  reset();
39  }
40 
41  MatrixInterpolator(const std::map<unsigned int, Matrix<T, R, C>> &matrices)
42  {
43  for (const auto &pair : matrices)
44  matrices_[pair.first] = pair.second;
45  }
46 
47  ~MatrixInterpolator() {}
48 
49  void reset()
50  {
51  matrices_.clear();
52  matrices_[0] = Matrix<T, R, C>::identity();
53  }
54 
56  const std::string &key_name,
57  const std::string &matrix_name)
58  {
59  matrices_.clear();
60 
61  if (!yaml.isList()) {
62  LOG(MatrixInterpolator, Error) << "yaml object must be a list";
63  return -EINVAL;
64  }
65 
66  for (const auto &value : yaml.asList()) {
67  unsigned int ct = std::stoul(value[key_name].get<std::string>(""));
68  std::optional<Matrix<T, R, C>> matrix =
69  value[matrix_name].get<Matrix<T, R, C>>();
70  if (!matrix) {
71  LOG(MatrixInterpolator, Error) << "Failed to read matrix";
72  return -EINVAL;
73  }
74 
75  matrices_[ct] = *matrix;
76 
77  LOG(MatrixInterpolator, Debug)
78  << "Read matrix '" << matrix_name << "' for key '"
79  << key_name << "' " << ct << ": "
80  << matrices_[ct].toString();
81  }
82 
83  if (matrices_.size() < 1) {
84  LOG(MatrixInterpolator, Error) << "Need at least one matrix";
85  return -EINVAL;
86  }
87 
88  return 0;
89  }
90 
91  Matrix<T, R, C> get(unsigned int ct)
92  {
93  ASSERT(matrices_.size() > 0);
94 
95  if (matrices_.size() == 1 ||
96  ct <= matrices_.begin()->first)
97  return matrices_.begin()->second;
98 
99  if (ct >= matrices_.rbegin()->first)
100  return matrices_.rbegin()->second;
101 
102  if (matrices_.find(ct) != matrices_.end())
103  return matrices_[ct];
104 
105  /* The above four guarantee that this will succeed */
106  auto iter = matrices_.upper_bound(ct);
107  unsigned int ctUpper = iter->first;
108  unsigned int ctLower = (--iter)->first;
109 
110  double lambda = (ct - ctLower) / static_cast<double>(ctUpper - ctLower);
111  Matrix<T, R, C> ret =
112  lambda * matrices_[ctUpper] + (1.0 - lambda) * matrices_[ctLower];
113  return ret;
114  }
115 
116 private:
117  std::map<unsigned int, Matrix<T, R, C>> matrices_;
118 };
119 
120 } /* namespace ipa */
121 
122 } /* namespace libcamera */
MatrixInterpolator(const std::map< unsigned int, Matrix< T, R, C >> &matrices)
Construct a matrix interpolator from a map of matrices.
Definition: matrix_interpolator.h:41
#define LOG(category, severity)
Log a message.
Top-level libcamera namespace.
Definition: backtrace.h:17
ListAdapter asList() const
Wrap a list YamlObject in an adapter that exposes iterators.
Definition: yaml_parser.h:196
#define ASSERT(condition)
Abort program execution if assertion fails.
int readYaml(const libcamera::YamlObject &yaml, const std::string &key_name, const std::string &matrix_name)
Initialize an MatrixInterpolator instance from yaml.
Definition: matrix_interpolator.h:55
bool isList() const
Return whether the YamlObject is a list.
Definition: yaml_parser.h:153
#define LOG_DECLARE_CATEGORY(name)
Declare a category of log messages.
Matrix class.
static Matrix identity()
Construct an identity matrix.
Definition: matrix.h:44
A class representing the tree structure of the YAML content.
Definition: yaml_parser.h:25
void reset()
Reset the matrix interpolator content to a single identity matrix.
Definition: matrix_interpolator.h:49
Matrix class.
Definition: matrix.h:31
Logging infrastructure.
A YAML parser helper.
Class for storing, retrieving, and interpolating matrices.
Definition: matrix_interpolator.h:33