libcamera v0.3.1 Supporting cameras in Linux since 2019

Loading...
Searching...
No Matches
matrix.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 * Matrix and related operations
6 */
7#pragma once
8
9#include <algorithm>
10#include <cmath>
11#include <sstream>
12#include <vector>
13
14#include <libcamera/base/log.h>
15#include <libcamera/base/span.h>
16
17#include "libcamera/internal/yaml_parser.h"
18
19 namespace libcamera {
20
21 LOG_DECLARE_CATEGORY(Matrix)
22
23 namespace ipa {
24
25#ifndef __DOXYGEN__
26 template<typename T, unsigned int Rows, unsigned int Cols,
27 std::enable_if_t<std::is_arithmetic_v<T>> * = nullptr>
28#else
29 template<typename T, unsigned int Rows, unsigned int Cols>
30#endif /* __DOXYGEN__ */
31 class Matrix
32{
33 public:
34 Matrix()
35 {
36 data_.fill(static_cast<T>(0));
37 }
38
39 Matrix(const std::vector<T> &data)
40 {
41 std::copy(data.begin(), data.end(), data_.begin());
42 }
43
44 static Matrix identity()
45 {
46 Matrix ret;
47 for (size_t i = 0; i < std::min(Rows, Cols); i++)
48 ret[i][i] = static_cast<T>(1);
49 return ret;
50 }
51
52 ~Matrix() = default;
53
54 const std::string toString() const
55 {
56 std::stringstream out;
57
58 out << "Matrix { ";
59 for (unsigned int i = 0; i < Rows; i++) {
60 out << "[ ";
61 for (unsigned int j = 0; j < Cols; j++) {
62 out << (*this)[i][j];
63 out << ((j + 1 < Cols) ? ", " : " ");
64 }
65 out << ((i + 1 < Rows) ? "], " : "]");
66 }
67 out << " }";
68
69 return out.str();
70 }
71
72 Span<const T, Cols> operator[](size_t i) const
73 {
74 return Span<const T, Cols>{ &data_.data()[i * Cols], Cols };
75 }
76
77 Span<T, Cols> operator[](size_t i)
78 {
79 return Span<T, Cols>{ &data_.data()[i * Cols], Cols };
80 }
81
82#ifndef __DOXYGEN__
83 template<typename U, std::enable_if_t<std::is_arithmetic_v<U>>>
84#else
85 template<typename U>
86#endif /* __DOXYGEN__ */
87 Matrix<T, Rows, Cols> &operator*=(U d)
88 {
89 for (unsigned int i = 0; i < Rows * Cols; i++)
90 data_[i] *= d;
91 return *this;
92 }
93
94 private:
95 std::array<T, Rows * Cols> data_;
96};
97
98#ifndef __DOXYGEN__
99 template<typename T, typename U, unsigned int Rows, unsigned int Cols,
100 std::enable_if_t<std::is_arithmetic_v<T>> * = nullptr>
101#else
102 template<typename T, typename U, unsigned int Rows, unsigned int Cols>
103#endif /* __DOXYGEN__ */
104 Matrix<U, Rows, Cols> operator*(T d, const Matrix<U, Rows, Cols> &m)
105{
106 Matrix<U, Rows, Cols> result;
107
108 for (unsigned int i = 0; i < Rows; i++) {
109 for (unsigned int j = 0; j < Cols; j++)
110 result[i][j] = d * m[i][j];
111 }
112
113 return result;
114}
115
116#ifndef __DOXYGEN__
117 template<typename T, typename U, unsigned int Rows, unsigned int Cols,
118 std::enable_if_t<std::is_arithmetic_v<T>> * = nullptr>
119#else
120 template<typename T, typename U, unsigned int Rows, unsigned int Cols>
121#endif /* __DOXYGEN__ */
122 Matrix<U, Rows, Cols> operator*(const Matrix<U, Rows, Cols> &m, T d)
123{
124 return d * m;
125}
126
127#ifndef __DOXYGEN__
128 template<typename T,
129 unsigned int R1, unsigned int C1,
130 unsigned int R2, unsigned int C2,
131 std::enable_if_t<C1 == R2> * = nullptr>
132#else
133 template<typename T, unsigned int R1, unsigned int C1, unsigned int R2, unsigned in C2>
134#endif /* __DOXYGEN__ */
135 Matrix<T, R1, C2> operator*(const Matrix<T, R1, C1> &m1, const Matrix<T, R2, C2> &m2)
136{
137 Matrix<T, R1, C2> result;
138
139 for (unsigned int i = 0; i < R1; i++) {
140 for (unsigned int j = 0; j < C2; j++) {
141 T sum = 0;
142
143 for (unsigned int k = 0; k < C1; k++)
144 sum += m1[i][k] * m2[k][j];
145
146 result[i][j] = sum;
147 }
148 }
149
150 return result;
151}
152
153 template<typename T, unsigned int Rows, unsigned int Cols>
154 Matrix<T, Rows, Cols> operator+(const Matrix<T, Rows, Cols> &m1, const Matrix<T, Rows, Cols> &m2)
155{
156 Matrix<T, Rows, Cols> result;
157
158 for (unsigned int i = 0; i < Rows; i++) {
159 for (unsigned int j = 0; j < Cols; j++)
160 result[i][j] = m1[i][j] + m2[i][j];
161 }
162
163 return result;
164}
165
166#ifndef __DOXYGEN__
167 bool matrixValidateYaml(const YamlObject &obj, unsigned int size);
168#endif /* __DOXYGEN__ */
169
170} /* namespace ipa */
171
172#ifndef __DOXYGEN__
173 template<typename T, unsigned int Rows, unsigned int Cols>
174std::ostream &operator<<(std::ostream &out, const ipa::Matrix<T, Rows, Cols> &m)
175{
176 out << m.toString();
177 return out;
178}
179
180 template<typename T, unsigned int Rows, unsigned int Cols>
181 struct YamlObject::Getter<ipa::Matrix<T, Rows, Cols>> {
182 std::optional<ipa::Matrix<T, Rows, Cols>> get(const YamlObject &obj) const
183 {
184 if (!ipa::matrixValidateYaml(obj, Rows * Cols))
185 return std::nullopt;
186
187 ipa::Matrix<T, Rows, Cols> matrix;
188 T *data = &matrix[0][0];
189
190 unsigned int i = 0;
191 for (const YamlObject &entry : obj.asList()) {
192 const auto value = entry.get<T>();
193 if (!value)
194 return std::nullopt;
195
196 data[i++] = *value;
197 }
198
199 return matrix;
200 }
201};
202#endif /* __DOXYGEN__ */
203
204} /* namespace libcamera */
libcamera::YamlObject
A class representing the tree structure of the YAML content.
Definition yaml_parser.h:26
libcamera::YamlObject::get
std::optional< T > get() const
Parse the YamlObject as a T value.
Definition yaml_parser.h:165
libcamera::YamlObject::asList
ListAdapter asList() const
Wrap a list YamlObject in an adapter that exposes iterators.
Definition yaml_parser.h:196
libcamera::ipa::Matrix
Matrix class.
Definition matrix.h:32
libcamera::ipa::Matrix::operator*=
Matrix< T, Rows, Cols > & operator*=(U d)
Multiply the matrix by a scalar in-place.
Definition matrix.h:87
libcamera::ipa::Matrix::toString
const std::string toString() const
Assemble and return a string describing the matrix.
Definition matrix.h:54
libcamera::ipa::Matrix::Matrix
Matrix(const std::vector< T > &data)
Construct a matrix from supplied data.
Definition matrix.h:39
libcamera::ipa::Matrix::identity
static Matrix identity()
Construct an identity matrix.
Definition matrix.h:44
libcamera::ipa::Matrix::Matrix
Matrix()
Construct a zero matrix.
Definition matrix.h:34
libcamera::ipa::Matrix::operator[]
Span< T, Cols > operator[](size_t i)
Index to a row in the matrix.
Definition matrix.h:77
libcamera::ipa::Matrix::operator[]
Span< const T, Cols > operator[](size_t i) const
Index to a row in the matrix.
Definition matrix.h:72
log.h
Logging infrastructure.
LOG_DECLARE_CATEGORY
#define LOG_DECLARE_CATEGORY(name)
Declare a category of log messages.
Definition log.h:47
libcamera::ipa::operator*
Matrix< U, Rows, Cols > operator*(T d, const Matrix< U, Rows, Cols > &m)
Multiply the matrix by a scalar.
Definition matrix.h:104
libcamera::ipa::operator+
Matrix< T, Rows, Cols > operator+(const Matrix< T, Rows, Cols > &m1, const Matrix< T, Rows, Cols > &m2)
Matrix addition.
Definition matrix.h:154
libcamera
Top-level libcamera namespace.
Definition backtrace.h:17
libcamera::operator<<
std::ostream & operator<<(std::ostream &out, const Point &p)
Insert a text representation of a Point into an output stream.
Definition geometry.cpp:91
yaml_parser.h
A YAML parser helper.