Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
vpFeatureLuminanceMapping.cpp
1/*
2 * ViSP, open source Visual Servoing Platform software.
3 * Copyright (C) 2005 - 2024 by Inria. All rights reserved.
4 *
5 * This software is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 * See the file LICENSE.txt at the root directory of this source
10 * distribution for additional information about the GNU GPL.
11 *
12 * For using ViSP with software that can not be combined with the GNU
13 * GPL, please contact Inria about acquiring a ViSP Professional
14 * Edition License.
15 *
16 * See https://visp.inria.fr for more information.
17 *
18 * This software was developed at:
19 * Inria Rennes - Bretagne Atlantique
20 * Campus Universitaire de Beaulieu
21 * 35042 Rennes Cedex
22 * France
23 *
24 * If you have questions regarding the use of this file, please contact
25 * Inria at visp@inria.fr
26 *
27 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
28 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
29 *
30 * Description:
31 * Luminance dimensionality reduction features
32 */
33
34#include <visp3/visual_features/vpFeatureLuminanceMapping.h>
35#if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
36#ifdef VISP_HAVE_MODULE_IO
37#include <visp3/io/vpImageIo.h>
38#endif
40
41// vpLuminanceMapping
42
44{
45 const unsigned h = I.getHeight();
46 const unsigned w = I.getWidth();
47 if (h < 2 * border || w < 2 * border) {
48 throw vpException(vpException::dimensionError, "Image is smaller than required border crop");
49 }
50 Ivec.resize((h - 2 * border) * (w - 2 * border));
51 unsigned l = 0;
52 for (unsigned i = border; i < h - border; ++i) {
53 for (unsigned j = border; j < w - border; ++j) {
54 Ivec[l++] = static_cast<double>(I[i][j]);
55 }
56 }
57}
58
60{
61 const unsigned h = I.getHeight();
62 const unsigned w = I.getWidth();
63 if (h < 2 * border || w < 2 * border) {
64 throw vpException(vpException::dimensionError, "Image is smaller than required border crop");
65 }
66 Imat.resize((h - 2 * border), (w - 2 * border), false, false);
67 for (unsigned i = border; i < h - border; ++i) {
68 for (unsigned j = border; j < w - border; ++j) {
69 Imat[i - border][j - border] = static_cast<double>(I[i][j]);
70 }
71 }
72}
73
74// vpLuminancePCA
75
76vpLuminancePCA::vpLuminancePCA(const std::shared_ptr<vpMatrix> &basis, const std::shared_ptr<vpColVector> &mean, const vpColVector &explainedVariance)
77 : vpLuminanceMapping(basis->getRows())
78{
79 m_Ih = m_Iw = 0;
80 init(basis, mean, explainedVariance);
81}
82
83void vpLuminancePCA::init(const std::shared_ptr<vpMatrix> &basis, const std::shared_ptr<vpColVector> &mean, const vpColVector &variance)
84{
85 if (basis->getCols() != mean->getRows()) {
86 throw vpException(vpException::dimensionError, "PCA mean and basis should have the same number of inputs");
87 }
88 if (variance.getRows() != basis->getRows()) {
89 throw vpException(vpException::dimensionError, "PCA explained variance should have the same size as the subspace");
90 }
91 m_mappingSize = basis->getRows();
92 m_basis = basis;
93 m_mean = mean;
94 m_explainedVariance = variance;
96}
97
99{
100 *this = other;
101}
102
104{
105 m_basis = other.m_basis;
106 m_mean = other.m_mean;
107 m_explainedVariance = other.m_explainedVariance;
109 m_border = other.m_border;
110 m_Ivec = other.m_Ivec;
111 m_Ih = other.m_Ih;
112 m_Iw = other.m_Iw;
113
114 return *this;
115}
116
118{
119 m_Ih = I.getHeight() - 2 * m_border;
120 m_Iw = I.getWidth() - 2 * m_border;
121 imageAsVector(I, m_Ivec, m_border);
122
123 m_Ivec -= *m_mean;
124 s = (*m_basis) * m_Ivec;
125}
126
128{
129 const vpColVector vI = ((*m_basis).transpose() * s + (*m_mean));
130 I.resize(m_Ih, m_Iw);
131 // Vector to image
132 for (unsigned int i = 0; i < m_Ih; ++i) {
133 for (unsigned int j = 0; j < m_Iw; ++j) {
134 I[i][j] = static_cast<unsigned char>(vI[i * m_Iw + j]);
135 }
136 }
137}
138
140{
141 L = (*m_basis) * LI;
142}
143
144vpLuminancePCA vpLuminancePCA::load(const std::string &basisFilename, const std::string &meanFilename, const std::string &explainedVarianceFile)
145{
146 std::shared_ptr<vpMatrix> basis = std::make_shared<vpMatrix>();
147 std::shared_ptr<vpColVector> mean = std::make_shared<vpColVector>();
148 vpColVector explainedVariance;
149 vpMatrix::loadMatrix(basisFilename, *basis, true);
150 vpMatrix::loadMatrix(meanFilename, *mean, true);
151 vpMatrix::loadMatrix(explainedVarianceFile, explainedVariance, true);
152
153 if (mean->getCols() > 1) {
155 "Read something that was not a column vector when trying to load the PCA mean vector");
156 }
157 if (explainedVariance.getCols() > 1) {
159 "Read something that was not a column vector when trying to load the PCA components explained variance");
160 }
161 if (basis->getCols() != mean->getRows()) {
162 std::stringstream ss;
163 ss << "Error when loading PCA from binary files";
164 ss << "The basis matrix had dimensions (" << basis->getRows() << ", " << basis->getCols() << ")";
165 ss << " and the mean vector had size " << mean->getRows() << ".";
166 ss << "You may be loading data from two different PCAs";
168 }
169
170 return vpLuminancePCA(basis, mean, explainedVariance);
171}
172
173void vpLuminancePCA::save(const std::string &basisFilename, const std::string &meanFilename, const std::string &explainedVarianceFile) const
174{
175 if (m_basis.get() == nullptr || m_mean.get() == nullptr) {
177 "Tried to save a PCA projection that was uninitialized");
178 }
179 if (m_basis->size() == 0 || m_mean->getCols() == 0 || m_basis->getCols() != m_mean->getRows()) {
181 "Tried to save a PCA projection but there are issues with the basis and mean dimensions");
182 }
183 vpMatrix::saveMatrix(basisFilename, *m_basis, true);
184 vpMatrix::saveMatrix(meanFilename, *m_mean, true);
185 vpMatrix::saveMatrix(explainedVarianceFile, m_explainedVariance, true);
186}
187
188vpLuminancePCA vpLuminancePCA::learn(const std::vector<vpImage<unsigned char>> &images, const unsigned int projectionSize, const unsigned int border)
189{
190 vpMatrix matrix;
191 for (unsigned int i = 0; i < static_cast<unsigned int>(images.size()); ++i) {
192 const vpImage<unsigned char> &I = images[i];
193 if (i == 0) {
194 matrix.resize(static_cast<unsigned int>(images.size()), (I.getHeight() - 2 * border) * (I.getWidth() - 2 * border));
195 }
196 if ((I.getHeight() - 2 * border) * (I.getWidth() - 2 * border) != matrix.getCols()) {
197 throw vpException(vpException::badValue, "Not all images have the same dimensions when learning pca");
198 }
199 for (unsigned j = border; j < I.getHeight() - border; ++j) {
200 for (unsigned k = border; k < I.getWidth() - border; ++k) {
201 matrix[i][(j - border) * (I.getWidth() - 2 * border) + k - border] = I[j][k];
202 }
203 }
204 }
205
206 return vpLuminancePCA::learn(matrix.transpose(), projectionSize);
207}
208
209#ifdef VISP_HAVE_MODULE_IO
210vpLuminancePCA vpLuminancePCA::learn(const std::vector<std::string> &imageFiles, const unsigned int projectionSize, const unsigned int border)
211{
212 vpMatrix matrix;
214 for (unsigned int i = 0; i < static_cast<unsigned int>(imageFiles.size()); ++i) {
215 vpImageIo::read(I, imageFiles[i]);
216 if (i == 0) {
217 matrix.resize(static_cast<unsigned int>(imageFiles.size()), (I.getHeight() - 2 * border) * (I.getWidth() - 2 * border));
218 }
219 if ((I.getHeight() - 2 * border) * (I.getWidth() - 2 * border) != matrix.getCols()) {
220 throw vpException(vpException::badValue, "Not all images have the same dimensions when learning pca");
221 }
222 for (unsigned j = border; j < I.getHeight() - border; ++j) {
223 for (unsigned k = border; k < I.getWidth() - border; ++k) {
224 matrix[i][(j - border) * (I.getWidth() - 2 * border) + k - border] = I[j][k];
225 }
226 }
227 }
228 return vpLuminancePCA::learn(matrix.transpose(), projectionSize);
229}
230#endif
231
232vpLuminancePCA vpLuminancePCA::learn(const vpMatrix &images, const unsigned int projectionSize)
233{
234 if (projectionSize > images.getRows() || projectionSize > images.getCols()) {
235 throw vpException(vpException::badValue, "Cannot use a subspace greater than the data dimensions (number of pixels or images)");
236 }
237 if (images.getRows() < images.getCols()) {
238 throw vpException(vpException::badValue, "Cannot compute SVD when there are more images (columns) than pixels (rows)");
239 }
240 // Mean computation
241 vpColVector mean(images.getRows(), 0.0);
242 for (unsigned i = 0; i < images.getCols(); ++i) {
243 mean += images.getCol(i);
244 }
245 mean /= images.getCols();
246
247 // Before SVD, center data
248 vpMatrix centered(images.getRows(), images.getCols());
249 for (unsigned i = 0; i < centered.getRows(); ++i) {
250 for (unsigned j = 0; j < centered.getCols(); ++j) {
251 centered[i][j] = images[i][j] - mean[i];
252 }
253 }
254
255 vpColVector eigenValues;
256 vpMatrix V;
257 centered.svd(eigenValues, V);
258 vpMatrix U(centered.getRows(), projectionSize);
259 for (unsigned i = 0; i < centered.getRows(); ++i) {
260 for (unsigned j = 0; j < projectionSize; ++j) {
261 U[i][j] = centered[i][j];
262 }
263 }
264 double cumEigenValues = eigenValues.sum();
265 vpColVector componentsExplainedVar(eigenValues, 0, projectionSize);
266 componentsExplainedVar /= cumEigenValues;
267 std::shared_ptr<vpMatrix> basis = std::make_shared<vpMatrix>(U.t());
268 std::shared_ptr<vpColVector> meanPtr = std::make_shared<vpColVector>(mean);
269 return vpLuminancePCA(basis, meanPtr, componentsExplainedVar);
270}
271
272//vpMatrixZigZagIndex
274
275void vpLuminanceDCT::vpMatrixZigZagIndex::init(unsigned rows, unsigned cols)
276{
277 // Adapted from https://www.geeksforgeeks.org/print-matrix-in-zig-zag-fashion/
278 m_colIndex.resize(rows * cols);
279 m_rowIndex.resize(rows * cols);
280 m_rows = rows;
281 m_cols = cols;
282 int rowCount = static_cast<int>(rows);
283 int colCount = static_cast<int>(cols);
284
285 unsigned int index = 0;
286 int row = 0, col = 0;
287
288 bool row_inc = 0;
289
290 int mindim = std::min(rowCount, colCount);
291 for (int len = 1; len <= mindim; ++len) {
292 for (int i = 0; i < len; ++i) {
293 m_rowIndex[index] = row;
294 m_colIndex[index] = col;
295 ++index;
296 if (i + 1 == len) {
297 break;
298 }
299
300 if (row_inc) {
301 ++row;
302 --col;
303 }
304 else {
305 --row;
306 ++col;
307 }
308 }
309
310 if (len == mindim) {
311 break;
312 }
313
314 if (row_inc)
315 ++row, row_inc = false;
316 else
317 ++col, row_inc = true;
318 }
319
320 // Update the indexes of row and col variable
321 if (row == 0) {
322 if (col == rowCount - 1) {
323 ++row;
324 }
325 else {
326 ++col;
327 }
328 row_inc = 1;
329 }
330 else {
331 if (row == colCount - 1) {
332 ++col;
333 }
334 else {
335 ++row;
336 }
337 row_inc = 0;
338 }
339
340 // Print the next half zig-zag pattern
341 int maxdim = std::max(rowCount, rowCount) - 1;
342 for (int len, diag = maxdim; diag > 0; --diag) {
343
344 if (diag > mindim) {
345 len = mindim;
346 }
347 else {
348 len = diag;
349 }
350
351 for (int i = 0; i < len; ++i) {
352 m_rowIndex[index] = row;
353 m_colIndex[index] = col;
354 ++index;
355
356 if (i + 1 == len) {
357 break;
358 }
359
360 if (row_inc) {
361 ++row;
362 --col;
363 }
364 else {
365 ++col;
366 --row;
367 }
368 }
369
370 if (row == 0 || col == rowCount - 1) {
371 if (col == rowCount - 1) {
372 ++row;
373 }
374 else {
375 ++col;
376 }
377 row_inc = true;
378 }
379
380 else if (col == 0 || row == colCount - 1) {
381 if (row == colCount - 1) {
382 ++col;
383 }
384 else {
385 ++row;
386 }
387 row_inc = false;
388 }
389 }
390}
391
392void vpLuminanceDCT::vpMatrixZigZagIndex::getValues(const vpMatrix &m, unsigned int start, unsigned int end, vpColVector &s) const
393{
394 if (m.getRows() != m_rows || m.getCols() != m_cols) {
395 throw vpException(vpException::dimensionError, "Input matrix has wrong dimensions");
396 }
397
398 if (end <= start) {
399 throw vpException(vpException::dimensionError, "End index should be > to the start index");
400 }
401
402 s.resize(end - start, false);
403
404 for (unsigned index = start; index < end; ++index) {
405 s[index - start] = m[m_rowIndex[index]][m_colIndex[index]];
406 }
407}
408
409void vpLuminanceDCT::vpMatrixZigZagIndex::setValues(const vpColVector &s, unsigned int start, vpMatrix &m) const
410{
411 if (m.getRows() != m_rows || m.getCols() != m_cols) {
412 throw vpException(vpException::dimensionError, "Input matrix has wrong dimensions");
413 }
414
415 if (start + s.size() > m.size()) {
416 throw vpException(vpException::dimensionError, "Start index combined to vector size exceeds matrix size");
417 }
418
419 for (unsigned index = start; index < start + s.size(); ++index) {
420 m[m_rowIndex[index]][m_colIndex[index]] = s[index - start];
421 }
422}
423
424// vpLuminanceDCT
425
427{
428 *this = other;
429}
430
432{
433 m_Ih = I.getHeight() - 2 * m_border;
434 m_Iw = I.getWidth() - 2 * m_border;
435 if (m_Imat.getCols() != m_Ih || m_Imat.getRows() != m_Iw) {
436 computeDCTMatrices(m_Ih, m_Iw);
437 m_zigzag.init(m_Ih, m_Iw);
438 }
441 m_zigzag.getValues(m_dct, 0, m_mappingSize, s);
442}
443
444void vpLuminanceDCT::computeDCTMatrix(vpMatrix &D, unsigned int n) const
445{
446 D.resize(n, n, false, false);
447 for (unsigned i = 0; i < n; i++) {
448 D[0][i] = 1.0 / sqrt(n);
449 }
450 double alpha = sqrt(2./(n));
451 for (unsigned int i = 1; i < n; i++) {
452 for (unsigned int j = 0; j < n; j++) {
453 D[i][j] = alpha*cos((2 * j + 1) * i * M_PI / (2.0 * n));
454 }
455 }
456}
457
458void vpLuminanceDCT::computeDCTMatrices(unsigned int rows, unsigned int cols)
459{
460 computeDCTMatrix(m_Dcols, rows);
461 computeDCTMatrix(m_Drows, cols);
462 m_Drows = m_Drows.transpose();
463}
464
466{
467 vpMatrix dctCut(m_dct.getRows(), m_dct.getCols(), 0.0);
468 m_zigzag.setValues(s, 0, dctCut);
469 const vpMatrix Ir = m_Dcols.t() * dctCut * m_Drows.t();
470 I.resize(Ir.getRows(), Ir.getCols());
471 for (unsigned int i = 0; i < I.getRows(); ++i) {
472 for (unsigned int j = 0; j < I.getCols(); ++j) {
473 I[i][j] = static_cast<unsigned char>(std::max(0.0, std::min(Ir[i][j], 255.0)));
474 }
475 }
476}
477
479{
480 const vpMatrix LIT = LI.t();
481 for (unsigned int dof = 0; dof < 6; ++dof) {
482 m_dIdrPlanes[dof].resize(m_Ih, m_Iw, false, false);
483 memcpy(m_dIdrPlanes[dof].data, LIT[dof], m_Ih * m_Iw * sizeof(double));
484 }
485
486 L.resize(m_mappingSize, 6, false, false);
487 vpMatrix dTddof(m_Ih, m_Iw);
488 vpColVector column;
489 for (unsigned int dof = 0; dof < 6; ++dof) {
490 dTddof = m_Dcols * m_dIdrPlanes[dof] * m_Drows;
491 m_zigzag.getValues(dTddof, 0, m_mappingSize, column);
492 for (unsigned int row = 0; row < L.getRows(); ++row) {
493 L[row][dof] = column[row];
494 }
495 }
496}
497
498// Feature luminance mapping
499
501unsigned int h, unsigned int w, double Z, std::shared_ptr<vpLuminanceMapping> mapping)
502{
503 init(cam, h, w, Z, mapping);
504}
505
506vpFeatureLuminanceMapping::vpFeatureLuminanceMapping(const vpFeatureLuminance &luminance, std::shared_ptr<vpLuminanceMapping> mapping)
507{
508 init(luminance, mapping);
509}
514
516{
517 dim_s = 0;
518 m_featI.init(0, 0, 0.0);
519 m_mapping = nullptr;
520}
521
523 const vpCameraParameters &cam, unsigned int h, unsigned int w, double Z,
524 std::shared_ptr<vpLuminanceMapping> mapping)
525{
526 m_featI.init(h, w, Z);
527 m_featI.setCameraParameters(cam);
528 m_mapping = mapping;
529 m_mapping->setBorder(m_featI.getBorder());
530 dim_s = m_mapping->getProjectionSize();
531 s.resize(dim_s, true);
532}
533void vpFeatureLuminanceMapping::init(const vpFeatureLuminance &luminance, std::shared_ptr<vpLuminanceMapping> mapping)
534{
535 m_featI = luminance;
536 m_mapping = mapping;
537 dim_s = m_mapping->getProjectionSize();
538 m_mapping->setBorder(m_featI.getBorder());
539 s.resize(dim_s, true);
540}
541
543{
544 dim_s = f.dim_s;
545 s = f.s;
546 m_mapping = f.m_mapping;
547 m_featI = f.m_featI;
548 return *this;
549}
554
556{
557 m_featI.buildFrom(I);
558 m_featI.interaction(m_LI);
559 m_mapping->map(I, s);
560}
561
563{
564 if (select != FEATURE_ALL) {
565 throw vpException(vpException::notImplementedError, "cannot compute error on subset of a mapping");
566 }
568 error(s_star, e);
569 return e;
570}
571
573{
574 e.resize(dim_s, false);
575 for (unsigned int i = 0; i < dim_s; i++) {
576 e[i] = s[i] - s_star[i];
577 }
578}
579
581{
582 if (select != FEATURE_ALL) {
583 throw vpException(vpException::notImplementedError, "cannot compute interaction matrix for a subset of a mapping");
584 }
585 vpMatrix dsdr(dim_s, 6);
586 interaction(dsdr);
587 return dsdr;
588}
590{
591 L.resize(dim_s, 6, false, false);
592 m_featI.interaction(m_LI);
593 m_mapping->interaction(I, m_LI, s, L);
594}
595
596void vpFeatureLuminanceMapping::print(unsigned int /*select*/) const
597{
598 std::cout << s << std::endl;
599}
600END_VISP_NAMESPACE
601#endif // C++11
unsigned int getCols() const
Definition vpArray2D.h:423
void resize(unsigned int nrows, unsigned int ncols, bool flagNullify=true, bool recopy_=true)
Definition vpArray2D.h:448
unsigned int size() const
Return the number of elements of the 2D array.
Definition vpArray2D.h:435
unsigned int getRows() const
Definition vpArray2D.h:433
vpColVector s
State of the visual feature.
unsigned int dim_s
Dimension of the visual feature.
Generic class defining intrinsic camera parameters.
Implementation of column vector and the associated operations.
double sum() const
void resize(unsigned int i, bool flagNullify=true)
error that can be emitted by ViSP classes.
Definition vpException.h:60
@ badValue
Used to indicate that a value is not in the allowed range.
Definition vpException.h:73
@ notInitialized
Used to indicate that a parameter is not initialized.
Definition vpException.h:74
@ dimensionError
Bad dimension.
Definition vpException.h:71
@ notImplementedError
Not implemented.
Definition vpException.h:69
vpColVector error(const vpBasicFeature &s_star, unsigned int select=FEATURE_ALL) VP_OVERRIDE
void buildFrom(vpImage< unsigned char > &I)
vpMatrix interaction(unsigned int select=FEATURE_ALL) VP_OVERRIDE
Compute the interaction matrix from a subset of the possible features.
vpFeatureLuminanceMapping(const vpCameraParameters &cam, unsigned int h, unsigned int w, double Z, const std::shared_ptr< vpLuminanceMapping > mapping)
void print(unsigned int select=FEATURE_ALL) const VP_OVERRIDE
Print the name of the feature.
vpFeatureLuminanceMapping * duplicate() const VP_OVERRIDE
vpFeatureLuminanceMapping & operator=(const vpFeatureLuminanceMapping &f)
Class that defines the image luminance visual feature.
static const int DEFAULT_BORDER
static void read(vpImage< unsigned char > &I, const std::string &filename, int backend=IO_DEFAULT_BACKEND)
Definition of the vpImage class member functions.
Definition vpImage.h:131
void init(unsigned rows, unsigned cols)
Initialize the ZigZag object. Computes and stores the zigzag indexing for a given matrix size.
void setValues(const vpColVector &s, unsigned int start, vpMatrix &m) const
set the values in the matrix, according to the values stored in the vector s and the zigzag indexing ...
void getValues(const vpMatrix &m, unsigned int start, unsigned int end, vpColVector &s) const
Fill the vector s with (end - start) values, according to the zigzag matrix indexing strategy.
void inverse(const vpColVector &s, vpImage< unsigned char > &I) VP_OVERRIDE
Reconstruct I from a representation s.
vpMatrix m_Dcols
DCT representation of the image.
vpLuminanceDCT::vpMatrixZigZagIndex m_zigzag
Luminance interaction matrix, seen as six image planes.
vpMatrix m_dct
Image as a matrix.
void map(const vpImage< unsigned char > &I, vpColVector &s) VP_OVERRIDE
Map an image I to a representation s. This representation s has getProjectionSize() rows.
void interaction(const vpImage< unsigned char > &I, const vpMatrix &LI, const vpColVector &s, vpMatrix &L) VP_OVERRIDE
Compute the interaction matrix associated with the representation s.
vpMatrix m_Imat
image dimensions (without borders)
std::array< vpMatrix, 6 > m_dIdrPlanes
the computed DCT matrices. The separable property of DCt is used so that a 1D DCT is computed on rows...
vpLuminanceDCT(const unsigned int k)
Build a new DCT object.
unsigned int getProjectionSize() const
Returns the size of the space to which an image is mapped to.
vpLuminanceMapping(unsigned int mappingSize)
Construct a new vp Luminance Mapping object.
static void imageAsMatrix(const vpImage< unsigned char > &I, vpMatrix &Imat, unsigned border)
static void imageAsVector(const vpImage< unsigned char > &I, vpColVector &Ivec, unsigned border)
unsigned m_border
Final vector size.
static vpLuminancePCA learn(const std::vector< std::string > &imageFiles, const unsigned int projectionSize, const unsigned int imageBorder=0)
Compute a new Principal Component Analysis on set of images, stored on disk.
void inverse(const vpColVector &s, vpImage< unsigned char > &I) VP_OVERRIDE
Reconstruct I from a representation s.
void save(const std::string &basisFilename, const std::string &meanFileName, const std::string &explainedVarianceFile) const
Save the PCA basis to multiple text files, for later use via the load function.
void map(const vpImage< unsigned char > &I, vpColVector &s) VP_OVERRIDE
Map an image I to a representation s. This representation s has getProjectionSize() rows.
void init(const std::shared_ptr< vpMatrix > &basis, const std::shared_ptr< vpColVector > &mean, const vpColVector &variance)
Initialize the PCA object with a basis, mean and explained variance vector.
void interaction(const vpImage< unsigned char > &I, const vpMatrix &LI, const vpColVector &s, vpMatrix &L) VP_OVERRIDE
Compute the interaction matrix associated with the representation s.
static vpLuminancePCA load(const std::string &basisFilename, const std::string &meanFileName, const std::string &explainedVarianceFile)
Save the PCA basis to multiple text files, for later use via the load function.
vpLuminancePCA & operator=(const vpLuminancePCA &other)
Implementation of a matrix and operations on matrices.
Definition vpMatrix.h:175
static bool loadMatrix(const std::string &filename, vpArray2D< double > &M, bool binary=false, char *header=nullptr)
Definition vpMatrix.h:841
void svd(vpColVector &w, vpMatrix &V)
vpColVector getCol(unsigned int j) const
Definition vpMatrix.cpp:560
vpMatrix transpose() const
static bool saveMatrix(const std::string &filename, const vpArray2D< double > &M, bool binary=false, const char *header="")
Definition vpMatrix.h:997
vpMatrix t() const