42 #include <visp3/core/vpConfig.h>
43 #include <visp3/core/vpDebug.h>
44 #include <visp3/core/vpEndian.h>
45 #include <visp3/core/vpException.h>
46 #include <visp3/core/vpImageException.h>
47 #include <visp3/core/vpImagePoint.h>
48 #include <visp3/core/vpRGBa.h>
49 #include <visp3/core/vpRGBf.h>
51 #if defined(VISP_HAVE_THREADS)
62 #if defined(_MSC_VER) && (_MSC_VER < 1700)
63 typedef long long int64_t;
64 typedef unsigned short uint16_t;
122 template <
class Type>
class vpImage;
134 template <
class Type>
class vpImage
146 #if ((__cplusplus >= 201103L) || (defined(_MSVC_LANG) && (_MSVC_LANG >= 201103L)))
148 vpImage(vpImage<Type> &&);
151 vpImage(
unsigned int height,
unsigned int width);
153 vpImage(
unsigned int height,
unsigned int width, Type value);
155 vpImage(Type *
const array,
unsigned int height,
unsigned int width,
bool copyData =
false);
175 inline unsigned int getCols()
const {
return width; }
184 inline unsigned int getHeight()
const {
return height; }
215 inline unsigned int getRows()
const {
return height; }
224 inline unsigned int getSize()
const {
return width * height; }
227 double getStdev(
const double &mean,
const vpImage<bool> *p_mask =
nullptr,
unsigned int *nbValidPoints =
nullptr)
const;
232 Type
getValue(
unsigned int i,
unsigned int j)
const;
245 inline unsigned int getWidth()
const {
return width; }
251 void init(
unsigned int height,
unsigned int width);
253 void init(
unsigned int height,
unsigned int width, Type value);
255 void init(Type *
const array,
unsigned int height,
unsigned int width,
bool copyData =
false);
266 inline const Type *
operator[](
unsigned int i)
const {
return row[i]; }
267 inline const Type *
operator[](
int i)
const {
return row[i]; }
275 inline Type
operator()(
unsigned int i,
unsigned int j)
const {
return bitmap[i * width + j]; }
281 inline void operator()(
unsigned int i,
unsigned int j,
const Type &v) {
bitmap[i * width + j] = v; }
295 unsigned int i = (
unsigned int)ip.
get_i();
296 unsigned int j = (
unsigned int)ip.
get_j();
298 return bitmap[i * width + j];
311 unsigned int i = (
unsigned int)ip.
get_i();
312 unsigned int j = (
unsigned int)ip.
get_j();
314 bitmap[i * width + j] = v;
325 friend std::ostream &operator<< <>(std::ostream &s,
const vpImage<Type> &I);
332 void performLut(
const Type(&lut)[256],
unsigned int nbThreads = 1);
338 void resize(
unsigned int h,
unsigned int w);
340 void resize(
unsigned int h,
unsigned int w,
const Type &val);
351 unsigned int npixels;
360 if (I.
bitmap ==
nullptr) {
364 for (
unsigned int i = 0; i < I.
getHeight(); i++) {
365 for (
unsigned int j = 0; j < I.
getWidth() - 1; j++) {
383 if (I.
bitmap ==
nullptr) {
387 std::ios_base::fmtflags original_flags = s.flags();
389 for (
unsigned int i = 0; i < I.
getHeight(); i++) {
390 for (
unsigned int j = 0; j < I.
getWidth() - 1; j++) {
391 s << std::setw(3) << static_cast<unsigned>(I[i][j]) <<
" ";
395 s << std::setw(3) << static_cast<unsigned>(I[i][I.
getWidth() - 1]);
403 s.flags(original_flags);
409 if (I.
bitmap ==
nullptr) {
413 std::ios_base::fmtflags original_flags = s.flags();
415 for (
unsigned int i = 0; i < I.
getHeight(); i++) {
416 for (
unsigned int j = 0; j < I.
getWidth() - 1; j++) {
417 s << std::setw(4) << static_cast<int>(I[i][j]) <<
" ";
421 s << std::setw(4) << static_cast<int>(I[i][I.
getWidth() - 1]);
429 s.flags(original_flags);
435 if (I.
bitmap ==
nullptr) {
439 std::ios_base::fmtflags original_flags = s.flags();
442 for (
unsigned int i = 0; i < I.
getHeight(); i++) {
443 for (
unsigned int j = 0; j < I.
getWidth() - 1; j++) {
456 s.flags(original_flags);
462 if (I.
bitmap ==
nullptr) {
466 std::ios_base::fmtflags original_flags = s.flags();
469 for (
unsigned int i = 0; i < I.
getHeight(); i++) {
470 for (
unsigned int j = 0; j < I.
getWidth() - 1; j++) {
483 s.flags(original_flags);
487 #if defined(VISP_HAVE_THREADS)
490 struct vpImageLut_Param_t
492 unsigned int m_start_index;
493 unsigned int m_end_index;
495 unsigned char m_lut[256];
496 unsigned char *m_bitmap;
498 vpImageLut_Param_t() : m_start_index(0), m_end_index(0), m_lut(), m_bitmap(nullptr) { }
500 vpImageLut_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)
505 void performLutThread(vpImageLut_Param_t *imageLut_param)
507 unsigned int start_index = imageLut_param->m_start_index;
508 unsigned int end_index = imageLut_param->m_end_index;
510 unsigned char *bitmap = imageLut_param->m_bitmap;
512 unsigned char *ptrStart = bitmap + start_index;
513 unsigned char *ptrEnd = bitmap + end_index;
514 unsigned char *ptrCurrent = ptrStart;
516 if (end_index - start_index >= 8) {
518 for (; ptrCurrent <= ptrEnd - 8;) {
519 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent];
522 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent];
525 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent];
528 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent];
531 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent];
534 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent];
537 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent];
540 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent];
545 for (; ptrCurrent != ptrEnd; ++ptrCurrent) {
546 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent];
550 struct vpImageLutRGBa_Param_t
552 unsigned int m_start_index;
553 unsigned int m_end_index;
556 unsigned char *m_bitmap;
558 vpImageLutRGBa_Param_t() : m_start_index(0), m_end_index(0), m_lut(), m_bitmap(nullptr) { }
560 vpImageLutRGBa_Param_t(
unsigned int start_index,
unsigned int end_index,
unsigned char *bitmap)
561 : m_start_index(start_index), m_end_index(end_index), m_lut(), m_bitmap(bitmap)
565 void performLutRGBaThread(vpImageLutRGBa_Param_t *imageLut_param)
567 unsigned int start_index = imageLut_param->m_start_index;
568 unsigned int end_index = imageLut_param->m_end_index;
570 unsigned char *bitmap = imageLut_param->m_bitmap;
572 unsigned char *ptrStart = bitmap + start_index * 4;
573 unsigned char *ptrEnd = bitmap + end_index * 4;
574 unsigned char *ptrCurrent = ptrStart;
576 if (end_index - start_index >= 4 * 2) {
578 for (; ptrCurrent <= ptrEnd - 4 * 2;) {
579 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].R;
581 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].G;
583 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].B;
585 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].A;
588 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].R;
590 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].G;
592 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].B;
594 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].A;
599 while (ptrCurrent != ptrEnd) {
600 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].R;
603 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].G;
606 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].B;
609 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].A;
625 std::fill(bitmap, bitmap + npixels, value);
633 if (h != this->height) {
634 if (row !=
nullptr) {
640 if ((h != this->height) || (w != this->width)) {
641 if (bitmap !=
nullptr) {
652 npixels = width * height;
654 if (bitmap ==
nullptr) {
655 bitmap =
new Type[npixels];
658 if (bitmap ==
nullptr) {
662 row =
new Type *[height];
663 if (row ==
nullptr) {
667 for (
unsigned int i = 0; i < height; i++)
668 row[i] = bitmap + i * width;
674 template <
class Type>
void vpImage<Type>::init(Type *
const array,
unsigned int h,
unsigned int w,
bool copyData)
676 if (h != this->height) {
677 if (row !=
nullptr) {
684 if ((copyData && ((h != this->height) || (w != this->width))) || !copyData) {
685 if (bitmap !=
nullptr) {
693 hasOwnership = copyData;
697 npixels = width * height;
700 if (bitmap ==
nullptr)
701 bitmap =
new Type[npixels];
703 if (bitmap ==
nullptr) {
708 memcpy(
static_cast<void *
>(bitmap),
static_cast<void *
>(array), (
size_t)(npixels *
sizeof(Type)));
716 row =
new Type *[height];
717 if (row ==
nullptr) {
721 for (
unsigned int i = 0; i < height; i++) {
722 row[i] = bitmap + i * width;
729 template <
class Type>
731 : bitmap(nullptr), display(nullptr), npixels(0), width(0), height(0), row(nullptr), hasOwnership(true)
739 template <
class Type>
741 : bitmap(nullptr), display(nullptr), npixels(0), width(0), height(0), row(nullptr), hasOwnership(true)
749 template <
class Type>
751 : bitmap(nullptr), display(nullptr), npixels(0), width(0), height(0), row(nullptr), hasOwnership(true)
753 init(array, h, w, copyData);
759 template <
class Type>
760 vpImage<Type>::vpImage() : bitmap(nullptr), display(nullptr), npixels(0), width(0), height(0), row(nullptr), hasOwnership(true)
814 if (bitmap !=
nullptr) {
821 if (row !=
nullptr) {
838 template <
class Type>
840 : bitmap(nullptr), display(nullptr), npixels(0), width(0), height(0), row(nullptr), hasOwnership(true)
844 memcpy(
static_cast<void *
>(
bitmap),
static_cast<void *
>(I.
bitmap), I.npixels *
sizeof(Type));
848 #if ((__cplusplus >= 201103L) || (defined(_MSVC_LANG) && (_MSVC_LANG >= 201103L)))
852 template <class Type>
854 : bitmap(I.bitmap), display(I.display), npixels(I.npixels), width(I.width), height(I.height), row(I.row),
855 hasOwnership(I.hasOwnership)
863 I.hasOwnership =
false;
879 for (
unsigned int i = 0; i < npixels; i++) {
902 for (
unsigned int i = 0; i < npixels; i++) {
908 for (
unsigned int i = 0; i < npixels; i++) {
930 for (
unsigned int i = 0; i < npixels; i++) {
936 for (
unsigned int i = 0; i < npixels; i++) {
956 if ((height == 0) || (width == 0)) {
959 unsigned int nbPointsInMask = 0;
960 double sum = getSum(p_mask, &nbPointsInMask);
961 if (nbPointsInMask == 0) {
965 *nbValidPoints = nbPointsInMask;
967 return sum / nbPointsInMask;
987 double mean = getMeanValue(p_mask, nbValidPoints);
988 return getStdev(mean, p_mask);
1011 if ((height == 0) || (width == 0)) {
1014 const unsigned int size = width * height;
1016 unsigned int nbPointsInMask = 0;
1021 for (
unsigned int i = 0; i < size; ++i) {
1023 sum += (bitmap[i] - mean) * (bitmap[i] - mean);
1029 for (
unsigned int i = 0; i < size; ++i) {
1030 sum += (bitmap[i] - mean) * (bitmap[i] - mean);
1032 nbPointsInMask = size;
1034 sum /=
static_cast<double>(nbPointsInMask);
1035 if (nbValidPoints) {
1036 *nbValidPoints = nbPointsInMask;
1038 return std::sqrt(sum);
1041 #ifndef DOXYGEN_SHOULD_SKIP_THIS
1062 if ((height == 0) || (width == 0)) {
1065 const unsigned int size = width * height;
1067 unsigned int nbPointsInMask = 0;
1072 for (
unsigned int i = 0; i < size; ++i) {
1074 double val =
static_cast<double>(
bitmap[i].R) +
static_cast<double>(
bitmap[i].G) +
static_cast<double>(
bitmap[i].B);
1075 sum += (val - mean) * (val - mean);
1081 for (
unsigned int i = 0; i < size; ++i) {
1082 double val =
static_cast<double>(
bitmap[i].R) +
static_cast<double>(
bitmap[i].G) +
static_cast<double>(
bitmap[i].B);
1083 sum += (val - mean) * (val - mean);
1085 nbPointsInMask = size;
1087 sum /=
static_cast<double>(nbPointsInMask);
1088 if (nbValidPoints) {
1089 *nbValidPoints = nbPointsInMask;
1091 return std::sqrt(sum);
1114 if ((height == 0) || (width == 0)) {
1117 const unsigned int size = width * height;
1119 unsigned int nbPointsInMask = 0;
1124 for (
unsigned int i = 0; i < size; ++i) {
1126 double val =
static_cast<double>(bitmap[i].R) +
static_cast<double>(bitmap[i].G) +
static_cast<double>(bitmap[i].B);
1127 sum += (val - mean) * (val - mean);
1133 for (
unsigned int i = 0; i < size; ++i) {
1134 double val =
static_cast<double>(bitmap[i].R) +
static_cast<double>(bitmap[i].G) +
static_cast<double>(bitmap[i].B);
1135 sum += (val - mean) * (val - mean);
1137 nbPointsInMask = size;
1139 sum /=
static_cast<double>(nbPointsInMask);
1140 if (nbValidPoints) {
1141 *nbValidPoints = nbPointsInMask;
1143 return std::sqrt(sum);
1159 for (
unsigned int i = 0; i < npixels; i++) {
1160 if (bitmap[i] < m) {
1164 (void)onlyFiniteVal;
1181 if (onlyFiniteVal) {
1182 for (
unsigned int i = 0; i < npixels; i++)
1187 for (
unsigned int i = 0; i < npixels; i++)
1207 if (onlyFiniteVal) {
1208 for (
unsigned int i = 0; i < npixels; i++)
1213 for (
unsigned int i = 0; i < npixels; i++)
1235 min = max = bitmap[0];
1236 for (
unsigned int i = 0; i < npixels; i++) {
1237 if (bitmap[i] < min)
1239 if (bitmap[i] > max)
1242 (void)onlyFiniteVal;
1262 if (onlyFiniteVal) {
1263 for (
unsigned int i = 0; i < npixels; i++) {
1273 for (
unsigned int i = 0; i < npixels; i++) {
1299 if (onlyFiniteVal) {
1300 for (
unsigned int i = 0; i < npixels; i++) {
1310 for (
unsigned int i = 0; i < npixels; i++) {
1334 min = max = bitmap[0];
1335 if (onlyFiniteVal) {
1336 for (
unsigned int i = 0; i < npixels; i++) {
1338 if (bitmap[i].R < min.
R)
1339 min.
R = bitmap[i].R;
1340 if (bitmap[i].R > max.
R)
1341 max.
R = bitmap[i].R;
1344 if (bitmap[i].G < min.
G)
1345 min.
G = bitmap[i].G;
1346 if (bitmap[i].G > max.
G)
1347 max.
G = bitmap[i].G;
1350 if (bitmap[i].B < min.
B)
1351 min.
B = bitmap[i].B;
1352 if (bitmap[i].B > max.
B)
1353 max.
B = bitmap[i].B;
1358 for (
unsigned int i = 0; i < npixels; i++) {
1359 if (bitmap[i].R < min.
R)
1360 min.
R = bitmap[i].R;
1361 if (bitmap[i].R > max.
R)
1362 max.
R = bitmap[i].R;
1364 if (bitmap[i].G < min.
G)
1365 min.
G = bitmap[i].G;
1366 if (bitmap[i].G > max.
G)
1367 max.
G = bitmap[i].G;
1369 if (bitmap[i].B < min.
B)
1370 min.
B = bitmap[i].B;
1371 if (bitmap[i].B > max.
B)
1372 max.
B = bitmap[i].B;
1398 template <
class Type>
1403 "values of an empty image"));
1405 Type min = bitmap[0], max = bitmap[0];
1407 for (
unsigned int i = 0; i < height; i++) {
1408 for (
unsigned int j = 0; j < width; j++) {
1409 if (row[i][j] < min) {
1414 if (row[i][j] > max) {
1421 if (minLoc !=
nullptr)
1424 if (maxLoc !=
nullptr)
1427 if (minVal !=
nullptr)
1430 if (maxVal !=
nullptr)
1454 for (
unsigned int i = 0; i < npixels; i++)
1474 for (
unsigned int i = 0; i < npixels; i++) {
1475 if (bitmap[i] != I.
bitmap[i]) {
1535 int itl = (int)topLeft.
get_i();
1536 int jtl = (int)topLeft.
get_j();
1538 int dest_ibegin = 0;
1539 int dest_jbegin = 0;
1542 int dest_w = (int)this->getWidth();
1543 int dest_h = (int)this->getHeight();
1549 if (itl >= dest_h || jtl >= dest_w)
1562 if (src_w - src_jbegin > dest_w - dest_jbegin)
1563 wsize = dest_w - dest_jbegin;
1565 wsize = src_w - src_jbegin;
1567 if (src_h - src_ibegin > dest_h - dest_ibegin)
1568 hsize = dest_h - dest_ibegin;
1570 hsize = src_h - src_ibegin;
1572 for (
int i = 0; i < hsize; i++) {
1573 Type *srcBitmap = src.
bitmap + ((src_ibegin + i) * src_w + src_jbegin);
1574 Type *destBitmap = this->bitmap + ((dest_ibegin + i) * dest_w + dest_jbegin);
1576 memcpy(
static_cast<void *
>(destBitmap),
static_cast<void *
>(srcBitmap), (
size_t)wsize *
sizeof(Type));
1612 unsigned int h = height / 2;
1613 unsigned int w = width / 2;
1615 for (
unsigned int i = 0; i < h; i++)
1616 for (
unsigned int j = 0; j < w; j++)
1617 res[i][j] = (*
this)[i << 1][j << 1];
1637 template <
class Type>
1640 if (v_scale == 1 && h_scale == 1) {
1644 unsigned int h = height / v_scale;
1645 unsigned int w = width / h_scale;
1647 for (
unsigned int i = 0; i < h; i++)
1648 for (
unsigned int j = 0; j < w; j++)
1649 sampled[i][j] = (*
this)[i * v_scale][j * h_scale];
1676 unsigned int h = height / 4;
1677 unsigned int w = width / 4;
1679 for (
unsigned int i = 0; i < h; i++)
1680 for (
unsigned int j = 0; j < w; j++)
1681 res[i][j] = (*
this)[i << 2][j << 2];
1723 for (
int i = 0; i < h; i++)
1724 for (
int j = 0; j < w; j++)
1725 res[i][j] = (*
this)[i >> 1][j >> 1];
1736 for (
int i = 0; i < h; i += 2)
1737 for (
int j = 1; j < w - 1; j += 2)
1738 res[i][j] = (Type)(0.5 * ((*this)[i >> 1][j >> 1] + (*this)[i >> 1][(j >> 1) + 1]));
1741 for (
int i = 1; i < h - 1; i += 2)
1742 for (
int j = 0; j < w; j += 2)
1743 res[i][j] = (Type)(0.5 * ((*this)[i >> 1][j >> 1] + (*this)[(i >> 1) + 1][j >> 1]));
1746 for (
int i = 1; i < h - 1; i += 2)
1747 for (
int j = 1; j < w - 1; j += 2)
1748 res[i][j] = (Type)(0.25 * ((*this)[i >> 1][j >> 1] + (*this)[i >> 1][(j >> 1) + 1] +
1749 (*
this)[(i >> 1) + 1][j >> 1] + (*
this)[(i >> 1) + 1][(j >> 1) + 1]));
1766 if (i >= height || j >= width) {
1791 if (i < 0 || j < 0 || i + 1 > height || j + 1 > width) {
1794 if (height * width == 0) {
1798 unsigned int iround =
static_cast<unsigned int>(floor(i));
1799 unsigned int jround =
static_cast<unsigned int>(floor(j));
1801 double rratio = i -
static_cast<double>(iround);
1802 double cratio = j -
static_cast<double>(jround);
1804 double rfrac = 1.0 - rratio;
1805 double cfrac = 1.0 - cratio;
1807 unsigned int iround_1 = std::min<unsigned int>(height - 1, iround + 1);
1808 unsigned int jround_1 = std::min<unsigned int>(width - 1, jround + 1);
1811 (
static_cast<double>(row[iround][jround]) * rfrac +
static_cast<double>(row[iround_1][jround]) * rratio) * cfrac +
1812 (
static_cast<double>(row[iround][jround_1]) * rfrac +
static_cast<double>(row[iround_1][jround_1]) * rratio) *
1823 if (i < 0 || j < 0 || i + 1 > height || j + 1 > width) {
1826 if (height * width == 0) {
1830 unsigned int iround =
static_cast<unsigned int>(floor(i));
1831 unsigned int jround =
static_cast<unsigned int>(floor(j));
1833 double rratio = i -
static_cast<double>(iround);
1834 double cratio = j -
static_cast<double>(jround);
1836 double rfrac = 1.0 - rratio;
1837 double cfrac = 1.0 - cratio;
1839 unsigned int iround_1 = std::min<unsigned int>(height - 1, iround + 1);
1840 unsigned int jround_1 = std::min<unsigned int>(width - 1, jround + 1);
1842 return (row[iround][jround] * rfrac + row[iround_1][jround] * rratio) * cfrac +
1843 (row[iround][jround_1] * rfrac + row[iround_1][jround_1] * rratio) * cratio;
1851 if (i < 0 || j < 0 || i + 1 > height || j + 1 > width) {
1854 if (height * width == 0) {
1859 #if (defined(VISP_LITTLE_ENDIAN) || defined(VISP_BIG_ENDIAN)) && !(defined(__alpha__) || defined(_M_ALPHA))
1861 const int32_t precision = 1 << 16;
1862 int64_t y =
static_cast<int64_t
>(i * precision);
1863 int64_t x =
static_cast<int64_t
>(j * precision);
1865 int64_t iround = y & (~0xFFFF);
1866 int64_t jround = x & (~0xFFFF);
1868 int64_t rratio = y - iround;
1869 int64_t cratio = x - jround;
1871 int64_t rfrac = precision - rratio;
1872 int64_t cfrac = precision - cratio;
1874 int64_t x_ = x >> 16;
1875 int64_t y_ = y >> 16;
1877 if (y_ + 1 < height && x_ + 1 < width) {
1881 return static_cast<unsigned char>((((up & 0x00FF) * rfrac + (down & 0x00FF) * rratio) * cfrac +
1882 ((up >> 8) * rfrac + (down >> 8) * rratio) * cratio) >>
1885 else if (y_ + 1 < height) {
1886 return static_cast<unsigned char>(((row[y_][x_] * rfrac + row[y_ + 1][x_] * rratio)) >> 16);
1888 else if (x_ + 1 < width) {
1890 return static_cast<unsigned char>(((up & 0x00FF) * cfrac + (up >> 8) * cratio) >> 16);
1896 unsigned int iround =
static_cast<unsigned int>(floor(i));
1897 unsigned int jround =
static_cast<unsigned int>(floor(j));
1899 if (iround >= height || jround >= width) {
1904 double rratio = i -
static_cast<double>(iround);
1905 double cratio = j -
static_cast<double>(jround);
1907 double rfrac = 1.0 - rratio;
1908 double cfrac = 1.0 - cratio;
1910 unsigned int iround_1 = std::min<unsigned int>(height - 1, iround + 1);
1911 unsigned int jround_1 = std::min<unsigned int>(width - 1, jround + 1);
1914 (
static_cast<double>(row[iround][jround]) * rfrac +
static_cast<double>(row[iround_1][jround]) * rratio) * cfrac +
1915 (
static_cast<double>(row[iround][jround_1]) * rfrac +
static_cast<double>(row[iround_1][jround_1]) * rratio) *
1926 if (i < 0 || j < 0 || i + 1 > height || j + 1 > width) {
1929 if (height * width == 0) {
1933 unsigned int iround =
static_cast<unsigned int>(floor(i));
1934 unsigned int jround =
static_cast<unsigned int>(floor(j));
1936 double rratio = i -
static_cast<double>(iround);
1937 double cratio = j -
static_cast<double>(jround);
1939 double rfrac = 1.0 - rratio;
1940 double cfrac = 1.0 - cratio;
1942 unsigned int iround_1 = std::min<unsigned int>(height - 1, iround + 1);
1943 unsigned int jround_1 = std::min<unsigned int>(width - 1, jround + 1);
1946 (
static_cast<double>(row[iround][jround].R) * rfrac +
static_cast<double>(row[iround_1][jround].R) * rratio) *
1948 (
static_cast<double>(row[iround][jround_1].R) * rfrac +
static_cast<double>(row[iround_1][jround_1].R) * rratio) *
1951 (
static_cast<double>(row[iround][jround].G) * rfrac +
static_cast<double>(row[iround_1][jround].G) * rratio) *
1953 (
static_cast<double>(row[iround][jround_1].G) * rfrac +
static_cast<double>(row[iround_1][jround_1].G) * rratio) *
1956 (
static_cast<double>(row[iround][jround].B) * rfrac +
static_cast<double>(row[iround_1][jround].B) * rratio) *
1958 (
static_cast<double>(row[iround][jround_1].B) * rfrac +
static_cast<double>(row[iround_1][jround_1].B) * rratio) *
1970 if (i < 0 || j < 0 || i + 1 > height || j + 1 > width) {
1973 if (height * width == 0) {
1977 unsigned int iround =
static_cast<unsigned int>(floor(i));
1978 unsigned int jround =
static_cast<unsigned int>(floor(j));
1980 double rratio = i -
static_cast<double>(iround);
1981 double cratio = j -
static_cast<double>(jround);
1983 double rfrac = 1.0 - rratio;
1984 double cfrac = 1.0 - cratio;
1986 unsigned int iround_1 = std::min<unsigned int>(height - 1, iround + 1);
1987 unsigned int jround_1 = std::min<unsigned int>(width - 1, jround + 1);
1990 (
static_cast<double>(row[iround][jround].R) * rfrac +
static_cast<double>(row[iround_1][jround].R) * rratio) *
1992 (
static_cast<double>(row[iround][jround_1].R) * rfrac +
static_cast<double>(row[iround_1][jround_1].R) * rratio) *
1995 (
static_cast<double>(row[iround][jround].G) * rfrac +
static_cast<double>(row[iround_1][jround].G) * rratio) *
1997 (
static_cast<double>(row[iround][jround_1].G) * rfrac +
static_cast<double>(row[iround_1][jround_1].G) * rratio) *
2000 (
static_cast<double>(row[iround][jround].B) * rfrac +
static_cast<double>(row[iround_1][jround].B) * rratio) *
2002 (
static_cast<double>(row[iround][jround_1].B) * rfrac +
static_cast<double>(row[iround_1][jround_1].B) * rratio) *
2005 return vpRGBf(
static_cast<float>(valueR),
static_cast<float>(valueG),
static_cast<float>(valueB));
2066 if ((height == 0) || (width == 0)) {
2067 if (nbValidPoints) {
2078 unsigned int nbPointsInMask = 0;
2079 unsigned int size = height * width;
2081 for (
unsigned int i = 0; i < size; ++i) {
2083 res +=
static_cast<double>(bitmap[i]);
2089 for (
unsigned int i = 0; i < size; ++i) {
2090 res +=
static_cast<double>(bitmap[i]);
2092 nbPointsInMask = size;
2094 if (nbValidPoints) {
2095 *nbValidPoints = nbPointsInMask;
2101 #ifndef DOXYGEN_SHOULD_SKIP_THIS
2115 if ((height == 0) || (width == 0)) {
2119 unsigned int nbPointsInMask = 0;
2120 unsigned int size = height * width;
2125 for (
unsigned int i = 0; i < size; ++i) {
2127 res +=
static_cast<double>(
bitmap[i].R) +
static_cast<double>(
bitmap[i].G) +
static_cast<double>(
bitmap[i].B);
2133 for (
unsigned int i = 0; i < height * width; ++i) {
2134 res +=
static_cast<double>(
bitmap[i].R) +
static_cast<double>(
bitmap[i].G) +
static_cast<double>(
bitmap[i].B);
2136 nbPointsInMask = size;
2138 if (nbValidPoints) {
2139 *nbValidPoints = nbPointsInMask;
2157 if ((height == 0) || (width == 0)) {
2161 unsigned int nbPointsInMask = 0;
2162 unsigned int size = height * width;
2167 for (
unsigned int i = 0; i < size; ++i) {
2169 res +=
static_cast<double>(bitmap[i].R) +
static_cast<double>(bitmap[i].G) +
static_cast<double>(bitmap[i].B);
2175 for (
unsigned int i = 0; i < height * width; ++i) {
2176 res +=
static_cast<double>(bitmap[i].R) +
static_cast<double>(bitmap[i].G) +
static_cast<double>(bitmap[i].B);
2178 nbPointsInMask = size;
2180 if (nbValidPoints) {
2181 *nbValidPoints = nbPointsInMask;
2221 C.
resize(this->getHeight(), this->getWidth());
2224 std::cout << me << std::endl;
2228 if ((this->getWidth() != B.
getWidth()) || (this->getHeight() != B.
getHeight())) {
2232 for (
unsigned int i = 0; i < this->getWidth() * this->getHeight(); i++) {
2256 std::cout << me << std::endl;
2279 std::cerr <<
"Not implemented !" << std::endl;
2295 unsigned char *ptrStart = (
unsigned char *)
bitmap;
2296 unsigned char *ptrEnd = ptrStart + size;
2297 unsigned char *ptrCurrent = ptrStart;
2299 bool use_single_thread = (nbThreads == 0 || nbThreads == 1);
2300 #if !defined(VISP_HAVE_THREADS)
2301 use_single_thread =
true;
2304 if (!use_single_thread &&
getSize() <= nbThreads) {
2305 use_single_thread =
true;
2308 if (use_single_thread) {
2311 while (ptrCurrent != ptrEnd) {
2312 *ptrCurrent = lut[*ptrCurrent];
2317 #if defined(VISP_HAVE_THREADS)
2319 std::vector<std::thread *> threadpool;
2320 std::vector<vpImageLut_Param_t *> imageLutParams;
2322 unsigned int image_size =
getSize();
2323 unsigned int step = image_size / nbThreads;
2324 unsigned int last_step = image_size - step * (nbThreads - 1);
2326 for (
unsigned int index = 0; index < nbThreads; index++) {
2327 unsigned int start_index = index * step;
2328 unsigned int end_index = (index + 1) * step;
2330 if (index == nbThreads - 1) {
2331 end_index = start_index + last_step;
2334 vpImageLut_Param_t *imageLut_param =
new vpImageLut_Param_t(start_index, end_index,
bitmap);
2335 memcpy(imageLut_param->m_lut, lut, 256 *
sizeof(
unsigned char));
2337 imageLutParams.push_back(imageLut_param);
2340 std::thread *imageLut_thread =
new std::thread(&performLutThread, imageLut_param);
2341 threadpool.push_back(imageLut_thread);
2344 for (
size_t cpt = 0; cpt < threadpool.size(); cpt++) {
2346 threadpool[cpt]->join();
2350 for (
size_t cpt = 0; cpt < threadpool.size(); cpt++) {
2351 delete threadpool[cpt];
2354 for (
size_t cpt = 0; cpt < imageLutParams.size(); cpt++) {
2355 delete imageLutParams[cpt];
2374 unsigned char *ptrStart = (
unsigned char *)
bitmap;
2375 unsigned char *ptrEnd = ptrStart + size * 4;
2376 unsigned char *ptrCurrent = ptrStart;
2378 bool use_single_thread = (nbThreads == 0 || nbThreads == 1);
2379 #if !defined(VISP_HAVE_THREADS)
2380 use_single_thread =
true;
2383 if (!use_single_thread &&
getSize() <= nbThreads) {
2384 use_single_thread =
true;
2387 if (use_single_thread) {
2389 while (ptrCurrent != ptrEnd) {
2390 *ptrCurrent = lut[*ptrCurrent].R;
2393 *ptrCurrent = lut[*ptrCurrent].G;
2396 *ptrCurrent = lut[*ptrCurrent].B;
2399 *ptrCurrent = lut[*ptrCurrent].A;
2404 #if defined(VISP_HAVE_THREADS)
2406 std::vector<std::thread *> threadpool;
2407 std::vector<vpImageLutRGBa_Param_t *> imageLutParams;
2409 unsigned int image_size =
getSize();
2410 unsigned int step = image_size / nbThreads;
2411 unsigned int last_step = image_size - step * (nbThreads - 1);
2413 for (
unsigned int index = 0; index < nbThreads; index++) {
2414 unsigned int start_index = index * step;
2415 unsigned int end_index = (index + 1) * step;
2417 if (index == nbThreads - 1) {
2418 end_index = start_index + last_step;
2421 vpImageLutRGBa_Param_t *imageLut_param =
new vpImageLutRGBa_Param_t(start_index, end_index, (
unsigned char *)
bitmap);
2422 memcpy(
static_cast<void *
>(imageLut_param->m_lut), lut, 256 *
sizeof(
vpRGBa));
2424 imageLutParams.push_back(imageLut_param);
2427 std::thread *imageLut_thread =
new std::thread(&performLutRGBaThread, imageLut_param);
2428 threadpool.push_back(imageLut_thread);
2431 for (
size_t cpt = 0; cpt < threadpool.size(); cpt++) {
2433 threadpool[cpt]->join();
2437 for (
size_t cpt = 0; cpt < threadpool.size(); cpt++) {
2438 delete threadpool[cpt];
2441 for (
size_t cpt = 0; cpt < imageLutParams.size(); cpt++) {
2442 delete imageLutParams[cpt];
2453 swap(first.npixels, second.npixels);
2454 swap(first.width, second.width);
2455 swap(first.height, second.height);
2456 swap(first.row, second.row);
friend std::ostream & operator<<(std::ostream &s, const vpArray2D< Type > &A)
Class that defines generic functionalities for display.
error that can be emitted by ViSP classes.
@ memoryAllocationError
Memory allocation error.
@ divideByZeroError
Division by zero.
@ 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 ...
void set_ij(double ii, double jj)
Definition of the vpImage class member functions.
Type operator()(const vpImagePoint &ip) const
void destroy()
Destructor : Memory de-allocation.
void subsample(unsigned int v_scale, unsigned int h_scale, vpImage< Type > &sampled) const
void halfSizeImage(vpImage< Type > &res) const
vpImage< Type > & operator=(vpImage< Type > other)
Copy operator.
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 quarterSizeImage(vpImage< Type > &res) const
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...
void init(unsigned int height, unsigned int width)
Set the size of the image.
Type * operator[](unsigned int i)
operator[] allows operation like I[i] = x.
void resize(unsigned int h, unsigned int w, const Type &val)
resize the image : Image initialization
unsigned int getWidth() const
friend std::ostream & operator<<(std::ostream &s, const vpImage< unsigned char > &I)
void resize(unsigned int h, unsigned int w)
resize the image : Image initialization
unsigned int getNumberOfPixel() const
Type getValue(double i, double j) const
void doubleSizeImage(vpImage< Type > &res)
vpImage(unsigned int height, unsigned int width, Type value)
constructor set the size of the image and init all the pixel
void performLut(const Type(&lut)[256], unsigned int nbThreads=1)
const Type * operator[](int i) const
friend std::ostream & operator<<(std::ostream &s, const vpImage< float > &I)
bool operator==(const vpImage< Type > &I) const
void insert(const vpImage< Type > &src, const vpImagePoint &topLeft)
void sub(const vpImage< Type > &A, const vpImage< Type > &B, vpImage< Type > &C) const
Type getValue(unsigned int i, unsigned int j) const
double getValue(double i, double j) const
vpImage< Type > operator-(const vpImage< Type > &B) const
void init(unsigned int height, unsigned int width, Type value)
Set the size of the image.
unsigned int getSize() const
friend void swap(vpImage< Type > &first, vpImage< Type > &second)
unsigned int getCols() const
Type * bitmap
points toward the bitmap
const Type * operator[](unsigned int i) const
operator[] allows operation like x = I[i]
double getStdev(const vpImage< bool > *p_mask=nullptr, unsigned int *nbValidPoints=nullptr) const
Return the standard deviation of the bitmap.
Type getValue(const vpImagePoint &ip) const
void sub(const vpImage< Type > &B, vpImage< Type > &C) const
vpImage(Type *const array, unsigned int height, unsigned int width, bool copyData=false)
constructor from an image stored as a continuous array in memory
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
double getStdev(const double &mean, 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.
virtual ~vpImage()
destructor
unsigned int getHeight() const
unsigned int getRows() const
friend std::ostream & operator<<(std::ostream &s, const vpImage< double > &I)
void getMinMaxValue(Type &min, Type &max, bool onlyFiniteVal=true) const
Look for the minimum and the maximum value within the bitmap.
vpImage< Type > & operator=(const Type &v)
= operator : Set all the element of the bitmap to a given value v.
friend std::ostream & operator<<(std::ostream &s, const vpImage< char > &I)
void operator()(const vpImagePoint &ip, const Type &v)
Type operator()(unsigned int i, unsigned int j) const
bool operator!=(const vpImage< Type > &I) const
double getMeanValue(const vpImage< bool > *p_mask=nullptr, unsigned int *nbValidPoints=nullptr) const
Return the mean value of the bitmap.
void init(unsigned int h, unsigned int w, Type value)
vpImage(const vpImage< Type > &)
copy constructor
vpImage(unsigned int height, unsigned int width)
constructor set the size of the image
void operator()(unsigned int i, unsigned int j, const Type &v)
static int round(double x)
static bool isFinite(double value)
VISP_EXPORT uint16_t reinterpret_cast_uchar_to_uint16_LE(unsigned char *const ptr)