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 #include <visp3/core/vpRGBf.h>
56 #if defined(VISP_HAVE_PTHREAD) || (defined(_WIN32) && !defined(WINRT_8_0))
57 #include <visp3/core/vpThread.h>
67 #if defined(_MSC_VER) && (_MSC_VER < 1700)
68 typedef long long int64_t;
69 typedef unsigned short uint16_t;
127 template <
class Type>
class vpImage;
139 template <
class Type>
class vpImage
151 #if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
156 vpImage(
unsigned int height,
unsigned int width);
158 vpImage(
unsigned int height,
unsigned int width, Type value);
160 vpImage(Type *
const array,
unsigned int height,
unsigned int width,
bool copyData =
false);
180 inline unsigned int getCols()
const {
return width; }
189 inline unsigned int getHeight()
const {
return height; }
219 inline unsigned int getRows()
const {
return height; }
228 inline unsigned int getSize()
const {
return width * height; }
231 Type
getValue(
unsigned int i,
unsigned int j)
const;
247 inline unsigned int getWidth()
const {
return width; }
253 void init(
unsigned int height,
unsigned int width);
255 void init(
unsigned int height,
unsigned int width, Type value);
257 void init(Type *
const array,
unsigned int height,
unsigned int width,
bool copyData =
false);
268 inline const Type *
operator[](
unsigned int i)
const {
return row[i]; }
269 inline const Type *
operator[](
int i)
const {
return row[i]; }
277 inline Type
operator()(
unsigned int i,
unsigned int j)
const {
return bitmap[i * width + j]; }
283 inline void operator()(
unsigned int i,
unsigned int j,
const Type &v) {
bitmap[i * width + j] = v; }
297 unsigned int i = (
unsigned int)ip.
get_i();
298 unsigned int j = (
unsigned int)ip.
get_j();
300 return bitmap[i * width + j];
313 unsigned int i = (
unsigned int)ip.
get_i();
314 unsigned int j = (
unsigned int)ip.
get_j();
316 bitmap[i * width + j] = v;
327 friend std::ostream &operator<< <>(std::ostream &s,
const vpImage<Type> &I);
334 void performLut(
const Type (&lut)[256],
unsigned int nbThreads = 1);
340 void resize(
unsigned int h,
unsigned int w);
342 void resize(
unsigned int h,
unsigned int w,
const Type &val);
353 unsigned int npixels;
366 for (
unsigned int i = 0; i < I.
getHeight(); i++) {
367 for (
unsigned int j = 0; j < I.
getWidth() - 1; j++) {
389 std::ios_base::fmtflags original_flags = s.flags();
391 for (
unsigned int i = 0; i < I.
getHeight(); i++) {
392 for (
unsigned int j = 0; j < I.
getWidth() - 1; j++) {
393 s << std::setw(3) << static_cast<unsigned>(I[i][j]) <<
" ";
397 s << std::setw(3) << static_cast<unsigned>(I[i][I.
getWidth() - 1]);
405 s.flags(original_flags);
415 std::ios_base::fmtflags original_flags = s.flags();
417 for (
unsigned int i = 0; i < I.
getHeight(); i++) {
418 for (
unsigned int j = 0; j < I.
getWidth() - 1; j++) {
419 s << std::setw(4) << static_cast<int>(I[i][j]) <<
" ";
423 s << std::setw(4) << static_cast<int>(I[i][I.
getWidth() - 1]);
431 s.flags(original_flags);
441 std::ios_base::fmtflags original_flags = s.flags();
444 for (
unsigned int i = 0; i < I.
getHeight(); i++) {
445 for (
unsigned int j = 0; j < I.
getWidth() - 1; j++) {
458 s.flags(original_flags);
468 std::ios_base::fmtflags original_flags = s.flags();
471 for (
unsigned int i = 0; i < I.
getHeight(); i++) {
472 for (
unsigned int j = 0; j < I.
getWidth() - 1; j++) {
485 s.flags(original_flags);
489 #if defined(VISP_HAVE_PTHREAD) || (defined(_WIN32) && !defined(WINRT_8_0))
492 struct ImageLut_Param_t {
493 unsigned int m_start_index;
494 unsigned int m_end_index;
496 unsigned char m_lut[256];
497 unsigned char *m_bitmap;
499 ImageLut_Param_t() : m_start_index(0), m_end_index(0), m_lut(), m_bitmap(NULL) {}
501 ImageLut_Param_t(
unsigned int start_index,
unsigned int end_index,
unsigned char *bitmap)
502 : m_start_index(start_index), m_end_index(end_index), m_lut(), m_bitmap(bitmap)
509 ImageLut_Param_t *imageLut_param =
static_cast<ImageLut_Param_t *
>(args);
510 unsigned int start_index = imageLut_param->m_start_index;
511 unsigned int end_index = imageLut_param->m_end_index;
513 unsigned char *bitmap = imageLut_param->m_bitmap;
515 unsigned char *ptrStart = bitmap + start_index;
516 unsigned char *ptrEnd = bitmap + end_index;
517 unsigned char *ptrCurrent = ptrStart;
524 if (end_index - start_index >= 8) {
526 for (; ptrCurrent <= ptrEnd - 8;) {
527 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent];
530 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent];
533 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent];
536 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent];
539 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent];
542 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent];
545 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent];
548 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent];
553 for (; ptrCurrent != ptrEnd; ++ptrCurrent) {
554 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent];
560 struct ImageLutRGBa_Param_t {
561 unsigned int m_start_index;
562 unsigned int m_end_index;
565 unsigned char *m_bitmap;
567 ImageLutRGBa_Param_t() : m_start_index(0), m_end_index(0), m_lut(), m_bitmap(NULL) {}
569 ImageLutRGBa_Param_t(
unsigned int start_index,
unsigned int end_index,
unsigned char *bitmap)
570 : m_start_index(start_index), m_end_index(end_index), m_lut(), m_bitmap(bitmap)
577 ImageLutRGBa_Param_t *imageLut_param =
static_cast<ImageLutRGBa_Param_t *
>(args);
578 unsigned int start_index = imageLut_param->m_start_index;
579 unsigned int end_index = imageLut_param->m_end_index;
581 unsigned char *bitmap = imageLut_param->m_bitmap;
583 unsigned char *ptrStart = bitmap + start_index * 4;
584 unsigned char *ptrEnd = bitmap + end_index * 4;
585 unsigned char *ptrCurrent = ptrStart;
587 if (end_index - start_index >= 4 * 2) {
589 for (; ptrCurrent <= ptrEnd - 4 * 2;) {
590 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].R;
592 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].G;
594 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].B;
596 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].A;
599 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].R;
601 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].G;
603 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].B;
605 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].A;
610 while (ptrCurrent != ptrEnd) {
611 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].R;
614 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].G;
617 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].B;
620 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].A;
638 std::fill(bitmap, bitmap + npixels, value);
646 if (h != this->height) {
654 if ((h != this->height) || (w != this->width)) {
655 if (bitmap != NULL) {
667 npixels = width * height;
669 if (bitmap == NULL) {
670 bitmap =
new Type[npixels];
674 if (bitmap == NULL) {
679 row =
new Type *[height];
684 for (
unsigned int i = 0; i < height; i++)
685 row[i] = bitmap + i * width;
691 template <
class Type>
void vpImage<Type>::init(Type *
const array,
unsigned int h,
unsigned int w,
bool copyData)
693 if (h != this->height) {
701 if ((copyData && ((h != this->height) || (w != this->width))) || !copyData) {
702 if (bitmap != NULL) {
710 hasOwnership = copyData;
714 npixels = width * height;
718 bitmap =
new Type[npixels];
720 if (bitmap == NULL) {
725 memcpy(
static_cast<void *
>(bitmap),
static_cast<void *
>(array), (
size_t)(npixels *
sizeof(Type)));
732 row =
new Type *[height];
737 for (
unsigned int i = 0; i < height; i++) {
738 row[i] = bitmap + i * width;
745 template <
class Type>
747 : bitmap(NULL), display(NULL), npixels(0), width(0), height(0), row(NULL), hasOwnership(true)
755 template <
class Type>
757 : bitmap(NULL), display(NULL), npixels(0), width(0), height(0), row(NULL), hasOwnership(true)
765 template <
class Type>
767 : bitmap(NULL), display(NULL), npixels(0), width(0), height(0), row(NULL), hasOwnership(true)
769 init(array, h, w, copyData);
775 template <
class Type>
833 if (bitmap != NULL) {
861 template <
class Type>
863 : bitmap(NULL), display(NULL), npixels(0), width(0), height(0), row(NULL), hasOwnership(true)
866 memcpy(
static_cast<void *
>(
bitmap),
static_cast<void *
>(I.
bitmap), I.npixels *
sizeof(Type));
869 #if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
873 template <
class Type>
875 : bitmap(I.bitmap), display(I.display), npixels(I.npixels), width(I.width), height(I.height), row(I.row),
876 hasOwnership(I.hasOwnership)
884 I.hasOwnership =
false;
900 for (
unsigned int i = 0; i < npixels; i++) {
923 for (
unsigned int i = 0; i < npixels; i++) {
928 for (
unsigned int i = 0; i < npixels; i++) {
950 for (
unsigned int i = 0; i < npixels; i++) {
955 for (
unsigned int i = 0; i < npixels; i++) {
968 if ((height == 0) || (width == 0))
971 return getSum() / (height * width);
986 for (
unsigned int i = 0; i < npixels; i++) {
1008 if (onlyFiniteVal) {
1009 for (
unsigned int i = 0; i < npixels; i++)
1013 for (
unsigned int i = 0; i < npixels; i++)
1033 if (onlyFiniteVal) {
1034 for (
unsigned int i = 0; i < npixels; i++)
1038 for (
unsigned int i = 0; i < npixels; i++)
1060 min = max = bitmap[0];
1061 for (
unsigned int i = 0; i < npixels; i++) {
1062 if (bitmap[i] < min)
1064 if (bitmap[i] > max)
1067 (void)onlyFiniteVal;
1087 if (onlyFiniteVal) {
1088 for (
unsigned int i = 0; i < npixels; i++) {
1097 for (
unsigned int i = 0; i < npixels; i++) {
1123 if (onlyFiniteVal) {
1124 for (
unsigned int i = 0; i < npixels; i++) {
1133 for (
unsigned int i = 0; i < npixels; i++) {
1157 min = max = bitmap[0];
1158 if (onlyFiniteVal) {
1159 for (
unsigned int i = 0; i < npixels; i++) {
1161 if (bitmap[i].R < min.
R)
1162 min.
R = bitmap[i].R;
1163 if (bitmap[i].R > max.
R)
1164 max.
R = bitmap[i].R;
1167 if (bitmap[i].G < min.
G)
1168 min.
G = bitmap[i].G;
1169 if (bitmap[i].G > max.
G)
1170 max.
G = bitmap[i].G;
1173 if (bitmap[i].B < min.
B)
1174 min.
B = bitmap[i].B;
1175 if (bitmap[i].B > max.
B)
1176 max.
B = bitmap[i].B;
1180 for (
unsigned int i = 0; i < npixels; i++) {
1181 if (bitmap[i].R < min.
R)
1182 min.
R = bitmap[i].R;
1183 if (bitmap[i].R > max.
R)
1184 max.
R = bitmap[i].R;
1186 if (bitmap[i].G < min.
G)
1187 min.
G = bitmap[i].G;
1188 if (bitmap[i].G > max.
G)
1189 max.
G = bitmap[i].G;
1191 if (bitmap[i].B < min.
B)
1192 min.
B = bitmap[i].B;
1193 if (bitmap[i].B > max.
B)
1194 max.
B = bitmap[i].B;
1220 template <
class Type>
1225 "values of an empty image"));
1227 Type min = bitmap[0], max = bitmap[0];
1229 for (
unsigned int i = 0; i < height; i++) {
1230 for (
unsigned int j = 0; j < width; j++) {
1231 if (row[i][j] < min) {
1236 if (row[i][j] > max) {
1280 for (
unsigned int i = 0; i < npixels; i++)
1300 for (
unsigned int i = 0; i < npixels; i++) {
1301 if (bitmap[i] != I.
bitmap[i]) {
1361 int itl = (int)topLeft.
get_i();
1362 int jtl = (int)topLeft.
get_j();
1364 int dest_ibegin = 0;
1365 int dest_jbegin = 0;
1368 int dest_w = (int)this->getWidth();
1369 int dest_h = (int)this->getHeight();
1375 if (itl >= dest_h || jtl >= dest_w)
1388 if (src_w - src_jbegin > dest_w - dest_jbegin)
1389 wsize = dest_w - dest_jbegin;
1391 wsize = src_w - src_jbegin;
1393 if (src_h - src_ibegin > dest_h - dest_ibegin)
1394 hsize = dest_h - dest_ibegin;
1396 hsize = src_h - src_ibegin;
1398 for (
int i = 0; i < hsize; i++) {
1399 Type *srcBitmap = src.
bitmap + ((src_ibegin + i) * src_w + src_jbegin);
1400 Type *destBitmap = this->bitmap + ((dest_ibegin + i) * dest_w + dest_jbegin);
1402 memcpy(
static_cast<void *
>(destBitmap),
static_cast<void *
>(srcBitmap), (
size_t)wsize *
sizeof(Type));
1438 unsigned int h = height / 2;
1439 unsigned int w = width / 2;
1441 for (
unsigned int i = 0; i < h; i++)
1442 for (
unsigned int j = 0; j < w; j++)
1443 res[i][j] = (*
this)[i << 1][j << 1];
1463 template <
class Type>
1466 if (v_scale == 1 && h_scale == 1) {
1470 unsigned int h = height / v_scale;
1471 unsigned int w = width / h_scale;
1473 for (
unsigned int i = 0; i < h; i++)
1474 for (
unsigned int j = 0; j < w; j++)
1475 sampled[i][j] = (*
this)[i * v_scale][j * h_scale];
1502 unsigned int h = height / 4;
1503 unsigned int w = width / 4;
1505 for (
unsigned int i = 0; i < h; i++)
1506 for (
unsigned int j = 0; j < w; j++)
1507 res[i][j] = (*
this)[i << 2][j << 2];
1549 for (
int i = 0; i < h; i++)
1550 for (
int j = 0; j < w; j++)
1551 res[i][j] = (*
this)[i >> 1][j >> 1];
1562 for (
int i = 0; i < h; i += 2)
1563 for (
int j = 1; j < w - 1; j += 2)
1564 res[i][j] = (Type)(0.5 * ((*this)[i >> 1][j >> 1] + (*this)[i >> 1][(j >> 1) + 1]));
1567 for (
int i = 1; i < h - 1; i += 2)
1568 for (
int j = 0; j < w; j += 2)
1569 res[i][j] = (Type)(0.5 * ((*this)[i >> 1][j >> 1] + (*this)[(i >> 1) + 1][j >> 1]));
1572 for (
int i = 1; i < h - 1; i += 2)
1573 for (
int j = 1; j < w - 1; j += 2)
1574 res[i][j] = (Type)(0.25 * ((*this)[i >> 1][j >> 1] + (*this)[i >> 1][(j >> 1) + 1] +
1575 (*
this)[(i >> 1) + 1][j >> 1] + (*
this)[(i >> 1) + 1][(j >> 1) + 1]));
1592 if (i >= height || j >= width) {
1617 if (i < 0 || j < 0 || i + 1 > height || j + 1 > width) {
1620 if (height * width == 0) {
1624 unsigned int iround =
static_cast<unsigned int>(floor(i));
1625 unsigned int jround =
static_cast<unsigned int>(floor(j));
1627 double rratio = i -
static_cast<double>(iround);
1628 double cratio = j -
static_cast<double>(jround);
1630 double rfrac = 1.0 - rratio;
1631 double cfrac = 1.0 - cratio;
1633 unsigned int iround_1 = (std::min)(height - 1, iround + 1);
1634 unsigned int jround_1 = (std::min)(width - 1, jround + 1);
1637 (
static_cast<double>(row[iround][jround]) * rfrac +
static_cast<double>(row[iround_1][jround]) * rratio) * cfrac +
1638 (
static_cast<double>(row[iround][jround_1]) * rfrac +
static_cast<double>(row[iround_1][jround_1]) * rratio) *
1649 if (i < 0 || j < 0 || i + 1 > height || j + 1 > width) {
1652 if (height * width == 0) {
1656 unsigned int iround =
static_cast<unsigned int>(floor(i));
1657 unsigned int jround =
static_cast<unsigned int>(floor(j));
1659 double rratio = i -
static_cast<double>(iround);
1660 double cratio = j -
static_cast<double>(jround);
1662 double rfrac = 1.0 - rratio;
1663 double cfrac = 1.0 - cratio;
1665 unsigned int iround_1 = (std::min)(height - 1, iround + 1);
1666 unsigned int jround_1 = (std::min)(width - 1, jround + 1);
1668 return (row[iround][jround] * rfrac + row[iround_1][jround] * rratio) * cfrac +
1669 (row[iround][jround_1] * rfrac + row[iround_1][jround_1] * rratio) * cratio;
1677 if (i < 0 || j < 0 || i + 1 > height || j + 1 > width) {
1680 if (height * width == 0) {
1685 #if (defined(VISP_LITTLE_ENDIAN) || defined(VISP_BIG_ENDIAN)) && !(defined(__alpha__) || defined(_M_ALPHA))
1687 const int32_t precision = 1 << 16;
1688 int64_t y =
static_cast<int64_t
>(i * precision);
1689 int64_t x =
static_cast<int64_t
>(j * precision);
1691 int64_t iround = y & (~0xFFFF);
1692 int64_t jround = x & (~0xFFFF);
1694 int64_t rratio = y - iround;
1695 int64_t cratio = x - jround;
1697 int64_t rfrac = precision - rratio;
1698 int64_t cfrac = precision - cratio;
1700 int64_t x_ = x >> 16;
1701 int64_t y_ = y >> 16;
1703 if (y_ + 1 < height && x_ + 1 < width) {
1707 return static_cast<unsigned char>((((up & 0x00FF) * rfrac + (down & 0x00FF) * rratio) * cfrac +
1708 ((up >> 8) * rfrac + (down >> 8) * rratio) * cratio) >>
1710 }
else if (y_ + 1 < height) {
1711 return static_cast<unsigned char>(((row[y_][x_] * rfrac + row[y_ + 1][x_] * rratio)) >> 16);
1712 }
else if (x_ + 1 < width) {
1714 return static_cast<unsigned char>(((up & 0x00FF) * cfrac + (up >> 8) * cratio) >> 16);
1719 unsigned int iround =
static_cast<unsigned int>(floor(i));
1720 unsigned int jround =
static_cast<unsigned int>(floor(j));
1722 if (iround >= height || jround >= width) {
1727 double rratio = i -
static_cast<double>(iround);
1728 double cratio = j -
static_cast<double>(jround);
1730 double rfrac = 1.0 - rratio;
1731 double cfrac = 1.0 - cratio;
1733 unsigned int iround_1 = (std::min)(height - 1, iround + 1);
1734 unsigned int jround_1 = (std::min)(width - 1, jround + 1);
1737 (
static_cast<double>(row[iround][jround]) * rfrac +
static_cast<double>(row[iround_1][jround]) * rratio) * cfrac +
1738 (
static_cast<double>(row[iround][jround_1]) * rfrac +
static_cast<double>(row[iround_1][jround_1]) * rratio) *
1749 if (i < 0 || j < 0 || i + 1 > height || j + 1 > width) {
1752 if (height * width == 0) {
1756 unsigned int iround =
static_cast<unsigned int>(floor(i));
1757 unsigned int jround =
static_cast<unsigned int>(floor(j));
1759 double rratio = i -
static_cast<double>(iround);
1760 double cratio = j -
static_cast<double>(jround);
1762 double rfrac = 1.0 - rratio;
1763 double cfrac = 1.0 - cratio;
1765 unsigned int iround_1 = (std::min)(height - 1, iround + 1);
1766 unsigned int jround_1 = (std::min)(width - 1, jround + 1);
1769 (
static_cast<double>(row[iround][jround].R) * rfrac +
static_cast<double>(row[iround_1][jround].R) * rratio) *
1771 (
static_cast<double>(row[iround][jround_1].R) * rfrac +
static_cast<double>(row[iround_1][jround_1].R) * rratio) *
1774 (
static_cast<double>(row[iround][jround].G) * rfrac +
static_cast<double>(row[iround_1][jround].G) * rratio) *
1776 (
static_cast<double>(row[iround][jround_1].G) * rfrac +
static_cast<double>(row[iround_1][jround_1].G) * rratio) *
1779 (
static_cast<double>(row[iround][jround].B) * rfrac +
static_cast<double>(row[iround_1][jround].B) * rratio) *
1781 (
static_cast<double>(row[iround][jround_1].B) * rfrac +
static_cast<double>(row[iround_1][jround_1].B) * rratio) *
1839 if ((height == 0) || (width == 0))
1843 for (
unsigned int i = 0; i < height * width; ++i) {
1844 res +=
static_cast<double>(bitmap[i]);
1854 if ((height == 0) || (width == 0))
1858 for (
unsigned int i = 0; i < height * width; ++i) {
1859 res +=
static_cast<double>(
bitmap[i].R) +
static_cast<double>(
bitmap[i].G) +
static_cast<double>(
bitmap[i].B);
1898 C.
resize(this->getHeight(), this->getWidth());
1900 std::cout << me << std::endl;
1904 if ((this->getWidth() != B.
getWidth()) || (this->getHeight() != B.
getHeight())) {
1908 for (
unsigned int i = 0; i < this->getWidth() * this->getHeight(); i++) {
1931 std::cout << me << std::endl;
1954 std::cerr <<
"Not implemented !" << std::endl;
1970 unsigned char *ptrStart = (
unsigned char *)
bitmap;
1971 unsigned char *ptrEnd = ptrStart + size;
1972 unsigned char *ptrCurrent = ptrStart;
1974 bool use_single_thread = (nbThreads == 0 || nbThreads == 1);
1975 #if !defined(VISP_HAVE_PTHREAD) && !defined(_WIN32)
1976 use_single_thread =
true;
1979 if (!use_single_thread &&
getSize() <= nbThreads) {
1980 use_single_thread =
true;
1983 if (use_single_thread) {
1986 while (ptrCurrent != ptrEnd) {
1987 *ptrCurrent = lut[*ptrCurrent];
1991 #if defined(VISP_HAVE_PTHREAD) || (defined(_WIN32) && !defined(WINRT_8_0))
1994 std::vector<vpThread *> threadpool;
1995 std::vector<ImageLut_Param_t *> imageLutParams;
1997 unsigned int image_size =
getSize();
1998 unsigned int step = image_size / nbThreads;
1999 unsigned int last_step = image_size - step * (nbThreads - 1);
2001 for (
unsigned int index = 0; index < nbThreads; index++) {
2002 unsigned int start_index = index * step;
2003 unsigned int end_index = (index + 1) * step;
2005 if (index == nbThreads - 1) {
2006 end_index = start_index + last_step;
2009 ImageLut_Param_t *imageLut_param =
new ImageLut_Param_t(start_index, end_index,
bitmap);
2010 memcpy(imageLut_param->m_lut, lut, 256 *
sizeof(
unsigned char));
2012 imageLutParams.push_back(imageLut_param);
2016 threadpool.push_back(imageLut_thread);
2019 for (
size_t cpt = 0; cpt < threadpool.size(); cpt++) {
2021 threadpool[cpt]->join();
2025 for (
size_t cpt = 0; cpt < threadpool.size(); cpt++) {
2026 delete threadpool[cpt];
2029 for (
size_t cpt = 0; cpt < imageLutParams.size(); cpt++) {
2030 delete imageLutParams[cpt];
2049 unsigned char *ptrStart = (
unsigned char *)
bitmap;
2050 unsigned char *ptrEnd = ptrStart + size * 4;
2051 unsigned char *ptrCurrent = ptrStart;
2053 bool use_single_thread = (nbThreads == 0 || nbThreads == 1);
2054 #if !defined(VISP_HAVE_PTHREAD) && !defined(_WIN32)
2055 use_single_thread =
true;
2058 if (!use_single_thread &&
getSize() <= nbThreads) {
2059 use_single_thread =
true;
2062 if (use_single_thread) {
2064 while (ptrCurrent != ptrEnd) {
2065 *ptrCurrent = lut[*ptrCurrent].R;
2068 *ptrCurrent = lut[*ptrCurrent].G;
2071 *ptrCurrent = lut[*ptrCurrent].B;
2074 *ptrCurrent = lut[*ptrCurrent].A;
2078 #if defined(VISP_HAVE_PTHREAD) || (defined(_WIN32) && !defined(WINRT_8_0))
2080 std::vector<vpThread *> threadpool;
2081 std::vector<ImageLutRGBa_Param_t *> imageLutParams;
2083 unsigned int image_size =
getSize();
2084 unsigned int step = image_size / nbThreads;
2085 unsigned int last_step = image_size - step * (nbThreads - 1);
2087 for (
unsigned int index = 0; index < nbThreads; index++) {
2088 unsigned int start_index = index * step;
2089 unsigned int end_index = (index + 1) * step;
2091 if (index == nbThreads - 1) {
2092 end_index = start_index + last_step;
2095 ImageLutRGBa_Param_t *imageLut_param =
new ImageLutRGBa_Param_t(start_index, end_index, (
unsigned char *)
bitmap);
2096 memcpy(
static_cast<void *
>(imageLut_param->m_lut), lut, 256 *
sizeof(
vpRGBa));
2098 imageLutParams.push_back(imageLut_param);
2102 threadpool.push_back(imageLut_thread);
2105 for (
size_t cpt = 0; cpt < threadpool.size(); cpt++) {
2107 threadpool[cpt]->join();
2111 for (
size_t cpt = 0; cpt < threadpool.size(); cpt++) {
2112 delete threadpool[cpt];
2115 for (
size_t cpt = 0; cpt < imageLutParams.size(); cpt++) {
2116 delete imageLutParams[cpt];
2127 swap(first.npixels, second.npixels);
2128 swap(first.width, second.width);
2129 swap(first.height, second.height);
2130 swap(first.row, second.row);
friend std::ostream & operator<<(std::ostream &s, const vpArray2D< Type > &A)
Class that defines generic functionnalities for display.
error that can be emited by ViSP classes.
@ memoryAllocationError
Memory allocation error.
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.
bool operator==(const vpImage< Type > &I)
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.
Type getMeanValue() const
Return the mean value of the bitmap.
Type getMinValue(bool onlyFiniteVal=true) const
Return the minimum value within the bitmap.
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...
void quarterSizeImage(vpImage< Type > &res) const
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)
void sub(const vpImage< Type > &B, vpImage< Type > &C)
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)
vpImage< Type > operator-(const vpImage< Type > &B)
void insert(const vpImage< Type > &src, const vpImagePoint &topLeft)
Type getValue(unsigned int i, unsigned int j) 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]
void sub(const vpImage< Type > &A, const vpImage< Type > &B, vpImage< Type > &C)
Type getValue(const vpImagePoint &ip) const
bool operator!=(const vpImage< Type > &I)
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
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
vpImage(vpImage< Type > &&)
move constructor
void init(unsigned int h, unsigned int w, Type value)
double getValue(double i, double j) const
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)