Zivid C++ API 2.9.0+4dbba385-1
Defining the Future of 3D Machine Vision
Matrix.h
Go to the documentation of this file.
1
2
3/*******************************************************************************
4
5 * This file is part of the Zivid 3D Camera API
6
7 *
8
9 * Copyright 2015-2023 (C) Zivid AS
10
11 * All rights reserved.
12
13 *
14
15 * Zivid Software License, v1.0
16
17 *
18
19 * Redistribution and use in source and binary forms, with or without
20
21 * modification, are permitted provided that the following conditions are met:
22
23 *
24
25 * 1. Redistributions of source code must retain the above copyright notice,
26
27 * this list of conditions and the following disclaimer.
28
29 *
30
31 * 2. Redistributions in binary form must reproduce the above copyright notice,
32
33 * this list of conditions and the following disclaimer in the documentation
34
35 * and/or other materials provided with the distribution.
36
37 *
38
39 * 3. Neither the name of Zivid AS nor the names of its contributors may be used
40
41 * to endorse or promote products derived from this software without specific
42
43 * prior written permission.
44
45 *
46
47 * 4. This software, with or without modification, must not be used with any
48
49 * other 3D camera than from Zivid AS.
50
51 *
52
53 * 5. Any software provided in binary form under this license must not be
54
55 * reverse engineered, decompiled, modified and/or disassembled.
56
57 *
58
59 * THIS SOFTWARE IS PROVIDED BY ZIVID AS "AS IS" AND ANY EXPRESS OR IMPLIED
60
61 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
62
63 * MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
64
65 * DISCLAIMED. IN NO EVENT SHALL ZIVID AS OR CONTRIBUTORS BE LIABLE FOR ANY
66
67 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
68
69 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
70
71 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
72
73 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
74
75 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
76
77 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
78
79 *
80
81 * Contact: Zivid Customer Success Team <customersuccess@zivid.com>
82
83 * Info: http://www.zivid.com
84
85 ******************************************************************************/
86
87
88
89#pragma once
90
92
93#include <array>
94#include <exception>
95#include <functional>
96#include <ostream>
97#include <sstream>
98#include <string>
99
100namespace Zivid
101{
105 template<typename T, size_t rowCount, size_t colCount>
106 class Matrix
107 {
108 static_assert(rowCount > 0 && colCount > 0, "rowCount and colCount must be > 0");
109
110 private:
111 using Storage = std::array<T, rowCount * colCount>;
112
113 static constexpr bool invertSupported = ((rowCount == 4 && colCount == 4) || (rowCount == 3 && colCount == 3))
114 && (std::is_same<T, float>::value || std::is_same<T, double>::value);
115
116 public:
120 using ValueType = T;
121
125 using Iterator = typename Storage::iterator;
126
130 using ConstIterator = typename Storage::const_iterator;
131
135 static constexpr size_t rows{ rowCount };
136
140 static constexpr size_t cols{ colCount };
141
143 Matrix() = default;
144
146 Matrix(const std::string &fileName)
147 {
148 load(fileName);
149 }
150
152 explicit Matrix(const std::array<T, colCount * rowCount> &arrArr)
153 : m_mat{ arrArr }
154 {}
155
157 template<typename Iterator>
158 Matrix(Iterator beginIt, Iterator endIt)
159 {
160 if(std::distance(beginIt, endIt) != rows * cols)
161 {
162 /* NOLINT */ throw std::out_of_range(
163 "Matrix constructor got input that does not match matrix size. Expected "
164 + std::to_string(rows * cols) + " items, got " + std::to_string(std::distance(beginIt, endIt))
165 + " items.");
166 }
167
168 std::copy(beginIt, endIt, m_mat.begin());
169 }
170
172 explicit Matrix(std::initializer_list<T> values)
173 : Matrix{ values.begin(), values.end() }
174 {}
175
177 explicit Matrix(std::initializer_list<std::initializer_list<T>> values)
178 {
179 if(values.size() != rows)
180 {
181 throw std::out_of_range(
182 "Matrix constructor got input that does not match matrix size. Expected " + std::to_string(rows)
183 + " rows, got " + std::to_string(values.size()) + " rows");
184 }
185
186 auto iterator = begin();
187 for(const auto &row : values)
188 {
189 if(row.size() != cols)
190 {
191 throw std::out_of_range(
192 "Matrix constructor got input that does not match matrix size. Expected all rows to be of size "
193 + std::to_string(cols) + ", got row with " + std::to_string(row.size()) + " values");
194 }
195 for(const auto &value : row)
196 {
197 *(iterator++) = value;
198 }
199 }
200 }
201
204 {
205 return m_mat.begin();
206 }
207
210 {
211 return m_mat.end();
212 }
213
216 {
217 return m_mat.begin();
218 }
219
222 {
223 return m_mat.end();
224 }
225
228 {
229 return m_mat.cbegin();
230 }
231
234 {
235 return m_mat.cend();
236 }
237
239 T &at(size_t row, size_t col)
240 {
241 throwIfOutOfBounds(row, col);
242 return m_mat[row * cols + col];
243 }
244
246 const T &at(size_t row, size_t col) const
247 {
248 throwIfOutOfBounds(row, col);
249 return m_mat[row * cols + col];
250 }
251
253 T &operator()(size_t row, size_t col)
254 {
255 return m_mat[row * cols + col];
256 }
257
259 const T &operator()(size_t row, size_t col) const
260 {
261 return m_mat[row * cols + col];
262 }
263
265 T *data()
266 {
267 return m_mat.data();
268 }
269
271 const T *data() const
272 {
273 return m_mat.data();
274 }
275
280 void save(const std::string &fileName) const;
281
287 void load(const std::string &fileName);
288
294 template<typename Q = T, typename = typename std::enable_if<invertSupported, Q>::type>
296
299 std::string toString() const
300 {
301 std::stringstream ss;
302 ss << "[ ";
303 for(size_t row = 0; row < rowCount; row++)
304 {
305 ss << (row == 0 ? "[" : "\n [");
306 for(size_t col = 0; col < colCount; col++)
307 {
308 const auto value{ m_mat[row * colCount + col] };
309 ss << (value >= 0 ? " " : "") << std::to_string(value);
310 ss << (col == colCount - 1 ? "" : ", ");
311 }
312 ss << (row == rowCount - 1 ? "]" : "], ");
313 }
314 ss << " ]";
315 return ss.str();
316 }
317
318 private:
319 static void throwIfOutOfBounds(size_t row, size_t col)
320 {
321 if(row >= rows)
322 {
323 throw std::out_of_range{ "Trying to access row with index " + std::to_string(row)
324 + ", but allowed range is [0, " + std::to_string(rows - 1) + "]" };
325 }
326 if(col >= cols)
327 {
328 throw std::out_of_range{ "Trying to access column with index " + std::to_string(col)
329 + ", but allowed range is [0, " + std::to_string(cols - 1) + "]" };
330 }
331 }
332
333 Storage m_mat{};
334 };
335
337 template<typename T, size_t rowCount, size_t colCount>
338 std::ostream &operator<<(std::ostream &stream, const Matrix<T, rowCount, colCount> &matrix)
339 {
340 return stream << matrix.toString();
341 }
342
347
352
357
362
363#ifndef NO_DOC
365 namespace Detail
366 {
368 saveFloatMatrix(const float *data, size_t rowCount, size_t colCount, const std::string &fileName);
369
371 loadFloatMatrix(float *data, size_t rowCount, size_t colCount, const std::string &fileName);
372 } // namespace Detail
373#endif
374
375#ifndef NO_DOC
376 extern template ZIVID_CORE_EXPORT Matrix<float, 4, 4> Matrix<float, 4, 4>::inverse<float, float>() const;
377
378 extern template ZIVID_CORE_EXPORT Matrix<double, 4, 4> Matrix<double, 4, 4>::inverse<double, double>() const;
379
380 extern template ZIVID_CORE_EXPORT Matrix<float, 3, 3> Matrix<float, 3, 3>::inverse<float, float>() const;
381
382 extern template ZIVID_CORE_EXPORT Matrix<double, 3, 3> Matrix<double, 3, 3>::inverse<double, double>() const;
383
384 template<typename T, size_t rowCount, size_t colCount>
385 void Matrix<T, rowCount, colCount>::save(const std::string &fileName) const
386 {
387 static_assert(std::is_same<T, float>::value, "Saving matrices of this type is not supported");
388
389 Detail::saveFloatMatrix(data(), rowCount, colCount, fileName);
390 }
391
392 template<typename T, size_t rowCount, size_t colCount>
393 void Matrix<T, rowCount, colCount>::load(const std::string &fileName)
394 {
395 static_assert(std::is_same<T, float>::value, "Loading matrices of this type is not supported");
396
397 Detail::loadFloatMatrix(data(), rowCount, colCount, fileName);
398 }
399
400#endif
401
402} // namespace Zivid
#define ZIVID_CORE_EXPORT
Definition: CoreExport.h:101
A fixed size matrix in row major order
Definition: Matrix.h:107
static constexpr size_t rows
The number of rows in the matrix
Definition: Matrix.h:135
T ValueType
The type stored in the matrix
Definition: Matrix.h:120
T * data()
Pointer to the underlying data
Definition: Matrix.h:265
void load(const std::string &fileName)
Load the matrix from the given file
ConstIterator begin() const
Iterator to the beginning of the matrix
Definition: Matrix.h:215
void save(const std::string &fileName) const
Save the matrix to the given file
typename Storage::iterator Iterator
The matrix iterator type for mutable access. It iterates over individual matrix elements in row major...
Definition: Matrix.h:125
Matrix(Iterator beginIt, Iterator endIt)
Constructor
Definition: Matrix.h:158
Matrix(std::initializer_list< T > values)
Constructor
Definition: Matrix.h:172
Matrix(const std::array< T, colCount *rowCount > &arrArr)
Constructor
Definition: Matrix.h:152
Matrix(const std::string &fileName)
Load the matrix from a file
Definition: Matrix.h:146
const T * data() const
Pointer to the underlying data
Definition: Matrix.h:271
static constexpr size_t cols
The number of columns in the matrix
Definition: Matrix.h:140
Iterator begin()
Iterator to the beginning of the matrix
Definition: Matrix.h:203
Matrix()=default
Constructor
ConstIterator cbegin() const
Iterator to the beginning of the matrix
Definition: Matrix.h:227
T & at(size_t row, size_t col)
Access specified element with bounds checking
Definition: Matrix.h:239
std::string toString() const
Get string representation of the Matrix
Definition: Matrix.h:299
ConstIterator end() const
Iterator to the end of the matrix
Definition: Matrix.h:221
Matrix(std::initializer_list< std::initializer_list< T > > values)
Constructor
Definition: Matrix.h:177
const T & at(size_t row, size_t col) const
Access specified element with bounds checking
Definition: Matrix.h:246
const T & operator()(size_t row, size_t col) const
Access specified element without bounds checking
Definition: Matrix.h:259
Iterator end()
Iterator to the end of the matrix
Definition: Matrix.h:209
ZIVID_CORE_EXPORT Matrix inverse() const
Get the inverse of this matrix
ConstIterator cend() const
Iterator to the end of the matrix
Definition: Matrix.h:233
T & operator()(size_t row, size_t col)
Access specified element without bounds checking
Definition: Matrix.h:253
typename Storage::const_iterator ConstIterator
The matrix iterator type for immutable access. It iterates over individual matrix elements in row maj...
Definition: Matrix.h:130
The main Zivid namespace. All Zivid code is found here
Definition: Application.h:99
std::ostream & operator<<(std::ostream &stream, const Array2D< T > &array)
Serialize array information to a stream
Definition: Array2D.h:243