Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
vpImage_getters.h
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 * Image handling.
32 */
33
34#ifndef VP_IMAGE_GETTERS_H
35#define VP_IMAGE_GETTERS_H
36
37// Warning: this file shouldn't be included by the user. Internal usage only to reduce length of vpImage.h
38
51template <class Type> inline Type vpImage<Type>::getValue(unsigned int i, unsigned int j) const
52{
53 if ((i >= height) || (j >= width)) {
54 throw(vpException(vpImageException::notInTheImage, "Pixel outside the image"));
55 }
56
57 return row[i][j];
58}
59
76template <class Type> Type vpImage<Type>::getValue(double i, double j) const
77{
78 if ((i < 0) || (j < 0) || ((i + 1) > height) || ((j + 1) > width)) {
79 throw(vpException(vpImageException::notInTheImage, "Pixel outside of the image"));
80 }
81 if ((height * width) == 0) {
83 }
84
85 unsigned int iround = static_cast<unsigned int>(floor(i));
86 unsigned int jround = static_cast<unsigned int>(floor(j));
87
88 double rratio = i - static_cast<double>(iround);
89 double cratio = j - static_cast<double>(jround);
90
91 double rfrac = 1.0 - rratio;
92 double cfrac = 1.0 - cratio;
93
94 unsigned int iround_1 = std::min<unsigned int>(height - 1, iround + 1);
95 unsigned int jround_1 = std::min<unsigned int>(width - 1, jround + 1);
96
97 double value =
98 (((static_cast<double>(row[iround][jround]) * rfrac) + (static_cast<double>(row[iround_1][jround]) * rratio)) * cfrac) +
99 (((static_cast<double>(row[iround][jround_1]) * rfrac) + (static_cast<double>(row[iround_1][jround_1]) * rratio)) *
100 cratio);
101
102 return static_cast<Type>(vpMath::round(value));
103}
104
108template <> inline double vpImage<double>::getValue(double i, double j) const
109{
110 if ((i < 0) || (j < 0) || ((i + 1) > height) || ((j + 1) > width)) {
111 throw(vpException(vpImageException::notInTheImage, "Pixel outside of the image"));
112 }
113 if ((height * width) == 0) {
115 }
116
117 unsigned int iround = static_cast<unsigned int>(floor(i));
118 unsigned int jround = static_cast<unsigned int>(floor(j));
119
120 double rratio = i - static_cast<double>(iround);
121 double cratio = j - static_cast<double>(jround);
122
123 double rfrac = 1.0 - rratio;
124 double cfrac = 1.0 - cratio;
125
126 unsigned int iround_1 = std::min<unsigned int>(height - 1, iround + 1);
127 unsigned int jround_1 = std::min<unsigned int>(width - 1, jround + 1);
128
129 return (((row[iround][jround] * rfrac) + (row[iround_1][jround] * rratio)) * cfrac) +
130 (((row[iround][jround_1] * rfrac) + (row[iround_1][jround_1] * rratio)) * cratio);
131}
132
136template <> inline unsigned char vpImage<unsigned char>::getValue(double i, double j) const
137{
138 if ((i < 0) || (j < 0) || ((i + 1) > height) || ((j + 1) > width)) {
139 throw(vpException(vpImageException::notInTheImage, "Pixel outside of the image"));
140 }
141 if ((height * width) == 0) {
143 }
144
145 // alpha architecture is bi-endianness. The following optimization makes testImageGetValue failing
146#if (defined(VISP_LITTLE_ENDIAN) || defined(VISP_BIG_ENDIAN)) && !(defined(__alpha__) || defined(_M_ALPHA))
147 // Fixed-point arithmetic
148 const uint32_t magic_8 = 8;
149 const uint32_t magic_16 = 16;
150 const uint32_t magic_32 = 32;
151 const uint32_t magic_0x00FF = 0x00FF;
152 const uint32_t precision = 1U << magic_16;
153 uint64_t y = static_cast<uint64_t>(i * precision);
154 uint64_t x = static_cast<uint64_t>(j * precision);
155
156 uint64_t iround = y & (~0xFFFFU);
157 uint64_t jround = x & (~0xFFFFU);
158
159 uint64_t rratio = y - iround;
160 uint64_t cratio = x - jround;
161
162 uint64_t rfrac = precision - rratio;
163 uint64_t cfrac = precision - cratio;
164
165 uint64_t x_ = x >> magic_16;
166 uint64_t y_ = y >> magic_16;
167
168 if (((y_ + 1) < height) && ((x_ + 1) < width)) {
169 uint16_t up = vpEndian::reinterpret_cast_uchar_to_uint16_LE(bitmap + (y_ * width) + x_);
170 uint16_t down = vpEndian::reinterpret_cast_uchar_to_uint16_LE(bitmap + ((y_ + 1) * width) + x_);
171
172 return static_cast<unsigned char>((((((up & magic_0x00FF) * rfrac) + ((down & magic_0x00FF) * rratio)) * cfrac)
173 + (((up >> magic_8) * rfrac) + ((down >> magic_8) * rratio)) * cratio) >> magic_32);
174 }
175 else if ((y_ + 1) < height) {
176 return static_cast<unsigned char>(((row[y_][x_] * rfrac) + (row[y_ + 1][x_] * rratio)) >> magic_16);
177 }
178 else if ((x_ + 1) < width) {
179 uint16_t up = vpEndian::reinterpret_cast_uchar_to_uint16_LE(bitmap + (y_ * width) + x_);
180 return static_cast<unsigned char>((((up & magic_0x00FF) * cfrac) + ((up >> magic_8) * cratio)) >> magic_16);
181 }
182 else {
183 return row[y_][x_];
185#else
186 unsigned int iround = static_cast<unsigned int>(floor(i));
187 unsigned int jround = static_cast<unsigned int>(floor(j));
188
189 if (iround >= height || jround >= width) {
190 throw(vpException(vpImageException::notInTheImage, "Pixel outside the image"));
191 }
192
193 double rratio = i - static_cast<double>(iround);
194 double cratio = j - static_cast<double>(jround);
195
196 double rfrac = 1.0 - rratio;
197 double cfrac = 1.0 - cratio;
198
199 unsigned int iround_1 = std::min<unsigned int>(height - 1, iround + 1);
200 unsigned int jround_1 = std::min<unsigned int>(width - 1, jround + 1);
201
202 double value =
203 (static_cast<double>(row[iround][jround]) * rfrac + static_cast<double>(row[iround_1][jround]) * rratio) * cfrac +
204 (static_cast<double>(row[iround][jround_1]) * rfrac + static_cast<double>(row[iround_1][jround_1]) * rratio) *
205 cratio;
206 return static_cast<unsigned char>(vpMath::round(value));
207#endif
208}
209
213template <> inline vpRGBa vpImage<vpRGBa>::getValue(double i, double j) const
214{
215 if ((i < 0) || (j < 0) || ((i + 1) > height) || ((j + 1) > width)) {
216 throw(vpException(vpImageException::notInTheImage, "Pixel outside of the image"));
217 }
218 if ((height * width) == 0) {
220 }
221
222 unsigned int iround = static_cast<unsigned int>(floor(i));
223 unsigned int jround = static_cast<unsigned int>(floor(j));
224
225 double rratio = i - static_cast<double>(iround);
226 double cratio = j - static_cast<double>(jround);
227
228 double rfrac = 1.0 - rratio;
229 double cfrac = 1.0 - cratio;
230
231 unsigned int iround_1 = std::min<unsigned int>(height - 1, iround + 1);
232 unsigned int jround_1 = std::min<unsigned int>(width - 1, jround + 1);
233
234 double valueR =
235 (((static_cast<double>(row[iround][jround].R) * rfrac) + (static_cast<double>(row[iround_1][jround].R) * rratio)) *
236 cfrac) +
237 (((static_cast<double>(row[iround][jround_1].R) * rfrac) + (static_cast<double>(row[iround_1][jround_1].R) * rratio)) *
238 cratio);
239 double valueG =
240 (((static_cast<double>(row[iround][jround].G) * rfrac) + (static_cast<double>(row[iround_1][jround].G) * rratio)) *
241 cfrac) +
242 (((static_cast<double>(row[iround][jround_1].G) * rfrac) + (static_cast<double>(row[iround_1][jround_1].G) * rratio)) *
243 cratio);
244 double valueB =
245 (((static_cast<double>(row[iround][jround].B) * rfrac) + (static_cast<double>(row[iround_1][jround].B) * rratio)) *
246 cfrac) +
247 (((static_cast<double>(row[iround][jround_1].B) * rfrac) + (static_cast<double>(row[iround_1][jround_1].B) * rratio)) *
248 cratio);
249
250 return vpRGBa(static_cast<unsigned char>(vpMath::round(valueR)), static_cast<unsigned char>(vpMath::round(valueG)),
251 static_cast<unsigned char>(vpMath::round(valueB)));
252}
253
257template <> inline vpRGBf vpImage<vpRGBf>::getValue(double i, double j) const
258{
259 if ((i < 0) || (j < 0) || ((i + 1) > height) || ((j + 1) > width)) {
260 throw(vpException(vpImageException::notInTheImage, "Pixel outside of the image"));
261 }
262 if ((height * width) == 0) {
264 }
265
266 unsigned int iround = static_cast<unsigned int>(floor(i));
267 unsigned int jround = static_cast<unsigned int>(floor(j));
268
269 double rratio = i - static_cast<double>(iround);
270 double cratio = j - static_cast<double>(jround);
271
272 double rfrac = 1.0 - rratio;
273 double cfrac = 1.0 - cratio;
274
275 unsigned int iround_1 = std::min<unsigned int>(height - 1, iround + 1);
276 unsigned int jround_1 = std::min<unsigned int>(width - 1, jround + 1);
277
278 double valueR =
279 (((static_cast<double>(row[iround][jround].R) * rfrac) + (static_cast<double>(row[iround_1][jround].R) * rratio)) *
280 cfrac) +
281 (((static_cast<double>(row[iround][jround_1].R) * rfrac) + (static_cast<double>(row[iround_1][jround_1].R) * rratio)) *
282 cratio);
283 double valueG =
284 (((static_cast<double>(row[iround][jround].G) * rfrac) + (static_cast<double>(row[iround_1][jround].G) * rratio)) *
285 cfrac) +
286 (((static_cast<double>(row[iround][jround_1].G) * rfrac) + (static_cast<double>(row[iround_1][jround_1].G) * rratio)) *
287 cratio);
288 double valueB =
289 (((static_cast<double>(row[iround][jround].B) * rfrac) + (static_cast<double>(row[iround_1][jround].B) * rratio)) *
290 cfrac) +
291 (((static_cast<double>(row[iround][jround_1].B) * rfrac) + (static_cast<double>(row[iround_1][jround_1].B) * rratio)) *
292 cratio);
293
294 return vpRGBf(static_cast<float>(valueR), static_cast<float>(valueG), static_cast<float>(valueB));
295}
296
313template <class Type> inline Type vpImage<Type>::getValue(const vpImagePoint &ip) const
314{
315 return getValue(ip.get_i(), ip.get_j());
316}
317
321template <> inline double vpImage<double>::getValue(const vpImagePoint &ip) const
322{
323 return getValue(ip.get_i(), ip.get_j());
324}
325
329template <> inline unsigned char vpImage<unsigned char>::getValue(const vpImagePoint &ip) const
330{
331 return getValue(ip.get_i(), ip.get_j());
332}
333
337template <> inline vpRGBa vpImage<vpRGBa>::getValue(const vpImagePoint &ip) const
338{
339 return getValue(ip.get_i(), ip.get_j());
340}
341
349template <class Type> Type vpImage<Type>::getMaxValue(bool onlyFiniteVal) const
350{
351 if (npixels == 0) {
352 throw(vpException(vpException::fatalError, "Cannot compute maximum value of an empty image"));
353 }
354 Type m = bitmap[0];
355 for (unsigned int i = 0; i < npixels; ++i) {
356 if (bitmap[i] > m) {
357 m = bitmap[i];
358 }
359 }
360 (void)onlyFiniteVal;
361 return m;
362}
363
372template <> inline double vpImage<double>::getMaxValue(bool onlyFiniteVal) const
373{
374 if (npixels == 0) {
375 throw(vpException(vpException::fatalError, "Cannot compute maximum value of an empty image"));
376 }
377 double m = bitmap[0];
378 if (onlyFiniteVal) {
379 for (unsigned int i = 0; i < npixels; ++i) {
380 if ((bitmap[i] > m) && (vpMath::isFinite(bitmap[i]))) {
381 m = bitmap[i];
382 }
383 }
384 }
385 else {
386 for (unsigned int i = 0; i < npixels; ++i) {
387 if (bitmap[i] > m) {
388 m = bitmap[i];
389 }
390 }
391 }
392 return m;
393}
394
403template <> inline float vpImage<float>::getMaxValue(bool onlyFiniteVal) const
404{
405 if (npixels == 0) {
406 throw(vpException(vpException::fatalError, "Cannot compute maximum value of an empty image"));
407 }
408 float m = bitmap[0];
409 if (onlyFiniteVal) {
410 for (unsigned int i = 0; i < npixels; ++i) {
411 if ((bitmap[i] > m) && (vpMath::isFinite(bitmap[i]))) {
412 m = bitmap[i];
413 }
414 }
415 }
416 else {
417 for (unsigned int i = 0; i < npixels; ++i) {
418 if (bitmap[i] > m) {
419 m = bitmap[i];
420 }
421 }
422 }
423 return m;
424}
425
433template <class Type> Type vpImage<Type>::getMinValue(bool onlyFiniteVal) const
434{
435 if (npixels == 0) {
436 throw(vpException(vpException::fatalError, "Cannot compute minimum value of an empty image"));
437 }
438 Type m = bitmap[0];
439 for (unsigned int i = 0; i < npixels; ++i) {
440 if (bitmap[i] < m) {
441 m = bitmap[i];
442 }
443 }
444 (void)onlyFiniteVal;
445 return m;
446}
447
456template <> inline double vpImage<double>::getMinValue(bool onlyFiniteVal) const
457{
458 if (npixels == 0) {
459 throw(vpException(vpException::fatalError, "Cannot compute minimum value of an empty image"));
460 }
461 double m = bitmap[0];
462 if (onlyFiniteVal) {
463 for (unsigned int i = 0; i < npixels; ++i) {
464 if ((bitmap[i] < m) && (vpMath::isFinite(bitmap[i]))) {
465 m = bitmap[i];
466 }
467 }
468 }
469 else {
470 for (unsigned int i = 0; i < npixels; ++i) {
471 if (bitmap[i] < m) {
472 m = bitmap[i];
473 }
474 }
475 }
476 return m;
477}
478
487template <> inline float vpImage<float>::getMinValue(bool onlyFiniteVal) const
488{
489 if (npixels == 0) {
490 throw(vpException(vpException::fatalError, "Cannot compute minimum value of an empty image"));
491 }
492 float m = bitmap[0];
493 if (onlyFiniteVal) {
494 for (unsigned int i = 0; i < npixels; ++i) {
495 if ((bitmap[i] < m) && (vpMath::isFinite(bitmap[i]))) {
496 m = bitmap[i];
497 }
498 }
499 }
500 else {
501 for (unsigned int i = 0; i < npixels; ++i) {
502 if (bitmap[i] < m) {
503 m = bitmap[i];
504 }
505 }
506 }
507 return m;
508}
509
520template <class Type> void vpImage<Type>::getMinMaxValue(Type &min, Type &max, bool onlyFiniteVal) const
521{
522 if (npixels == 0) {
523 throw(vpException(vpException::fatalError, "Cannot get minimum/maximum values of an empty image"));
524 }
525
526 min = bitmap[0];
527 max = bitmap[0];
528 for (unsigned int i = 0; i < npixels; ++i) {
529 if (bitmap[i] < min) {
530 min = bitmap[i];
531 }
532 if (bitmap[i] > max) {
533 max = bitmap[i];
534 }
535 }
536 (void)onlyFiniteVal;
537}
538
550template <> inline void vpImage<double>::getMinMaxValue(double &min, double &max, bool onlyFiniteVal) const
551{
552 if (npixels == 0) {
553 throw(vpException(vpException::fatalError, "Cannot get minimum/maximum values of an empty image"));
554 }
555
556 min = bitmap[0];
557 max = bitmap[0];
558 if (onlyFiniteVal) {
559 for (unsigned int i = 0; i < npixels; ++i) {
560 if (vpMath::isFinite(bitmap[i])) {
561 if (bitmap[i] < min) {
562 min = bitmap[i];
563 }
564 if (bitmap[i] > max) {
565 max = bitmap[i];
566 }
567 }
568 }
569 }
570 else {
571 for (unsigned int i = 0; i < npixels; ++i) {
572 if (bitmap[i] < min) {
573 min = bitmap[i];
574 }
575 if (bitmap[i] > max) {
576 max = bitmap[i];
577 }
578 }
579 }
580}
581
593template <> inline void vpImage<float>::getMinMaxValue(float &min, float &max, bool onlyFiniteVal) const
594{
595 if (npixels == 0) {
596 throw(vpException(vpException::fatalError, "Cannot get minimum/maximum values of an empty image"));
597 }
598
599 min = bitmap[0];
600 max = bitmap[0];
601 if (onlyFiniteVal) {
602 for (unsigned int i = 0; i < npixels; ++i) {
603 if (vpMath::isFinite(bitmap[i])) {
604 if (bitmap[i] < min) {
605 min = bitmap[i];
606 }
607 if (bitmap[i] > max) {
608 max = bitmap[i];
609 }
610 }
611 }
612 }
613 else {
614 for (unsigned int i = 0; i < npixels; ++i) {
615 if (bitmap[i] < min) {
616 min = bitmap[i];
617 }
618 if (bitmap[i] > max) {
619 max = bitmap[i];
620 }
621 }
622 }
623}
624
636template <> inline void vpImage<vpRGBf>::getMinMaxValue(vpRGBf &min, vpRGBf &max, bool onlyFiniteVal) const
637{
638 if (npixels == 0) {
639 throw(vpException(vpException::fatalError, "Cannot get minimum/maximum values of an empty image"));
640 }
641
642 min = bitmap[0];
643 max = bitmap[0];
644 if (onlyFiniteVal) {
645 for (unsigned int i = 0; i < npixels; ++i) {
646 if (vpMath::isFinite(bitmap[i].R)) {
647 if (bitmap[i].R < min.R) {
648 min.R = bitmap[i].R;
649 }
650 if (bitmap[i].R > max.R) {
651 max.R = bitmap[i].R;
652 }
653 }
654 if (vpMath::isFinite(bitmap[i].G)) {
655 if (bitmap[i].G < min.G) {
656 min.G = bitmap[i].G;
657 }
658 if (bitmap[i].G > max.G) {
659 max.G = bitmap[i].G;
660 }
661 }
662 if (vpMath::isFinite(bitmap[i].B)) {
663 if (bitmap[i].B < min.B) {
664 min.B = bitmap[i].B;
665 }
666 if (bitmap[i].B > max.B) {
667 max.B = bitmap[i].B;
668 }
669 }
670 }
671 }
672 else {
673 for (unsigned int i = 0; i < npixels; ++i) {
674 if (bitmap[i].R < min.R) {
675 min.R = bitmap[i].R;
676 }
677 if (bitmap[i].R > max.R) {
678 max.R = bitmap[i].R;
679 }
680
681 if (bitmap[i].G < min.G) {
682 min.G = bitmap[i].G;
683 }
684 if (bitmap[i].G > max.G) {
685 max.G = bitmap[i].G;
686 }
687
688 if (bitmap[i].B < min.B) {
689 min.B = bitmap[i].B;
690 }
691 if (bitmap[i].B > max.B) {
692 max.B = bitmap[i].B;
693 }
694 }
695 }
696}
697
719template <class Type>
720void vpImage<Type>::getMinMaxLoc(vpImagePoint *minLoc, vpImagePoint *maxLoc, Type *minVal, Type *maxVal) const
721{
722 if (npixels == 0) {
723 throw(vpException(vpException::fatalError, "Cannot get location of minimum/maximum "
724 "values of an empty image"));
725 }
726
727 Type min = bitmap[0], max = bitmap[0];
728 vpImagePoint minLoc_, maxLoc_;
729 for (unsigned int i = 0; i < height; ++i) {
730 for (unsigned int j = 0; j < width; ++j) {
731 if (row[i][j] < min) {
732 min = row[i][j];
733 minLoc_.set_ij(i, j);
734 }
735
736 if (row[i][j] > max) {
737 max = row[i][j];
738 maxLoc_.set_ij(i, j);
739 }
740 }
741 }
742
743 if (minLoc != nullptr) {
744 *minLoc = minLoc_;
745 }
746
747 if (maxLoc != nullptr) {
748 *maxLoc = maxLoc_;
749 }
750
751 if (minVal != nullptr) {
752 *minVal = min;
753 }
754
755 if (maxVal != nullptr) {
756 *maxVal = max;
757 }
758}
759
770template <class Type> double vpImage<Type>::getMeanValue(const vpImage<bool> *p_mask, unsigned int *nbValidPoints) const
771{
772 if ((height == 0) || (width == 0)) {
773 return 0.0;
774 }
775 unsigned int nbPointsInMask = 0;
776 double sum = getSum(p_mask, &nbPointsInMask);
777 if (nbPointsInMask == 0) {
778 throw(vpException(vpException::divideByZeroError, "Division by zero in vpImage::getMeanValue()"));
779 }
780 if (nbValidPoints) {
781 *nbValidPoints = nbPointsInMask;
782 }
783 return sum / nbPointsInMask;
784}
785
801template <class Type> double vpImage<Type>::getStdev(const vpImage<bool> *p_mask, unsigned int *nbValidPoints) const
802{
803 double mean = getMeanValue(p_mask, nbValidPoints);
804 return getStdev(mean, p_mask);
805}
806
825template <class Type> double vpImage<Type>::getStdev(const double &mean, const vpImage<bool> *p_mask, unsigned int *nbValidPoints) const
826{
827 if ((height == 0) || (width == 0)) {
828 return 0.0;
829 }
830 const unsigned int size = width * height;
831 double sum = 0.;
832 unsigned int nbPointsInMask = 0;
833 if (p_mask) {
834 if ((p_mask->getWidth() != width) || (p_mask->getHeight() != height)) {
835 throw(vpException(vpException::fatalError, "Cannot compute standard deviation: image and mask size differ"));
836 }
837 for (unsigned int i = 0; i < size; ++i) {
838 if (p_mask->bitmap[i]) {
839 sum += (bitmap[i] - mean) * (bitmap[i] - mean);
840 ++nbPointsInMask;
841 }
842 }
843 }
844 else {
845 for (unsigned int i = 0; i < size; ++i) {
846 sum += (bitmap[i] - mean) * (bitmap[i] - mean);
847 }
848 nbPointsInMask = size;
849 }
850 sum /= static_cast<double>(nbPointsInMask);
851 if (nbValidPoints) {
852 *nbValidPoints = nbPointsInMask;
853 }
854 return std::sqrt(sum);
855}
856
857#ifndef DOXYGEN_SHOULD_SKIP_THIS
877template <> inline double vpImage<vpRGBa>::getStdev(const double &mean, const vpImage<bool> *p_mask, unsigned int *nbValidPoints) const
878{
879 if ((height == 0) || (width == 0)) {
880 return 0.0;
881 }
882 const unsigned int size = width * height;
883 double sum = 0.;
884 unsigned int nbPointsInMask = 0;
885 if (p_mask) {
886 if ((p_mask->getWidth() != width) || (p_mask->getHeight() != height)) {
887 throw(vpException(vpException::fatalError, "Cannot compute standard deviation: image and mask size differ"));
888 }
889 for (unsigned int i = 0; i < size; ++i) {
890 if (p_mask->bitmap[i]) {
891 double val = static_cast<double>(bitmap[i].R) + static_cast<double>(bitmap[i].G) + static_cast<double>(bitmap[i].B);
892 sum += (val - mean) * (val - mean);
893 ++nbPointsInMask;
894 }
895 }
896 }
897 else {
898 for (unsigned int i = 0; i < size; ++i) {
899 double val = static_cast<double>(bitmap[i].R) + static_cast<double>(bitmap[i].G) + static_cast<double>(bitmap[i].B);
900 sum += (val - mean) * (val - mean);
901 }
902 nbPointsInMask = size;
903 }
904 sum /= static_cast<double>(nbPointsInMask);
905 if (nbValidPoints) {
906 *nbValidPoints = nbPointsInMask;
907 }
908 return std::sqrt(sum);
909}
910
930template <> inline double vpImage<vpRGBf>::getStdev(const double &mean, const vpImage<bool> *p_mask, unsigned int *nbValidPoints) const
931{
932 if ((height == 0) || (width == 0)) {
933 return 0.0;
934 }
935 const unsigned int size = width * height;
936 double sum = 0.;
937 unsigned int nbPointsInMask = 0;
938 if (p_mask) {
939 if ((p_mask->getWidth() != width) || (p_mask->getHeight() != height)) {
940 throw(vpException(vpException::fatalError, "Cannot compute standard deviation: image and mask size differ"));
941 }
942 for (unsigned int i = 0; i < size; ++i) {
943 if (p_mask->bitmap[i]) {
944 double val = static_cast<double>(bitmap[i].R) + static_cast<double>(bitmap[i].G) + static_cast<double>(bitmap[i].B);
945 sum += (val - mean) * (val - mean);
946 ++nbPointsInMask;
947 }
948 }
949 }
950 else {
951 for (unsigned int i = 0; i < size; ++i) {
952 double val = static_cast<double>(bitmap[i].R) + static_cast<double>(bitmap[i].G) + static_cast<double>(bitmap[i].B);
953 sum += (val - mean) * (val - mean);
954 }
955 nbPointsInMask = size;
956 }
957 sum /= static_cast<double>(nbPointsInMask);
958 if (nbValidPoints) {
959 *nbValidPoints = nbPointsInMask;
960 }
961 return std::sqrt(sum);
962}
963#endif // DOXYGEN_SHOULD_SKIP_THIS
964
976template <class Type> inline double vpImage<Type>::getSum(const vpImage<bool> *p_mask, unsigned int *nbValidPoints) const
977{
978 if ((height == 0) || (width == 0)) {
979 if (nbValidPoints) {
980 *nbValidPoints = 0;
981 }
982 return 0.0;
983 }
984 if (p_mask) {
985 if ((p_mask->getWidth() != width) || (p_mask->getHeight() != height)) {
986 throw(vpException(vpException::fatalError, "Cannot compute sum: image and mask size differ"));
987 }
988 }
989 double res = 0.0;
990 unsigned int nbPointsInMask = 0;
991 unsigned int size = height * width;
992 if (p_mask) {
993 for (unsigned int i = 0; i < size; ++i) {
994 if (p_mask->bitmap[i]) {
995 res += static_cast<double>(bitmap[i]);
996 ++nbPointsInMask;
997 }
998 }
999 }
1000 else {
1001 for (unsigned int i = 0; i < size; ++i) {
1002 res += static_cast<double>(bitmap[i]);
1003 }
1004 nbPointsInMask = size;
1005 }
1006 if (nbValidPoints) {
1007 *nbValidPoints = nbPointsInMask;
1008 }
1009
1010 return res;
1011}
1012
1013#ifndef DOXYGEN_SHOULD_SKIP_THIS
1026template <> inline double vpImage<vpRGBa>::getSum(const vpImage<bool> *p_mask, unsigned int *nbValidPoints) const
1027{
1028 if ((height == 0) || (width == 0)) {
1029 return 0.0;
1030 }
1031 double res = 0.0;
1032 unsigned int nbPointsInMask = 0;
1033 unsigned int size = height * width;
1034 if (p_mask) {
1035 if ((p_mask->getWidth() != width) || (p_mask->getHeight() != height)) {
1036 throw(vpException(vpException::fatalError, "Cannot compute sum: image and mask size differ"));
1037 }
1038 for (unsigned int i = 0; i < size; ++i) {
1039 if (p_mask->bitmap[i]) {
1040 res += static_cast<double>(bitmap[i].R) + static_cast<double>(bitmap[i].G) + static_cast<double>(bitmap[i].B);
1041 ++nbPointsInMask;
1042 }
1043 }
1044 }
1045 else {
1046 for (unsigned int i = 0; i < (height * width); ++i) {
1047 res += static_cast<double>(bitmap[i].R) + static_cast<double>(bitmap[i].G) + static_cast<double>(bitmap[i].B);
1048 }
1049 nbPointsInMask = size;
1050 }
1051 if (nbValidPoints) {
1052 *nbValidPoints = nbPointsInMask;
1053 }
1054 return res;
1055}
1056
1069template <> inline double vpImage<vpRGBf>::getSum(const vpImage<bool> *p_mask, unsigned int *nbValidPoints) const
1070{
1071 if ((height == 0) || (width == 0)) {
1072 return 0.0;
1073 }
1074 double res = 0.0;
1075 unsigned int nbPointsInMask = 0;
1076 unsigned int size = height * width;
1077 if (p_mask) {
1078 if ((p_mask->getWidth() != width) || (p_mask->getHeight() != height)) {
1079 throw(vpException(vpException::fatalError, "Cannot compute sum: image and mask size differ"));
1080 }
1081 for (unsigned int i = 0; i < size; ++i) {
1082 if (p_mask->bitmap[i]) {
1083 res += static_cast<double>(bitmap[i].R) + static_cast<double>(bitmap[i].G) + static_cast<double>(bitmap[i].B);
1084 ++nbPointsInMask;
1085 }
1086 }
1087 }
1088 else {
1089 for (unsigned int i = 0; i < (height * width); ++i) {
1090 res += static_cast<double>(bitmap[i].R) + static_cast<double>(bitmap[i].G) + static_cast<double>(bitmap[i].B);
1091 }
1092 nbPointsInMask = size;
1093 }
1094 if (nbValidPoints) {
1095 *nbValidPoints = nbPointsInMask;
1096 }
1097 return res;
1098}
1099#endif // DOXYGEN_SHOULD_SKIP_THIS
1100
1101#endif
error that can be emitted by ViSP classes.
Definition vpException.h:60
@ fatalError
Fatal error.
Definition vpException.h:72
@ divideByZeroError
Division by zero.
Definition vpException.h:70
@ notInitializedError
Image not initialized.
@ notInTheImage
Pixel not in the image.
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
double get_j() const
void set_ij(double ii, double jj)
double get_i() const
Definition of the vpImage class member functions.
Definition vpImage.h:131
double getSum(const vpImage< bool > *p_mask=nullptr, unsigned int *nbValidPoints=nullptr) const
Compute the sum of image intensities.
Type getMinValue(bool onlyFiniteVal=true) const
Return the minimum value within the bitmap.
void getMinMaxLoc(vpImagePoint *minLoc, vpImagePoint *maxLoc, Type *minVal=nullptr, Type *maxVal=nullptr) const
Get the position of the minimum and/or the maximum pixel value within the bitmap and the correspondin...
unsigned int getWidth() const
Definition vpImage.h:242
Type getValue(unsigned int i, unsigned int j) const
Type * bitmap
points toward the bitmap
Definition vpImage.h:135
double getStdev(const vpImage< bool > *p_mask=nullptr, unsigned int *nbValidPoints=nullptr) const
Return the standard deviation of the bitmap.
Type getMaxValue(bool onlyFiniteVal=true) const
Return the maximum value within the bitmap.
unsigned int getHeight() const
Definition vpImage.h:181
void getMinMaxValue(Type &min, Type &max, bool onlyFiniteVal=true) const
Look for the minimum and the maximum value within the bitmap.
vpImage()
constructor
Definition vpImage.h:521
double getMeanValue(const vpImage< bool > *p_mask=nullptr, unsigned int *nbValidPoints=nullptr) const
Return the mean value of the bitmap.
static int round(double x)
Definition vpMath.h:413
static bool isFinite(double value)
Definition vpMath.cpp:198
float B
Blue component.
Definition vpRGBf.h:161
float G
Green component.
Definition vpRGBf.h:160
float R
Red component.
Definition vpRGBf.h:159
VISP_EXPORT uint16_t reinterpret_cast_uchar_to_uint16_LE(unsigned char *const ptr)
Definition vpEndian.cpp:161