Visual Servoing Platform version 3.5.0
vpImage.h
1/****************************************************************************
2 *
3 * ViSP, open source Visual Servoing Platform software.
4 * Copyright (C) 2005 - 2019 by Inria. All rights reserved.
5 *
6 * This software is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 * See the file LICENSE.txt at the root directory of this source
11 * distribution for additional information about the GNU GPL.
12 *
13 * For using ViSP with software that can not be combined with the GNU
14 * GPL, please contact Inria about acquiring a ViSP Professional
15 * Edition License.
16 *
17 * See http://visp.inria.fr for more information.
18 *
19 * This software was developed at:
20 * Inria Rennes - Bretagne Atlantique
21 * Campus Universitaire de Beaulieu
22 * 35042 Rennes Cedex
23 * France
24 *
25 * If you have questions regarding the use of this file, please contact
26 * Inria at visp@inria.fr
27 *
28 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
29 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
30 *
31 * Description:
32 * Image handling.
33 *
34 * Authors:
35 * Eric Marchand
36 *
37 *****************************************************************************/
38
44#ifndef vpImage_H
45#define vpImage_H
46
47#include <visp3/core/vpConfig.h>
48#include <visp3/core/vpDebug.h>
49#include <visp3/core/vpEndian.h>
50#include <visp3/core/vpException.h>
51#include <visp3/core/vpImageException.h>
52#include <visp3/core/vpImagePoint.h>
53#include <visp3/core/vpRGBa.h>
54
55#if defined(VISP_HAVE_PTHREAD) || (defined(_WIN32) && !defined(WINRT_8_0))
56#include <visp3/core/vpThread.h>
57#endif
58
59#include <fstream>
60#include <iomanip> // std::setw
61#include <iostream>
62#include <math.h>
63#include <string.h>
64
65// Visual Studio 2010 or previous is missing inttypes.h
66#if defined(_MSC_VER) && (_MSC_VER < 1700)
67typedef long long int64_t;
68typedef unsigned short uint16_t;
69#else
70# include <inttypes.h>
71#endif
72
73class vpDisplay;
74
125// Ref: http://en.cppreference.com/w/cpp/language/friend#Template_friends
126template <class Type> class vpImage; // forward declare to make function declaration possible
127
128// declarations
129template <class Type> std::ostream &operator<<(std::ostream &, const vpImage<Type> &);
130
131std::ostream &operator<<(std::ostream &, const vpImage<unsigned char> &);
132std::ostream &operator<<(std::ostream &, const vpImage<char> &);
133std::ostream &operator<<(std::ostream &, const vpImage<float> &);
134std::ostream &operator<<(std::ostream &, const vpImage<double> &);
135
136template <class Type> void swap(vpImage<Type> &first, vpImage<Type> &second);
137
138template <class Type> class vpImage
139{
140 friend class vpImageConvert;
141
142public:
143 Type *bitmap;
145
150#if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
153#endif
155 vpImage(unsigned int height, unsigned int width);
157 vpImage(unsigned int height, unsigned int width, Type value);
159 vpImage(Type *const array, unsigned int height, unsigned int width, bool copyData = false);
161 virtual ~vpImage();
162
165
166 // destructor
167 void destroy();
168
169 // Returns a new image that's double size of the current image
171
179 inline unsigned int getCols() const { return width; }
188 inline unsigned int getHeight() const { return height; }
189
190 // Return the maximum value within the bitmap
191 Type getMaxValue() const;
192 // Return the mean value of the bitmap
193 Type getMeanValue() const;
194 // Return the minumum value within the bitmap
195 Type getMinValue() const;
196 // Look for the minumum and the maximum value within the bitmap
197 void getMinMaxValue(Type &min, Type &max) const;
198 // Look for the minumum and the maximum value within the bitmap and get their location
199 void getMinMaxLoc(vpImagePoint *minLoc, vpImagePoint *maxLoc, Type *minVal = NULL, Type *maxVal = NULL) const;
200
209 inline unsigned int getNumberOfPixel() const { return npixels; }
210
218 inline unsigned int getRows() const { return height; }
219
227 inline unsigned int getSize() const { return width * height; }
228
229 // Gets the value of a pixel at a location.
230 Type getValue(unsigned int i, unsigned int j) const;
231 // Gets the value of a pixel at a location with bilinear interpolation.
232 Type getValue(double i, double j) const;
233 // Gets the value of a pixel at a location with bilinear interpolation.
234 Type getValue(const vpImagePoint &ip) const;
235
236 // Get image pixels sum
237 double getSum() const;
238
246 inline unsigned int getWidth() const { return width; }
247
248 // Returns a new image that's half size of the current image
249 void halfSizeImage(vpImage<Type> &res) const;
250
252 void init(unsigned int height, unsigned int width);
254 void init(unsigned int height, unsigned int width, Type value);
256 void init(Type *const array, unsigned int height, unsigned int width, bool copyData = false);
257 void insert(const vpImage<Type> &src, const vpImagePoint &topLeft);
258
259 //------------------------------------------------------------------
260 // Acces to the image
261
263 inline Type *operator[](unsigned int i) { return row[i]; }
264 inline Type *operator[](int i) { return row[i]; }
265
267 inline const Type *operator[](unsigned int i) const { return row[i]; }
268 inline const Type *operator[](int i) const { return row[i]; }
269
276 inline Type operator()(unsigned int i, unsigned int j) const { return bitmap[i * width + j]; }
277
282 inline void operator()(unsigned int i, unsigned int j, const Type &v) { bitmap[i * width + j] = v; }
283
294 inline Type operator()(const vpImagePoint &ip) const
295 {
296 unsigned int i = (unsigned int)ip.get_i();
297 unsigned int j = (unsigned int)ip.get_j();
298
299 return bitmap[i * width + j];
300 }
301
310 inline void operator()(const vpImagePoint &ip, const Type &v)
311 {
312 unsigned int i = (unsigned int)ip.get_i();
313 unsigned int j = (unsigned int)ip.get_j();
314
315 bitmap[i * width + j] = v;
316 }
317
319
322
323 vpImage<Type> &operator=(const Type &v);
324 bool operator==(const vpImage<Type> &I);
325 bool operator!=(const vpImage<Type> &I);
326 friend std::ostream &operator<< <>(std::ostream &s, const vpImage<Type> &I);
327 friend std::ostream &operator<<(std::ostream &s, const vpImage<unsigned char> &I);
328 friend std::ostream &operator<<(std::ostream &s, const vpImage<char> &I);
329 friend std::ostream &operator<<(std::ostream &s, const vpImage<float> &I);
330 friend std::ostream &operator<<(std::ostream &s, const vpImage<double> &I);
331
332 // Perform a look-up table transformation
333 void performLut(const Type (&lut)[256], unsigned int nbThreads = 1);
334
335 // Returns a new image that's a quarter size of the current image
337
338 // set the size of the image without initializing it.
339 void resize(unsigned int h, unsigned int w);
340 // set the size of the image and initialize it.
341 void resize(unsigned int h, unsigned int w, const Type &val);
342
343 void sub(const vpImage<Type> &B, vpImage<Type> &C);
344 void sub(const vpImage<Type> &A, const vpImage<Type> &B, vpImage<Type> &C);
345 void subsample(unsigned int v_scale, unsigned int h_scale, vpImage<Type> &sampled) const;
346
347 friend void swap<>(vpImage<Type> &first, vpImage<Type> &second);
348
350
351private:
352 unsigned int npixels;
353 unsigned int width;
354 unsigned int height;
355 Type **row;
356 bool hasOwnership;
357};
358
359template <class Type> std::ostream &operator<<(std::ostream &s, const vpImage<Type> &I)
360{
361 if (I.bitmap == NULL) {
362 return s;
363 }
364
365 for (unsigned int i = 0; i < I.getHeight(); i++) {
366 for (unsigned int j = 0; j < I.getWidth() - 1; j++) {
367 s << I[i][j] << " ";
368 }
369
370 // We don't add " " after the last column element
371 s << I[i][I.getWidth() - 1];
372
373 // We don't add a \n character at the end of the last row line
374 if (i < I.getHeight() - 1) {
375 s << std::endl;
376 }
377 }
378
379 return s;
380}
381
382inline std::ostream &operator<<(std::ostream &s, const vpImage<unsigned char> &I)
383{
384 if (I.bitmap == NULL) {
385 return s;
386 }
387
388 std::ios_base::fmtflags original_flags = s.flags();
389
390 for (unsigned int i = 0; i < I.getHeight(); i++) {
391 for (unsigned int j = 0; j < I.getWidth() - 1; j++) {
392 s << std::setw(3) << static_cast<unsigned>(I[i][j]) << " ";
393 }
394
395 // We don't add " " after the last column element
396 s << std::setw(3) << static_cast<unsigned>(I[i][I.getWidth() - 1]);
397
398 // We don't add a \n character at the end of the last row line
399 if (i < I.getHeight() - 1) {
400 s << std::endl;
401 }
402 }
403
404 s.flags(original_flags); // restore s to standard state
405 return s;
406}
407
408inline std::ostream &operator<<(std::ostream &s, const vpImage<char> &I)
409{
410 if (I.bitmap == NULL) {
411 return s;
412 }
413
414 std::ios_base::fmtflags original_flags = s.flags();
415
416 for (unsigned int i = 0; i < I.getHeight(); i++) {
417 for (unsigned int j = 0; j < I.getWidth() - 1; j++) {
418 s << std::setw(4) << static_cast<int>(I[i][j]) << " ";
419 }
420
421 // We don't add " " after the last column element
422 s << std::setw(4) << static_cast<int>(I[i][I.getWidth() - 1]);
423
424 // We don't add a \n character at the end of the last row line
425 if (i < I.getHeight() - 1) {
426 s << std::endl;
427 }
428 }
429
430 s.flags(original_flags); // restore s to standard state
431 return s;
432}
433
434inline std::ostream &operator<<(std::ostream &s, const vpImage<float> &I)
435{
436 if (I.bitmap == NULL) {
437 return s;
438 }
439
440 std::ios_base::fmtflags original_flags = s.flags();
441 s.precision(9); // http://en.cppreference.com/w/cpp/types/numeric_limits/max_digits10
442
443 for (unsigned int i = 0; i < I.getHeight(); i++) {
444 for (unsigned int j = 0; j < I.getWidth() - 1; j++) {
445 s << I[i][j] << " ";
446 }
447
448 // We don't add " " after the last column element
449 s << I[i][I.getWidth() - 1];
450
451 // We don't add a \n character at the end of the last row line
452 if (i < I.getHeight() - 1) {
453 s << std::endl;
454 }
455 }
456
457 s.flags(original_flags); // restore s to standard state
458 return s;
459}
460
461inline std::ostream &operator<<(std::ostream &s, const vpImage<double> &I)
462{
463 if (I.bitmap == NULL) {
464 return s;
465 }
466
467 std::ios_base::fmtflags original_flags = s.flags();
468 s.precision(17); // http://en.cppreference.com/w/cpp/types/numeric_limits/max_digits10
469
470 for (unsigned int i = 0; i < I.getHeight(); i++) {
471 for (unsigned int j = 0; j < I.getWidth() - 1; j++) {
472 s << I[i][j] << " ";
473 }
474
475 // We don't add " " after the last column element
476 s << I[i][I.getWidth() - 1];
477
478 // We don't add a \n character at the end of the last row line
479 if (i < I.getHeight() - 1) {
480 s << std::endl;
481 }
482 }
483
484 s.flags(original_flags); // restore s to standard state
485 return s;
486}
487
488#if defined(VISP_HAVE_PTHREAD) || (defined(_WIN32) && !defined(WINRT_8_0))
489namespace
490{
491struct ImageLut_Param_t {
492 unsigned int m_start_index;
493 unsigned int m_end_index;
494
495 unsigned char m_lut[256];
496 unsigned char *m_bitmap;
497
498 ImageLut_Param_t() : m_start_index(0), m_end_index(0), m_lut(), m_bitmap(NULL) {}
499
500 ImageLut_Param_t(unsigned int start_index, unsigned int end_index, unsigned char *bitmap)
501 : m_start_index(start_index), m_end_index(end_index), m_lut(), m_bitmap(bitmap)
502 {
503 }
504};
505
506vpThread::Return performLutThread(vpThread::Args args)
507{
508 ImageLut_Param_t *imageLut_param = static_cast<ImageLut_Param_t *>(args);
509 unsigned int start_index = imageLut_param->m_start_index;
510 unsigned int end_index = imageLut_param->m_end_index;
511
512 unsigned char *bitmap = imageLut_param->m_bitmap;
513
514 unsigned char *ptrStart = bitmap + start_index;
515 unsigned char *ptrEnd = bitmap + end_index;
516 unsigned char *ptrCurrent = ptrStart;
517
518 // while(ptrCurrent != ptrEnd) {
519 // *ptrCurrent = imageLut_param->m_lut[*ptrCurrent];
520 // ++ptrCurrent;
521 // }
522
523 if (end_index - start_index >= 8) {
524 // Unroll loop version
525 for (; ptrCurrent <= ptrEnd - 8;) {
526 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent];
527 ++ptrCurrent;
528
529 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent];
530 ++ptrCurrent;
531
532 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent];
533 ++ptrCurrent;
534
535 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent];
536 ++ptrCurrent;
537
538 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent];
539 ++ptrCurrent;
540
541 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent];
542 ++ptrCurrent;
543
544 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent];
545 ++ptrCurrent;
546
547 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent];
548 ++ptrCurrent;
549 }
550 }
551
552 for (; ptrCurrent != ptrEnd; ++ptrCurrent) {
553 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent];
554 }
555
556 return 0;
557}
558
559struct ImageLutRGBa_Param_t {
560 unsigned int m_start_index;
561 unsigned int m_end_index;
562
563 vpRGBa m_lut[256];
564 unsigned char *m_bitmap;
565
566 ImageLutRGBa_Param_t() : m_start_index(0), m_end_index(0), m_lut(), m_bitmap(NULL) {}
567
568 ImageLutRGBa_Param_t(unsigned int start_index, unsigned int end_index, unsigned char *bitmap)
569 : m_start_index(start_index), m_end_index(end_index), m_lut(), m_bitmap(bitmap)
570 {
571 }
572};
573
574vpThread::Return performLutRGBaThread(vpThread::Args args)
575{
576 ImageLutRGBa_Param_t *imageLut_param = static_cast<ImageLutRGBa_Param_t *>(args);
577 unsigned int start_index = imageLut_param->m_start_index;
578 unsigned int end_index = imageLut_param->m_end_index;
579
580 unsigned char *bitmap = imageLut_param->m_bitmap;
581
582 unsigned char *ptrStart = bitmap + start_index * 4;
583 unsigned char *ptrEnd = bitmap + end_index * 4;
584 unsigned char *ptrCurrent = ptrStart;
585
586 if (end_index - start_index >= 4 * 2) {
587 // Unroll loop version
588 for (; ptrCurrent <= ptrEnd - 4 * 2;) {
589 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].R;
590 ptrCurrent++;
591 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].G;
592 ptrCurrent++;
593 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].B;
594 ptrCurrent++;
595 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].A;
596 ptrCurrent++;
597
598 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].R;
599 ptrCurrent++;
600 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].G;
601 ptrCurrent++;
602 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].B;
603 ptrCurrent++;
604 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].A;
605 ptrCurrent++;
606 }
607 }
608
609 while (ptrCurrent != ptrEnd) {
610 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].R;
611 ptrCurrent++;
612
613 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].G;
614 ptrCurrent++;
615
616 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].B;
617 ptrCurrent++;
618
619 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].A;
620 ptrCurrent++;
621 }
622
623 return 0;
624}
625}
626#endif
627
631template <class Type> void vpImage<Type>::init(unsigned int h, unsigned int w, Type value)
632{
633 init(h, w);
634
635 // for (unsigned int i = 0; i < npixels; i++)
636 // bitmap[i] = value;
637 std::fill(bitmap, bitmap + npixels, value);
638}
639
643template <class Type> void vpImage<Type>::init(unsigned int h, unsigned int w)
644{
645 if (h != this->height) {
646 if (row != NULL) {
647 vpDEBUG_TRACE(10, "Destruction row[]");
648 delete[] row;
649 row = NULL;
650 }
651 }
652
653 if ((h != this->height) || (w != this->width)) {
654 if (bitmap != NULL) {
655 vpDEBUG_TRACE(10, "Destruction bitmap[]");
656 if (hasOwnership) {
657 delete[] bitmap;
658 }
659 bitmap = NULL;
660 }
661 }
662
663 this->width = w;
664 this->height = h;
665
666 npixels = width * height;
667
668 if (bitmap == NULL) {
669 bitmap = new Type[npixels];
670 hasOwnership = true;
671 }
672
673 if (bitmap == NULL) {
674 throw(vpException(vpException::memoryAllocationError, "cannot allocate bitmap "));
675 }
676
677 if (row == NULL)
678 row = new Type *[height];
679 if (row == NULL) {
680 throw(vpException(vpException::memoryAllocationError, "cannot allocate row "));
681 }
682
683 for (unsigned int i = 0; i < height; i++)
684 row[i] = bitmap + i * width;
685}
686
690template <class Type>
691void vpImage<Type>::init(Type *const array, unsigned int h, unsigned int w, bool copyData)
692{
693 if (h != this->height) {
694 if (row != NULL) {
695 delete[] row;
696 row = NULL;
697 }
698 }
699
700 // Delete bitmap if copyData==false, otherwise only if the dimension differs
701 if ((copyData && ((h != this->height) || (w != this->width))) || !copyData) {
702 if (bitmap != NULL) {
703 if (hasOwnership) {
704 delete[] bitmap;
705 }
706 bitmap = NULL;
707 }
708 }
709
710 hasOwnership = copyData;
711 this->width = w;
712 this->height = h;
713
714 npixels = width * height;
715
716 if (copyData) {
717 if (bitmap == NULL)
718 bitmap = new Type[npixels];
719
720 if (bitmap == NULL) {
721 throw(vpException(vpException::memoryAllocationError, "cannot allocate bitmap "));
722 }
723
724 // Copy the image data
725 memcpy(static_cast<void*>(bitmap), static_cast<void*>(array), (size_t)(npixels * sizeof(Type)));
726 } else {
727 // Copy the address of the array in the bitmap
728 bitmap = array;
729 }
730
731 if (row == NULL)
732 row = new Type *[height];
733 if (row == NULL) {
734 throw(vpException(vpException::memoryAllocationError, "cannot allocate row "));
735 }
736
737 for (unsigned int i = 0; i < height; i++) {
738 row[i] = bitmap + i * width;
739 }
740}
741
745template <class Type>
746vpImage<Type>::vpImage(unsigned int h, unsigned int w)
747 : bitmap(NULL), display(NULL), npixels(0), width(0), height(0), row(NULL), hasOwnership(true)
748{
749 init(h, w, 0);
750}
751
755template <class Type>
756vpImage<Type>::vpImage(unsigned int h, unsigned int w, Type value)
757 : bitmap(NULL), display(NULL), npixels(0), width(0), height(0), row(NULL), hasOwnership(true)
758{
759 init(h, w, value);
760}
761
765template <class Type>
766vpImage<Type>::vpImage(Type *const array, unsigned int h, unsigned int w, bool copyData)
767 : bitmap(NULL), display(NULL), npixels(0), width(0), height(0), row(NULL), hasOwnership(true)
768{
769 init(array, h, w, copyData);
770}
771
775template <class Type> vpImage<Type>::vpImage() :
776 bitmap(NULL), display(NULL), npixels(0), width(0), height(0), row(NULL), hasOwnership(true)
777{
778}
779
800template <class Type> void vpImage<Type>::resize(unsigned int h, unsigned int w) { init(h, w); }
801
821template <class Type> void vpImage<Type>::resize(unsigned int h, unsigned int w, const Type &val) { init(h, w, val); }
822
829template <class Type> void vpImage<Type>::destroy()
830{
831 // vpERROR_TRACE("Deallocate ");
832
833 if (bitmap != NULL) {
834 // vpERROR_TRACE("Deallocate bitmap memory %p",bitmap);
835 // vpDEBUG_TRACE(20,"Deallocate bitmap memory %p",bitmap);
836 if (hasOwnership) {
837 delete[] bitmap;
838 }
839 bitmap = NULL;
840 }
841
842 if (row != NULL) {
843 // vpERROR_TRACE("Deallocate row memory %p",row);
844 // vpDEBUG_TRACE(20,"Deallocate row memory %p",row);
845 delete[] row;
846 row = NULL;
847 }
848}
849
856template <class Type> vpImage<Type>::~vpImage() { destroy(); }
857
861template <class Type>
863 : bitmap(NULL), display(NULL), npixels(0), width(0), height(0), row(NULL), hasOwnership(true)
864{
865 resize(I.getHeight(), I.getWidth());
866 memcpy(static_cast<void*>(bitmap), static_cast<void*>(I.bitmap), I.npixels * sizeof(Type));
867}
868
869#if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
873template <class Type>
875 : bitmap(I.bitmap), display(I.display), npixels(I.npixels), width(I.width), height(I.height), row(I.row), hasOwnership(I.hasOwnership)
876{
877 I.bitmap = NULL;
878 I.display = NULL;
879 I.npixels = 0;
880 I.width = 0;
881 I.height = 0;
882 I.row = NULL;
883 I.hasOwnership = false;
884}
885#endif
886
892template <class Type> Type vpImage<Type>::getMaxValue() const
893{
894 if (npixels == 0)
895 throw(vpException(vpException::fatalError, "Cannot compute maximum value of an empty image"));
896 Type m = bitmap[0];
897 for (unsigned int i = 0; i < npixels; i++) {
898 if (bitmap[i] > m)
899 m = bitmap[i];
900 }
901 return m;
902}
903
907template <class Type> Type vpImage<Type>::getMeanValue() const
908{
909 if ((height == 0) || (width == 0))
910 return 0.0;
911
912 return getSum() / (height * width);
913}
914
920template <class Type> Type vpImage<Type>::getMinValue() const
921{
922 if (npixels == 0)
923 throw(vpException(vpException::fatalError, "Cannot compute minimum value of an empty image"));
924 Type m = bitmap[0];
925 for (unsigned int i = 0; i < npixels; i++)
926 if (bitmap[i] < m)
927 m = bitmap[i];
928 return m;
929}
930
938template <class Type> void vpImage<Type>::getMinMaxValue(Type &min, Type &max) const
939{
940 if (npixels == 0)
941 throw(vpException(vpException::fatalError, "Cannot get minimum/maximum values of an empty image"));
942
943 min = max = bitmap[0];
944 for (unsigned int i = 0; i < npixels; i++) {
945 if (bitmap[i] < min)
946 min = bitmap[i];
947 if (bitmap[i] > max)
948 max = bitmap[i];
949 }
950}
951
973template <class Type>
974void vpImage<Type>::getMinMaxLoc(vpImagePoint *minLoc, vpImagePoint *maxLoc, Type *minVal, Type *maxVal) const
975{
976 if (npixels == 0)
977 throw(vpException(vpException::fatalError, "Cannot get location of minimum/maximum "
978 "values of an empty image"));
979
980 Type min = bitmap[0], max = bitmap[0];
981 vpImagePoint minLoc_, maxLoc_;
982 for (unsigned int i = 0; i < height; i++) {
983 for (unsigned int j = 0; j < width; j++) {
984 if (row[i][j] < min) {
985 min = row[i][j];
986 minLoc_.set_ij(i, j);
987 }
988
989 if (row[i][j] > max) {
990 max = row[i][j];
991 maxLoc_.set_ij(i, j);
992 }
993 }
994 }
995
996 if (minLoc != NULL)
997 *minLoc = minLoc_;
998
999 if (maxLoc != NULL)
1000 *maxLoc = maxLoc_;
1001
1002 if (minVal != NULL)
1003 *minVal = min;
1004
1005 if (maxVal != NULL)
1006 *maxVal = max;
1007}
1008
1013{
1014 swap(*this, other);
1015 // Swap back display pointer if it was not null
1016 // vpImage<unsigned char> I2(480, 640);
1017 // vpDisplayX d(I2);
1018 // I2 = I1; //copy only the data
1019 if (other.display != NULL)
1020 display = other.display;
1021
1022 return *this;
1023}
1024
1031template <class Type> vpImage<Type> &vpImage<Type>::operator=(const Type &v)
1032{
1033 for (unsigned int i = 0; i < npixels; i++)
1034 bitmap[i] = v;
1035
1036 return *this;
1037}
1038
1044template <class Type> bool vpImage<Type>::operator==(const vpImage<Type> &I)
1045{
1046 if (this->width != I.getWidth())
1047 return false;
1048 if (this->height != I.getHeight())
1049 return false;
1050
1051 // printf("wxh: %dx%d bitmap: %p I.bitmap %p\n", width, height, bitmap,
1052 // I.bitmap);
1053 for (unsigned int i = 0; i < npixels; i++) {
1054 if (bitmap[i] != I.bitmap[i]) {
1055 // std::cout << "differ for pixel " << i << " (" << i%this->height
1056 // << ", " << i - i%this->height << ")" << std::endl;
1057 return false;
1058 }
1059 }
1060 return true;
1061}
1067template <class Type> bool vpImage<Type>::operator!=(const vpImage<Type> &I)
1068{
1069 return !(*this == I);
1070}
1071
1098{
1099 vpImage<Type> C;
1100 sub(*this, B, C);
1101 return C;
1102}
1103
1115template <class Type> void vpImage<Type>::insert(const vpImage<Type> &src, const vpImagePoint &topLeft)
1116{
1117 int itl = (int)topLeft.get_i();
1118 int jtl = (int)topLeft.get_j();
1119
1120 int dest_ibegin = 0;
1121 int dest_jbegin = 0;
1122 int src_ibegin = 0;
1123 int src_jbegin = 0;
1124 int dest_w = (int)this->getWidth();
1125 int dest_h = (int)this->getHeight();
1126 int src_w = (int)src.getWidth();
1127 int src_h = (int)src.getHeight();
1128 int wsize = (int)src.getWidth();
1129 int hsize = (int)src.getHeight();
1130
1131 if (itl >= dest_h || jtl >= dest_w)
1132 return;
1133
1134 if (itl < 0)
1135 src_ibegin = -itl;
1136 else
1137 dest_ibegin = itl;
1138
1139 if (jtl < 0)
1140 src_jbegin = -jtl;
1141 else
1142 dest_jbegin = jtl;
1143
1144 if (src_w - src_jbegin > dest_w - dest_jbegin)
1145 wsize = dest_w - dest_jbegin;
1146 else
1147 wsize = src_w - src_jbegin;
1148
1149 if (src_h - src_ibegin > dest_h - dest_ibegin)
1150 hsize = dest_h - dest_ibegin;
1151 else
1152 hsize = src_h - src_ibegin;
1153
1154 for (int i = 0; i < hsize; i++) {
1155 Type *srcBitmap = src.bitmap + ((src_ibegin + i) * src_w + src_jbegin);
1156 Type *destBitmap = this->bitmap + ((dest_ibegin + i) * dest_w + dest_jbegin);
1157
1158 memcpy(static_cast<void*>(destBitmap), static_cast<void*>(srcBitmap), (size_t)wsize * sizeof(Type));
1159 }
1160}
1161
1192template <class Type> void vpImage<Type>::halfSizeImage(vpImage<Type> &res) const
1193{
1194 unsigned int h = height / 2;
1195 unsigned int w = width / 2;
1196 res.resize(h, w);
1197 for (unsigned int i = 0; i < h; i++)
1198 for (unsigned int j = 0; j < w; j++)
1199 res[i][j] = (*this)[i << 1][j << 1];
1200}
1201
1219template <class Type>
1220void vpImage<Type>::subsample(unsigned int v_scale, unsigned int h_scale, vpImage<Type> &sampled) const
1221{
1222 if (v_scale == 1 && h_scale == 1) {
1223 sampled = (*this);
1224 return;
1225 }
1226 unsigned int h = height / v_scale;
1227 unsigned int w = width / h_scale;
1228 sampled.resize(h, w);
1229 for (unsigned int i = 0; i < h; i++)
1230 for (unsigned int j = 0; j < w; j++)
1231 sampled[i][j] = (*this)[i * v_scale][j * h_scale];
1232}
1233
1256template <class Type> void vpImage<Type>::quarterSizeImage(vpImage<Type> &res) const
1257{
1258 unsigned int h = height / 4;
1259 unsigned int w = width / 4;
1260 res.resize(h, w);
1261 for (unsigned int i = 0; i < h; i++)
1262 for (unsigned int j = 0; j < w; j++)
1263 res[i][j] = (*this)[i << 2][j << 2];
1264}
1265
1298template <class Type> void vpImage<Type>::doubleSizeImage(vpImage<Type> &res)
1299{
1300 int h = height * 2;
1301 int w = width * 2;
1302
1303 res.resize(h, w);
1304
1305 for (int i = 0; i < h; i++)
1306 for (int j = 0; j < w; j++)
1307 res[i][j] = (*this)[i >> 1][j >> 1];
1308
1309 /*
1310 A B C
1311 E F G
1312 H I J
1313 A C H J are pixels from original image
1314 B E G I are interpolated pixels
1315 */
1316
1317 // interpolate pixels B and I
1318 for (int i = 0; i < h; i += 2)
1319 for (int j = 1; j < w - 1; j += 2)
1320 res[i][j] = (Type)(0.5 * ((*this)[i >> 1][j >> 1] + (*this)[i >> 1][(j >> 1) + 1]));
1321
1322 // interpolate pixels E and G
1323 for (int i = 1; i < h - 1; i += 2)
1324 for (int j = 0; j < w; j += 2)
1325 res[i][j] = (Type)(0.5 * ((*this)[i >> 1][j >> 1] + (*this)[(i >> 1) + 1][j >> 1]));
1326
1327 // interpolate pixel F
1328 for (int i = 1; i < h - 1; i += 2)
1329 for (int j = 1; j < w - 1; j += 2)
1330 res[i][j] = (Type)(0.25 * ((*this)[i >> 1][j >> 1] + (*this)[i >> 1][(j >> 1) + 1] +
1331 (*this)[(i >> 1) + 1][j >> 1] + (*this)[(i >> 1) + 1][(j >> 1) + 1]));
1332}
1333
1346template <class Type> inline Type vpImage<Type>::getValue(unsigned int i, unsigned int j) const
1347{
1348 if (i >= height || j >= width) {
1349 throw(vpException(vpImageException::notInTheImage, "Pixel outside the image"));
1350 }
1351
1352 return row[i][j];
1353}
1354
1371template <class Type> Type vpImage<Type>::getValue(double i, double j) const
1372{
1373 if (i < 0 || j < 0 || i+1 > height || j+1 > width) {
1374 throw(vpException(vpImageException::notInTheImage, "Pixel outside of the image"));
1375 }
1376 if (height * width == 0) {
1378 }
1379
1380 unsigned int iround = static_cast<unsigned int>(floor(i));
1381 unsigned int jround = static_cast<unsigned int>(floor(j));
1382
1383 double rratio = i - static_cast<double>(iround);
1384 double cratio = j - static_cast<double>(jround);
1385
1386 double rfrac = 1.0 - rratio;
1387 double cfrac = 1.0 - cratio;
1388
1389 unsigned int iround_1 = (std::min)(height - 1, iround + 1);
1390 unsigned int jround_1 = (std::min)(width - 1, jround + 1);
1391
1392 double value = (static_cast<double>(row[iround][jround]) * rfrac + static_cast<double>(row[iround_1][jround]) * rratio) * cfrac +
1393 (static_cast<double>(row[iround][jround_1]) * rfrac + static_cast<double>(row[iround_1][jround_1]) * rratio) * cratio;
1394
1395 return static_cast<Type>(vpMath::round(value));
1396}
1397
1401template <> inline double vpImage<double>::getValue(double i, double j) const
1402{
1403 if (i < 0 || j < 0 || i+1 > height || j+1 > width) {
1404 throw(vpException(vpImageException::notInTheImage, "Pixel outside of the image"));
1405 }
1406 if (height * width == 0) {
1408 }
1409
1410 unsigned int iround = static_cast<unsigned int>(floor(i));
1411 unsigned int jround = static_cast<unsigned int>(floor(j));
1412
1413 double rratio = i - static_cast<double>(iround);
1414 double cratio = j - static_cast<double>(jround);
1415
1416 double rfrac = 1.0 - rratio;
1417 double cfrac = 1.0 - cratio;
1418
1419 unsigned int iround_1 = (std::min)(height - 1, iround + 1);
1420 unsigned int jround_1 = (std::min)(width - 1, jround + 1);
1421
1422 return (row[iround][jround] * rfrac + row[iround_1][jround] * rratio) * cfrac +
1423 (row[iround][jround_1] * rfrac + row[iround_1][jround_1] * rratio) * cratio;
1424}
1425
1429template <> inline unsigned char vpImage<unsigned char>::getValue(double i, double j) const {
1430 if (i < 0 || j < 0 || i+1 > height || j+1 > width) {
1431 throw(vpException(vpImageException::notInTheImage, "Pixel outside of the image"));
1432 }
1433 if (height * width == 0) {
1435 }
1436
1437 // alpha architecture is bi-endianness. The following optimization makes testImageGetValue failing
1438#if (defined(VISP_LITTLE_ENDIAN) || defined(VISP_BIG_ENDIAN)) && !(defined(__alpha__) || defined(_M_ALPHA))
1439 //Fixed-point arithmetic
1440 const int32_t precision = 1 << 16;
1441 int64_t y = static_cast<int64_t>(i * precision);
1442 int64_t x = static_cast<int64_t>(j * precision);
1443
1444 int64_t iround = y & (~0xFFFF);
1445 int64_t jround = x & (~0xFFFF);
1446
1447 int64_t rratio = y - iround;
1448 int64_t cratio = x - jround;
1449
1450 int64_t rfrac = precision - rratio;
1451 int64_t cfrac = precision - cratio;
1452
1453 int64_t x_ = x >> 16;
1454 int64_t y_ = y >> 16;
1455
1456 if (y_ + 1 < height && x_ + 1 < width) {
1457 uint16_t up = vpEndian::reinterpret_cast_uchar_to_uint16_LE(bitmap + y_ * width + x_);
1458 uint16_t down = vpEndian::reinterpret_cast_uchar_to_uint16_LE(bitmap + (y_ + 1) * width + x_);
1459
1460 return static_cast<unsigned char>((((up & 0x00FF) * rfrac + (down & 0x00FF) * rratio) * cfrac +
1461 ((up >> 8) * rfrac + (down >> 8) * rratio) * cratio) >> 32);
1462 } else if (y_ + 1 < height) {
1463 return static_cast<unsigned char>(((row[y_][x_] * rfrac + row[y_ + 1][x_] * rratio)) >> 16);
1464 } else if (x_ + 1 < width) {
1465 uint16_t up = vpEndian::reinterpret_cast_uchar_to_uint16_LE(bitmap + y_ * width + x_);
1466 return static_cast<unsigned char>(((up & 0x00FF) * cfrac + (up >> 8) * cratio) >> 16);
1467 } else {
1468 return row[y_][x_];
1469 }
1470#else
1471 unsigned int iround = static_cast<unsigned int>(floor(i));
1472 unsigned int jround = static_cast<unsigned int>(floor(j));
1473
1474 if (iround >= height || jround >= width) {
1475 vpERROR_TRACE("Pixel outside the image") ;
1477 "Pixel outside the image"));
1478 }
1479
1480 double rratio = i - static_cast<double>(iround);
1481 double cratio = j - static_cast<double>(jround);
1482
1483 double rfrac = 1.0 - rratio;
1484 double cfrac = 1.0 - cratio;
1485
1486 unsigned int iround_1 = (std::min)(height - 1, iround + 1);
1487 unsigned int jround_1 = (std::min)(width - 1, jround + 1);
1488
1489 double value = (static_cast<double>(row[iround][jround]) * rfrac + static_cast<double>(row[iround_1][jround]) * rratio) * cfrac +
1490 (static_cast<double>(row[iround][jround_1]) * rfrac + static_cast<double>(row[iround_1][jround_1]) * rratio) * cratio;
1491 return static_cast<unsigned char>(vpMath::round(value));
1492#endif
1493}
1494
1498template <> inline vpRGBa vpImage<vpRGBa>::getValue(double i, double j) const
1499{
1500 if (i < 0 || j < 0 || i+1 > height || j+1 > width) {
1501 throw(vpException(vpImageException::notInTheImage, "Pixel outside of the image"));
1502 }
1503 if (height * width == 0) {
1505 }
1506
1507 unsigned int iround = static_cast<unsigned int>(floor(i));
1508 unsigned int jround = static_cast<unsigned int>(floor(j));
1509
1510 double rratio = i - static_cast<double>(iround);
1511 double cratio = j - static_cast<double>(jround);
1512
1513 double rfrac = 1.0 - rratio;
1514 double cfrac = 1.0 - cratio;
1515
1516 unsigned int iround_1 = (std::min)(height - 1, iround + 1);
1517 unsigned int jround_1 = (std::min)(width - 1, jround + 1);
1518
1519 double valueR = (static_cast<double>(row[iround][jround].R) * rfrac + static_cast<double>(row[iround_1][jround].R) * rratio) * cfrac +
1520 (static_cast<double>(row[iround][jround_1].R) * rfrac + static_cast<double>(row[iround_1][jround_1].R) * rratio) * cratio;
1521 double valueG = (static_cast<double>(row[iround][jround].G) * rfrac + static_cast<double>(row[iround_1][jround].G) * rratio) * cfrac +
1522 (static_cast<double>(row[iround][jround_1].G) * rfrac + static_cast<double>(row[iround_1][jround_1].G) * rratio) * cratio;
1523 double valueB = (static_cast<double>(row[iround][jround].B) * rfrac + static_cast<double>(row[iround_1][jround].B) * rratio) * cfrac +
1524 (static_cast<double>(row[iround][jround_1].B) * rfrac + static_cast<double>(row[iround_1][jround_1].B) * rratio) * cratio;
1525
1526 return vpRGBa(static_cast<unsigned char>(vpMath::round(valueR)),
1527 static_cast<unsigned char>(vpMath::round(valueG)),
1528 static_cast<unsigned char>(vpMath::round(valueB)));
1529}
1530
1547template <class Type> inline Type vpImage<Type>::getValue(const vpImagePoint &ip) const
1548{
1549 return getValue(ip.get_i(), ip.get_j());
1550}
1551
1555template <> inline double vpImage<double>::getValue(const vpImagePoint &ip) const
1556{
1557 return getValue(ip.get_i(), ip.get_j());
1558}
1559
1563template <> inline unsigned char vpImage<unsigned char>::getValue(const vpImagePoint &ip) const
1564{
1565 return getValue(ip.get_i(), ip.get_j());
1566}
1567
1571template <> inline vpRGBa vpImage<vpRGBa>::getValue(const vpImagePoint &ip) const
1572{
1573 return getValue(ip.get_i(), ip.get_j());
1574}
1575
1579template <class Type> inline double vpImage<Type>::getSum() const
1580{
1581 if ((height == 0) || (width == 0))
1582 return 0.0;
1583
1584 double res = 0.0;
1585 for (unsigned int i = 0; i < height * width; ++i) {
1586 res += static_cast<double>(bitmap[i]);
1587 }
1588 return res;
1589}
1590
1620template <class Type> void vpImage<Type>::sub(const vpImage<Type> &B, vpImage<Type> &C)
1621{
1622
1623 try {
1624 if ((this->getHeight() != C.getHeight()) || (this->getWidth() != C.getWidth()))
1625 C.resize(this->getHeight(), this->getWidth());
1626 } catch (const vpException &me) {
1627 std::cout << me << std::endl;
1628 throw;
1629 }
1630
1631 if ((this->getWidth() != B.getWidth()) || (this->getHeight() != B.getHeight())) {
1632 throw(vpException(vpException::memoryAllocationError, "vpImage mismatch in vpImage/vpImage subtraction"));
1633 }
1634
1635 for (unsigned int i = 0; i < this->getWidth() * this->getHeight(); i++) {
1636 *(C.bitmap + i) = *(bitmap + i) - *(B.bitmap + i);
1637 }
1638}
1639
1651template <class Type> void vpImage<Type>::sub(const vpImage<Type> &A, const vpImage<Type> &B, vpImage<Type> &C)
1652{
1653
1654 try {
1655 if ((A.getHeight() != C.getHeight()) || (A.getWidth() != C.getWidth()))
1656 C.resize(A.getHeight(), A.getWidth());
1657 } catch (const vpException &me) {
1658 std::cout << me << std::endl;
1659 throw;
1660 }
1661
1662 if ((A.getWidth() != B.getWidth()) || (A.getHeight() != B.getHeight())) {
1663 throw(vpException(vpException::memoryAllocationError, "vpImage mismatch in vpImage/vpImage subtraction "));
1664 }
1665
1666 for (unsigned int i = 0; i < A.getWidth() * A.getHeight(); i++) {
1667 *(C.bitmap + i) = *(A.bitmap + i) - *(B.bitmap + i);
1668 }
1669}
1670
1679template <class Type> void vpImage<Type>::performLut(const Type (&)[256], unsigned int)
1680{
1681 std::cerr << "Not implemented !" << std::endl;
1682}
1683
1694template <> inline void vpImage<unsigned char>::performLut(const unsigned char (&lut)[256], unsigned int nbThreads)
1695{
1696 unsigned int size = getWidth() * getHeight();
1697 unsigned char *ptrStart = (unsigned char *)bitmap;
1698 unsigned char *ptrEnd = ptrStart + size;
1699 unsigned char *ptrCurrent = ptrStart;
1700
1701 bool use_single_thread = (nbThreads == 0 || nbThreads == 1);
1702#if !defined(VISP_HAVE_PTHREAD) && !defined(_WIN32)
1703 use_single_thread = true;
1704#endif
1705
1706 if (!use_single_thread && getSize() <= nbThreads) {
1707 use_single_thread = true;
1708 }
1709
1710 if (use_single_thread) {
1711 // Single thread
1712
1713 while (ptrCurrent != ptrEnd) {
1714 *ptrCurrent = lut[*ptrCurrent];
1715 ++ptrCurrent;
1716 }
1717 } else {
1718#if defined(VISP_HAVE_PTHREAD) || (defined(_WIN32) && !defined(WINRT_8_0))
1719 // Multi-threads
1720
1721 std::vector<vpThread *> threadpool;
1722 std::vector<ImageLut_Param_t *> imageLutParams;
1723
1724 unsigned int image_size = getSize();
1725 unsigned int step = image_size / nbThreads;
1726 unsigned int last_step = image_size - step * (nbThreads - 1);
1727
1728 for (unsigned int index = 0; index < nbThreads; index++) {
1729 unsigned int start_index = index * step;
1730 unsigned int end_index = (index + 1) * step;
1731
1732 if (index == nbThreads - 1) {
1733 end_index = start_index + last_step;
1734 }
1735
1736 ImageLut_Param_t *imageLut_param = new ImageLut_Param_t(start_index, end_index, bitmap);
1737 memcpy(imageLut_param->m_lut, lut, 256 * sizeof(unsigned char));
1738
1739 imageLutParams.push_back(imageLut_param);
1740
1741 // Start the threads
1742 vpThread *imageLut_thread = new vpThread((vpThread::Fn)performLutThread, (vpThread::Args)imageLut_param);
1743 threadpool.push_back(imageLut_thread);
1744 }
1745
1746 for (size_t cpt = 0; cpt < threadpool.size(); cpt++) {
1747 // Wait until thread ends up
1748 threadpool[cpt]->join();
1749 }
1750
1751 // Delete
1752 for (size_t cpt = 0; cpt < threadpool.size(); cpt++) {
1753 delete threadpool[cpt];
1754 }
1755
1756 for (size_t cpt = 0; cpt < imageLutParams.size(); cpt++) {
1757 delete imageLutParams[cpt];
1758 }
1759#endif
1760 }
1761}
1762
1773template <> inline void vpImage<vpRGBa>::performLut(const vpRGBa (&lut)[256], unsigned int nbThreads)
1774{
1775 unsigned int size = getWidth() * getHeight();
1776 unsigned char *ptrStart = (unsigned char *)bitmap;
1777 unsigned char *ptrEnd = ptrStart + size * 4;
1778 unsigned char *ptrCurrent = ptrStart;
1779
1780 bool use_single_thread = (nbThreads == 0 || nbThreads == 1);
1781#if !defined(VISP_HAVE_PTHREAD) && !defined(_WIN32)
1782 use_single_thread = true;
1783#endif
1784
1785 if (!use_single_thread && getSize() <= nbThreads) {
1786 use_single_thread = true;
1787 }
1788
1789 if (use_single_thread) {
1790 // Single thread
1791 while (ptrCurrent != ptrEnd) {
1792 *ptrCurrent = lut[*ptrCurrent].R;
1793 ++ptrCurrent;
1794
1795 *ptrCurrent = lut[*ptrCurrent].G;
1796 ++ptrCurrent;
1797
1798 *ptrCurrent = lut[*ptrCurrent].B;
1799 ++ptrCurrent;
1800
1801 *ptrCurrent = lut[*ptrCurrent].A;
1802 ++ptrCurrent;
1803 }
1804 } else {
1805#if defined(VISP_HAVE_PTHREAD) || (defined(_WIN32) && !defined(WINRT_8_0))
1806 // Multi-threads
1807 std::vector<vpThread *> threadpool;
1808 std::vector<ImageLutRGBa_Param_t *> imageLutParams;
1809
1810 unsigned int image_size = getSize();
1811 unsigned int step = image_size / nbThreads;
1812 unsigned int last_step = image_size - step * (nbThreads - 1);
1813
1814 for (unsigned int index = 0; index < nbThreads; index++) {
1815 unsigned int start_index = index * step;
1816 unsigned int end_index = (index + 1) * step;
1817
1818 if (index == nbThreads - 1) {
1819 end_index = start_index + last_step;
1820 }
1821
1822 ImageLutRGBa_Param_t *imageLut_param = new ImageLutRGBa_Param_t(start_index, end_index, (unsigned char *)bitmap);
1823 memcpy(static_cast<void*>(imageLut_param->m_lut), lut, 256 * sizeof(vpRGBa));
1824
1825 imageLutParams.push_back(imageLut_param);
1826
1827 // Start the threads
1828 vpThread *imageLut_thread = new vpThread((vpThread::Fn)performLutRGBaThread, (vpThread::Args)imageLut_param);
1829 threadpool.push_back(imageLut_thread);
1830 }
1831
1832 for (size_t cpt = 0; cpt < threadpool.size(); cpt++) {
1833 // Wait until thread ends up
1834 threadpool[cpt]->join();
1835 }
1836
1837 // Delete
1838 for (size_t cpt = 0; cpt < threadpool.size(); cpt++) {
1839 delete threadpool[cpt];
1840 }
1841
1842 for (size_t cpt = 0; cpt < imageLutParams.size(); cpt++) {
1843 delete imageLutParams[cpt];
1844 }
1845#endif
1846 }
1847}
1848
1849template <class Type> void swap(vpImage<Type> &first, vpImage<Type> &second)
1850{
1851 using std::swap;
1852 swap(first.bitmap, second.bitmap);
1853 swap(first.display, second.display);
1854 swap(first.npixels, second.npixels);
1855 swap(first.width, second.width);
1856 swap(first.height, second.height);
1857 swap(first.row, second.row);
1858}
1859
1860#endif
friend std::ostream & operator<<(std::ostream &s, const vpArray2D< Type > &A)
Definition: vpArray2D.h:493
Class that defines generic functionnalities for display.
Definition: vpDisplay.h:178
error that can be emited by ViSP classes.
Definition: vpException.h:72
@ memoryAllocationError
Memory allocation error.
Definition: vpException.h:88
@ fatalError
Fatal error.
Definition: vpException.h:96
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition: vpImagePoint.h:88
double get_j() const
Definition: vpImagePoint.h:214
void set_ij(double ii, double jj)
Definition: vpImagePoint.h:188
double get_i() const
Definition: vpImagePoint.h:203
Definition of the vpImage class member functions.
Definition: vpImage.h:139
Type operator()(const vpImagePoint &ip) const
Definition: vpImage.h:294
friend std::ostream & operator<<(std::ostream &s, const vpImage< float > &I)
Definition: vpImage.h:434
void destroy()
Destructor : Memory de-allocation.
Definition: vpImage.h:829
bool operator==(const vpImage< Type > &I)
Definition: vpImage.h:1044
void subsample(unsigned int v_scale, unsigned int h_scale, vpImage< Type > &sampled) const
Definition: vpImage.h:1220
void halfSizeImage(vpImage< Type > &res) const
Definition: vpImage.h:1192
vpImage< Type > & operator=(vpImage< Type > other)
Copy operator.
Definition: vpImage.h:1012
Type getMeanValue() const
Return the mean value of the bitmap.
Definition: vpImage.h:907
double getSum() const
Definition: vpImage.h:1579
void getMinMaxLoc(vpImagePoint *minLoc, vpImagePoint *maxLoc, Type *minVal=NULL, Type *maxVal=NULL) const
Get the position of the minimum and/or the maximum pixel value within the bitmap and the correspondin...
Definition: vpImage.h:974
friend std::ostream & operator<<(std::ostream &s, const vpImage< char > &I)
Definition: vpImage.h:408
const Type * operator[](int i) const
Definition: vpImage.h:268
void quarterSizeImage(vpImage< Type > &res) const
Definition: vpImage.h:1256
void init(unsigned int height, unsigned int width)
Set the size of the image.
Definition: vpImage.h:643
void resize(unsigned int h, unsigned int w, const Type &val)
resize the image : Image initialization
Definition: vpImage.h:821
unsigned int getWidth() const
Definition: vpImage.h:246
void getMinMaxValue(Type &min, Type &max) const
Look for the minimum and the maximum value within the bitmap.
Definition: vpImage.h:938
void resize(unsigned int h, unsigned int w)
resize the image : Image initialization
Definition: vpImage.h:800
unsigned int getNumberOfPixel() const
Definition: vpImage.h:209
Type getValue(double i, double j) const
Definition: vpImage.h:1371
void doubleSizeImage(vpImage< Type > &res)
Definition: vpImage.h:1298
void sub(const vpImage< Type > &B, vpImage< Type > &C)
Definition: vpImage.h:1620
vpImage(unsigned int height, unsigned int width, Type value)
constructor set the size of the image and init all the pixel
Definition: vpImage.h:756
void performLut(const Type(&lut)[256], unsigned int nbThreads=1)
Definition: vpImage.h:1679
vpImage< Type > operator-(const vpImage< Type > &B)
Definition: vpImage.h:1097
void insert(const vpImage< Type > &src, const vpImagePoint &topLeft)
Definition: vpImage.h:1115
Type getValue(unsigned int i, unsigned int j) const
Definition: vpImage.h:1346
Type * operator[](unsigned int i)
operator[] allows operation like I[i] = x.
Definition: vpImage.h:263
Type getMinValue() const
Return the minimum value within the bitmap.
Definition: vpImage.h:920
void init(unsigned int height, unsigned int width, Type value)
Set the size of the image.
Definition: vpImage.h:631
unsigned int getSize() const
Definition: vpImage.h:227
friend void swap(vpImage< Type > &first, vpImage< Type > &second)
Definition: vpImage.h:1849
unsigned int getCols() const
Definition: vpImage.h:179
Type * bitmap
points toward the bitmap
Definition: vpImage.h:143
void sub(const vpImage< Type > &A, const vpImage< Type > &B, vpImage< Type > &C)
Definition: vpImage.h:1651
Type getValue(const vpImagePoint &ip) const
Definition: vpImage.h:1547
bool operator!=(const vpImage< Type > &I)
Definition: vpImage.h:1067
const Type * operator[](unsigned int i) const
operator[] allows operation like x = I[i]
Definition: vpImage.h:267
vpImage(Type *const array, unsigned int height, unsigned int width, bool copyData=false)
constructor from an image stored as a continuous array in memory
Definition: vpImage.h:766
Type getMaxValue() const
Return the maximum value within the bitmap.
Definition: vpImage.h:892
void init(Type *const array, unsigned int height, unsigned int width, bool copyData=false)
init from an image stored as a continuous array in memory
Definition: vpImage.h:691
Type * operator[](int i)
Definition: vpImage.h:264
virtual ~vpImage()
destructor
Definition: vpImage.h:856
unsigned int getHeight() const
Definition: vpImage.h:188
unsigned int getRows() const
Definition: vpImage.h:218
vpImage< Type > & operator=(const Type &v)
= operator : Set all the element of the bitmap to a given value v.
Definition: vpImage.h:1031
vpDisplay * display
Definition: vpImage.h:144
friend std::ostream & operator<<(std::ostream &s, const vpImage< double > &I)
Definition: vpImage.h:461
vpImage()
constructor
Definition: vpImage.h:775
void operator()(const vpImagePoint &ip, const Type &v)
Definition: vpImage.h:310
Type operator()(unsigned int i, unsigned int j) const
Definition: vpImage.h:276
vpImage(vpImage< Type > &&)
move constructor
Definition: vpImage.h:874
friend std::ostream & operator<<(std::ostream &s, const vpImage< unsigned char > &I)
Definition: vpImage.h:382
void init(unsigned int h, unsigned int w, Type value)
Definition: vpImage.h:631
double getValue(double i, double j) const
Definition: vpImage.h:1401
vpImage(const vpImage< Type > &)
copy constructor
Definition: vpImage.h:862
vpImage(unsigned int height, unsigned int width)
constructor set the size of the image
Definition: vpImage.h:746
void operator()(unsigned int i, unsigned int j, const Type &v)
Definition: vpImage.h:282
static int round(double x)
Definition: vpMath.h:247
Definition: vpRGBa.h:67
void * Return
Definition: vpThread.h:78
void *(* Fn)(Args)
Definition: vpThread.h:79
void * Args
Definition: vpThread.h:77
#define vpDEBUG_TRACE
Definition: vpDebug.h:487
#define vpERROR_TRACE
Definition: vpDebug.h:393
VISP_EXPORT uint16_t reinterpret_cast_uchar_to_uint16_LE(unsigned char *const ptr)
Definition: vpEndian.cpp:111