27 #include <mrpt/otherlibs/do_opencv_includes.h> 30 #include <mexplus/mxarray.h> 36 #if MRPT_HAS_WXWIDGETS 65 #define IMAGE_ALLOC_PERFLOG 0 67 #if IMAGE_ALLOC_PERFLOG 77 :
img(nullptr), m_imgIsReadOnly(false), m_imgIsExternalStorage(false)
87 :
img(nullptr), m_imgIsReadOnly(false), m_imgIsExternalStorage(false)
100 :
img(nullptr), m_imgIsReadOnly(false), m_imgIsExternalStorage(false)
113 if (
this == &o)
return *
this;
123 "Source image in = operator has nullptr IplImage*")
124 img = cvCloneImage((IplImage*)o.
img);
161 "Error loading externally-stored image from: %s",
176 if (
this == &o)
return;
208 :
img(nullptr), m_imgIsReadOnly(false), m_imgIsExternalStorage(false)
216 img = cvCloneImage((IplImage*)iplImage);
240 IplImage* ipl =
static_cast<IplImage*
>(
img);
241 if (static_cast<unsigned int>(ipl->width) ==
width &&
242 static_cast<unsigned int>(ipl->height) ==
height &&
243 ipl->nChannels == nChannels &&
244 ipl->origin == (originTopLeft ? 0 : 1))
254 #if IMAGE_ALLOC_PERFLOG 256 alloc_tims.
enter(sLog.c_str());
259 img = cvCreateImage(cvSize(
width,
height), IPL_DEPTH_8U, nChannels);
260 ((IplImage*)
img)->origin = originTopLeft ? 0 : 1;
262 #if IMAGE_ALLOC_PERFLOG 263 alloc_tims.
leave(sLog.c_str());
267 THROW_EXCEPTION(
"The MRPT has been compiled with MRPT_HAS_OPENCV=0 !");
281 IplImage* newImg = cvLoadImage(fileName.c_str(),
isColor);
282 if (newImg !=
nullptr)
293 THROW_EXCEPTION(
"The MRPT has been compiled with MRPT_HAS_OPENCV=0 !");
308 #if MRPT_OPENCV_VERSION_NUM > 0x110 310 p[0] = CV_IMWRITE_JPEG_QUALITY;
313 return (0 != cvSaveImage(fileName.c_str(),
img,
p));
315 return (0 != cvSaveImage(fileName.c_str(),
img));
318 THROW_EXCEPTION(
"The MRPT has been compiled with MRPT_HAS_OPENCV=0 !");
334 img = cvCloneImage((IplImage*)iplImage);
336 THROW_EXCEPTION(
"The MRPT has been compiled with MRPT_HAS_OPENCV=0 !");
351 ASSERTMSG_(iplImage != this->
img,
"Trying to assign read-only to itself.")
353 img = (IplImage*)iplImage;
357 THROW_EXCEPTION(
"The MRPT has been compiled with MRPT_HAS_OPENCV=0 !");
376 img = (IplImage*)iplImage;
378 THROW_EXCEPTION(
"The MRPT has been compiled with MRPT_HAS_OPENCV=0 !");
392 unsigned char* rawpixels,
bool swapRedBlue)
401 if (
color && swapRedBlue)
404 unsigned char* ptr_src = rawpixels;
405 unsigned char* ptr_dest =
406 reinterpret_cast<unsigned char*
>(((IplImage*)
img)->imageData);
407 const int bytes_per_row_out = ((IplImage*)
img)->widthStep;
409 for (
int h =
height; h--;)
411 for (
unsigned int i = 0; i <
width;
412 i++, ptr_src += 3, ptr_dest += 3)
414 unsigned char t0 = ptr_src[0], t1 = ptr_src[1], t2 = ptr_src[2];
419 ptr_dest += bytes_per_row_out -
width * 3;
424 if (((IplImage*)
img)->widthStep ==
425 ((IplImage*)
img)->
width * ((IplImage*)
img)->nChannels)
429 ((IplImage*)
img)->imageData, rawpixels,
435 unsigned char* ptr_src = rawpixels;
436 unsigned char* ptr_dest =
437 reinterpret_cast<unsigned char*
>(((IplImage*)
img)->imageData);
439 int bytes_per_row_out = ((IplImage*)
img)->widthStep;
440 for (
unsigned int y = 0;
y <
height;
y++)
442 memcpy(ptr_dest, ptr_src, bytes_per_row);
443 ptr_src += bytes_per_row;
444 ptr_dest += bytes_per_row_out;
449 THROW_EXCEPTION(
"The MRPT has been compiled with MRPT_HAS_OPENCV=0 !");
458 unsigned int col,
unsigned int row,
unsigned int channel)
const 462 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG) 467 IplImage* ipl = ((IplImage*)
img);
469 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG) 471 if (
row >= (
unsigned int)ipl->height || col >= (
unsigned int)ipl->width ||
472 channel >= (
unsigned int)ipl->nChannels)
476 "Pixel coordinates/channel out of bounds: row=%u/%u col=%u/%u " 478 row, ipl->height, col, ipl->width, channel, ipl->nChannels));
482 return (
unsigned char*)&ipl
483 ->imageData[
row * ipl->widthStep + col * ipl->nChannels + channel];
484 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG) 497 unsigned int col,
unsigned int row,
unsigned int channel)
const 501 IplImage* ipl = ((IplImage*)
img);
502 return (
unsigned char*)&ipl
503 ->imageData[
row * ipl->widthStep + col * ipl->nChannels + channel];
540 const bool hasColor =
isColor();
558 bool imageStoredAsZip =
561 out << imageStoredAsZip;
564 if (imageStoredAsZip)
566 std::vector<unsigned char> tempBuf;
568 ((IplImage*)
img)->imageData,
582 ((IplImage*)
img)->imageData,
621 out << neg_width << neg_height;
624 const IplImage* ipl =
static_cast<const IplImage*
>(
img);
625 const size_t bytes_per_row = ipl->width * 3;
628 &ipl->imageData[0], bytes_per_row * ipl->height);
650 "[CImage] Cannot deserialize image since MRPT has been " 651 "compiled without OpenCV")
670 in >>
width >>
height >> nChannels >> originTopLeft >> imgLength;
673 in.ReadBuffer(((IplImage*)
img)->imageData, imgLength);
734 bool imageIsZIP =
true;
738 if (version == 4 &&
imageSize <= 16 * 1024)
753 size_t outDataActualSize;
756 in, zipDataLen, ((IplImage*)
img)->imageData,
757 outDataBufferSize, outDataActualSize);
759 ASSERT_(outDataActualSize == outDataBufferSize);
765 ((IplImage*)
img)->imageData,
772 bool loadJPEG =
true;
795 const IplImage* ipl =
796 static_cast<const IplImage*
>(
img);
797 const size_t bytes_per_row = ipl->width * 3;
798 for (
int y = 0;
y < ipl->height;
y++)
800 const size_t nRead =
in.ReadBuffer(
801 &ipl->imageData[
y * ipl->widthStep],
803 if (nRead != bytes_per_row)
805 "Error: Truncated data stream " 806 "while parsing raw image?")
848 cv::Mat cvImg = cv::cvarrToMat(this->getAs<IplImage>());
849 return mexplus::from(cvImg);
861 s.x = ((IplImage*)
img)->width;
862 s.y = ((IplImage*)
img)->height;
874 return ((IplImage*)
img)->width;
888 return ((IplImage*)
img)->widthStep;
902 return ((IplImage*)
img)->height;
916 return ((IplImage*)
img)->nChannels > 1;
930 return static_cast<unsigned int>(((IplImage*)
img)->nChannels);
944 return ((IplImage*)
img)->origin == 0;
954 unsigned int col,
unsigned int row,
unsigned int channel)
const 958 return (*(*
this)(col,
row, channel)) / 255.0f;
970 unsigned char*
pixels = (*this)(col,
row, 0);
977 return (*(*
this)(col,
row, 0 )) / 255.0f;
990 for (
x = 0;
x < cx;
x++)
1010 IplImage* img_dest =
1011 cvCreateImage(cvSize(img_src->width, img_src->height), IPL_DEPTH_8U, 1);
1012 img_dest->origin = img_src->origin;
1016 if (
is_aligned<16>(img_src->imageData) && (img_src->width & 0xF) == 0 &&
1017 img_src->widthStep == img_src->width * img_src->nChannels &&
1018 img_dest->widthStep == img_dest->width * img_dest->nChannels)
1022 (
const uint8_t*)img_src->imageData, (
uint8_t*)img_dest->imageData,
1023 img_src->width, img_src->height);
1029 cvCvtColor(img_src, img_dest, CV_BGR2GRAY);
1042 const IplImage* ipl = this->getAs<const IplImage>();
1045 if (ipl->nChannels == 1)
1065 const IplImage* ipl = this->getAs<const IplImage>();
1067 if (ipl->nChannels == 1)
return;
1083 const IplImage* img_src = ((IplImage*)
img);
1084 const int w = img_src->width;
1085 const int h = img_src->height;
1088 IplImage* img_dest =
1089 cvCreateImage(cvSize(
w >> 1, h >> 1), IPL_DEPTH_8U, img_src->nChannels);
1090 img_dest->origin = img_src->origin;
1091 memcpy(img_dest->colorModel, img_src->colorModel, 4);
1092 memcpy(img_dest->channelSeq, img_src->channelSeq, 4);
1093 img_dest->dataOrder = img_src->dataOrder;
1097 if (img_src->nChannels == 3 &&
is_aligned<16>(img_src->imageData) &&
1099 img_src->widthStep == img_src->width * img_src->nChannels &&
1100 img_dest->widthStep == img_dest->width * img_dest->nChannels)
1103 (
const uint8_t*)img_src->imageData, (
uint8_t*)img_dest->imageData,
1111 if (img_src->nChannels == 1 &&
is_aligned<16>(img_src->imageData) &&
1113 img_src->widthStep == img_src->width * img_src->nChannels &&
1114 img_dest->widthStep == img_dest->width * img_dest->nChannels)
1117 (
const uint8_t*)img_src->imageData, (
uint8_t*)img_dest->imageData,
1141 const IplImage* img_src = ((IplImage*)
img);
1142 const int w = img_src->width;
1143 const int h = img_src->height;
1146 IplImage* img_dest =
1147 cvCreateImage(cvSize(
w >> 1, h >> 1), IPL_DEPTH_8U, img_src->nChannels);
1148 img_dest->origin = img_src->origin;
1149 memcpy(img_dest->colorModel, img_src->colorModel, 4);
1150 memcpy(img_dest->channelSeq, img_src->channelSeq, 4);
1151 img_dest->dataOrder = img_src->dataOrder;
1155 if (img_src->nChannels == 1 &&
is_aligned<16>(img_src->imageData) &&
1157 img_src->widthStep == img_src->width * img_src->nChannels &&
1158 img_dest->widthStep == img_dest->width * img_dest->nChannels)
1161 (
const uint8_t*)img_src->imageData, (
uint8_t*)img_dest->imageData,
1193 return ((IplImage*)
img)->channelSeq;
1203 unsigned int width,
unsigned int height,
unsigned int bytesPerRow,
1204 unsigned char*
red,
unsigned char*
green,
unsigned char*
blue)
1213 for (
unsigned int y = 0;
y <
height;
y++)
1216 unsigned char* dest = (
unsigned char*)((IplImage*)
img)->imageData +
1217 ((IplImage*)
img)->widthStep *
y;
1220 unsigned char* srcR =
red + bytesPerRow *
y;
1221 unsigned char* srcG =
green + bytesPerRow *
y;
1222 unsigned char* srcB =
blue + bytesPerRow *
y;
1224 for (
unsigned int x = 0;
x <
width;
x++)
1226 *(dest++) = *(srcB++);
1227 *(dest++) = *(srcG++);
1228 *(dest++) = *(srcR++);
1244 ((IplImage*)
img)->origin =
val ? 0 : 1;
1255 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG) 1261 IplImage* ipl = ((IplImage*)
img);
1263 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG) 1270 if (ipl->nChannels == 1)
1272 *((
unsigned char*)&ipl->imageData[
y * ipl->widthStep +
x]) =
1273 (
unsigned char)
color;
1277 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG) 1279 if (ipl->dataOrder != 0)
1281 "Please, use interleaved images like normal people!!! :-)");
1283 unsigned char* dest =
1284 (
unsigned char*)&ipl->imageData[
y * ipl->widthStep + 3 *
x];
1285 unsigned char*
src = (
unsigned char*)&
color;
1294 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG) 1311 IplImage* ipl = ((IplImage*)
img);
1315 ipl, cvPoint(x0, y0), cvPoint(x1, y1),
1329 IplImage* ipl = ((IplImage*)
img);
1341 const CImage& patch,
const unsigned int col_,
const unsigned int row_)
1344 IplImage* ipl_int = ((IplImage*)
img);
1345 IplImage* ipl_ext = ((IplImage*)patch.
img);
1349 if (row_ + ipl_ext->height >
getHeight() ||
1350 col_ + ipl_ext->width >
getWidth())
1354 for (
unsigned int i = 0; i < patch.
getHeight(); i++)
1357 &ipl_int->imageData[(i + row_) * ipl_int->widthStep +
1358 col_ * ipl_int->nChannels],
1359 &ipl_ext->imageData[i * ipl_ext->widthStep], ipl_ext->widthStep);
1368 CImage& patch,
const unsigned int col_,
const unsigned int row_,
1369 const unsigned int col_num,
const unsigned int row_num)
const 1374 IplImage* ipl_int = ((IplImage*)
img);
1377 if ((ipl_int->width < (
int)(col_ + col_num)) ||
1378 (ipl_int->height < (
int)(row_ + row_num)))
1382 "Trying to extract patch out of image boundaries: Image " 1383 "size=%ix%i, Patch size=%ux%u, extraction location=(%u,%u)",
1384 ipl_int->width, ipl_int->height, col_num, row_num, col_, row_))
1387 patch.
resize(col_num, row_num, ((IplImage*)
img)->nChannels,
true);
1388 IplImage* ipl_ext = ((IplImage*)patch.
img);
1391 for (
unsigned int i = 0; i < row_num; i++)
1394 &ipl_ext->imageData[i * ipl_ext->widthStep],
1395 &ipl_int->imageData[(i + row_) * ipl_int->widthStep +
1396 col_ * ipl_int->nChannels],
1397 ipl_ext->widthStep);
1407 const CImage& img2,
int width_init,
int height_init)
const 1414 THROW_EXCEPTION(
"Correlation Error!, image to correlate out of bounds");
1418 float syy = 0.0f, sxy = 0.0f, sxx = 0.0f, m1 = 0.0f, m2 = 0.0f,
1426 for (j = 0; j < img2.
getWidth(); j++)
1441 for (j = 0; j < img2.
getWidth(); j++)
1443 x1 = *(*this)(j + width_init, i + height_init) -
1453 return sxy / sqrt(sxx * syy);
1463 const CImage& patch_img,
size_t& x_max,
size_t& y_max,
double& max_val,
1464 int x_search_ini,
int y_search_ini,
int x_search_size,
int y_search_size,
1465 CImage* out_corr_image)
const 1473 CvPoint min_point, max_point;
1476 (x_search_ini < 0 || y_search_ini < 0 || x_search_size < 0 ||
1479 const IplImage *im, *patch_im;
1483 const IplImage* im_ = this->getAs<IplImage>();
1484 const IplImage* patch_im_ = patch_img.
getAs<IplImage>();
1486 IplImage* aux = cvCreateImage(cvGetSize(im_), 8, 1);
1487 IplImage* aux2 = cvCreateImage(cvGetSize(patch_im_), 8, 1);
1488 cvCvtColor(im_, aux, CV_BGR2GRAY);
1489 cvCvtColor(patch_im_, aux2, CV_BGR2GRAY);
1495 im = this->getAs<IplImage>();
1496 patch_im = patch_img.
getAs<IplImage>();
1501 x_search_size = im->width - patch_im->width;
1502 y_search_size = im->height - patch_im->height;
1506 if ((x_search_ini + x_search_size + patch_im->width - 1) > im->width)
1508 (x_search_ini + x_search_size + patch_im->width - 1) - im->width;
1510 if ((y_search_ini + y_search_size + patch_im->height - 1) > im->height)
1512 (y_search_ini + y_search_size + patch_im->height - 1) - im->height;
1514 ASSERT_((x_search_ini + x_search_size + patch_im->width - 1) <= im->width)
1515 ASSERT_((y_search_ini + y_search_size + patch_im->height - 1) <= im->height)
1517 IplImage* result = cvCreateImage(
1518 cvSize(x_search_size + 1, y_search_size + 1), IPL_DEPTH_32F, 1);
1520 const IplImage* ipl_ext;
1524 IplImage* aux = cvCreateImage(
1526 patch_im->width + x_search_size,
1527 patch_im->height + y_search_size),
1529 for (
unsigned int i = 0; i < (
unsigned int)y_search_size; i++)
1532 &aux->imageData[i * aux->widthStep],
1533 &im->imageData[(i + y_search_ini) * im->widthStep +
1534 x_search_ini * im->nChannels],
1535 aux->width * aux->nChannels);
1548 cvMatchTemplate(ipl_ext, patch_im, result, CV_TM_CCORR_NORMED);
1552 cvMinMaxLoc(result, &mini, &max_val, &min_point, &max_point,
nullptr);
1553 x_max = max_point.x + x_search_ini + (
round(patch_im->width - 1) / 2);
1554 y_max = max_point.y + y_search_ini + (
round(patch_im->height - 1) / 2);
1559 IplImage* aux =
const_cast<IplImage*
>(ipl_ext);
1560 cvReleaseImage(&aux);
1568 cvReleaseImage(&result);
1570 THROW_EXCEPTION(
"The MRPT has been compiled with MRPT_HAS_OPENCV=0 !");
1583 IplImage* ipl = getAs<IplImage>();
1586 ipl->nChannels == 1,
1587 "CImage::normalize() only defined for grayscale images.")
1590 for (
int y = 0;
y < ipl->height;
y++)
1593 ipl->imageData +
y * ipl->widthStep);
1594 for (
int x = 0;
x < ipl->width;
x++)
1597 if (min_ >
val) min_ =
val;
1598 if (max_ <
val) max_ =
val;
1603 const double s = 255.0 / ((double)max_ - (
double)min_);
1608 for (
int y = 0;
y < ipl->height;
y++)
1611 reinterpret_cast<uint8_t*
>(ipl->imageData +
y * ipl->widthStep);
1612 for (
int x = 0;
x < ipl->width;
x++)
1625 CMatrixFloat& outMatrix,
bool doResize,
int x_min,
int y_min,
int x_max,
1635 if (x_max == -1) x_max = ((IplImage*)
img)->width - 1;
1636 if (y_max == -1) y_max = ((IplImage*)
img)->height - 1;
1638 ASSERT_(x_min >= 0 && x_min < ((IplImage*)
img)->
width && x_min < x_max);
1641 int lx = (x_max - x_min + 1);
1642 int ly = (y_max - y_min + 1);
1644 if (doResize || (
int)outMatrix.getRowCount() < ly ||
1645 (int)outMatrix.getColCount() < lx)
1646 outMatrix.setSize(y_max - y_min + 1, x_max - x_min + 1);
1651 for (
int y = 0;
y < ly;
y++)
1655 for (
int x = 0;
x < lx;
x++)
1657 aux = *
pixels++ * 0.3f * (1.0f / 255);
1658 aux += *
pixels++ * 0.59f * (1.0f / 255);
1659 aux += *
pixels++ * 0.11f * (1.0f / 255);
1660 outMatrix.set_unsafe(
y,
x, aux);
1666 for (
int y = 0;
y < ly;
y++)
1669 for (
int x = 0;
x < lx;
x++)
1670 outMatrix.set_unsafe(
y,
x, (*
pixels++) * (1.0f / 255));
1684 int x_max,
int y_max)
const 1693 if (x_max == -1) x_max = ((IplImage*)
img)->width - 1;
1694 if (y_max == -1) y_max = ((IplImage*)
img)->height - 1;
1696 ASSERT_(x_min >= 0 && x_min < ((IplImage*)
img)->
width && x_min < x_max);
1699 int lx = (x_max - x_min + 1);
1700 int ly = (y_max - y_min + 1);
1702 if (doResize || (
int)outMatrixR.getRowCount() < ly ||
1703 (int)outMatrixR.getColCount() < lx)
1704 outMatrixR.setSize(y_max - y_min + 1, x_max - x_min + 1);
1705 if (doResize || (
int)outMatrixG.getRowCount() < ly ||
1706 (int)outMatrixG.getColCount() < lx)
1707 outMatrixG.setSize(y_max - y_min + 1, x_max - x_min + 1);
1708 if (doResize || (
int)outMatrixB.getRowCount() < ly ||
1709 (int)outMatrixB.getColCount() < lx)
1710 outMatrixB.setSize(y_max - y_min + 1, x_max - x_min + 1);
1714 for (
int y = 0;
y < ly;
y++)
1718 for (
int x = 0;
x < lx;
x++)
1720 aux = *
pixels++ * (1.0f / 255);
1721 outMatrixR.set_unsafe(
y,
x, aux);
1722 aux = *
pixels++ * (1.0f / 255);
1723 outMatrixG.set_unsafe(
y,
x, aux);
1724 aux = *
pixels++ * (1.0f / 255);
1725 outMatrixB.set_unsafe(
y,
x, aux);
1731 for (
int y = 0;
y < ly;
y++)
1734 for (
int x = 0;
x < lx;
x++)
1736 outMatrixR.set_unsafe(
y,
x, (*
pixels) * (1.0f / 255));
1737 outMatrixG.set_unsafe(
y,
x, (*
pixels) * (1.0f / 255));
1738 outMatrixB.set_unsafe(
y,
x, (*
pixels++) * (1.0f / 255));
1752 int v_search_ini,
int u_search_size,
int v_search_size,
float biasThisImg,
1753 float biasInImg)
const 1761 if (u_search_ini == -1) u_search_ini = 0;
1762 if (v_search_ini == -1) v_search_ini = 0;
1763 if (u_search_size == -1) u_search_size =
getWidth();
1764 if (v_search_size == -1) v_search_size =
getHeight();
1766 int u_search_end = u_search_ini + u_search_size - 1;
1767 int v_search_end = v_search_ini + v_search_size - 1;
1774 size_t actual_lx = max(u_search_size, (
int)in_img.
getWidth());
1775 size_t actual_ly = max(v_search_size, (
int)in_img.
getHeight());
1781 CMatrix i1(ly, lx), i2(ly, lx);
1787 i2.fill(biasThisImg);
1791 i2,
false, u_search_ini, v_search_ini, u_search_ini + u_search_size - 1,
1792 v_search_ini + v_search_size - 1);
1796 i2.array() -= biasThisImg;
1797 i1.array() -= biasInImg;
1803 CMatrix I1_R, I1_I, I2_R, I2_I, ZEROS(ly, lx);
1811 for (
y = 0;
y < ly;
y++)
1812 for (
x = 0;
x < lx;
x++)
1814 float r1 = I1_R.get_unsafe(
y,
x);
1815 float r2 = I2_R.get_unsafe(
y,
x);
1817 float ii1 = I1_I.get_unsafe(
y,
x);
1818 float ii2 = I2_I.get_unsafe(
y,
x);
1821 I2_R.set_unsafe(
y,
x, (r1 * r2 + ii1 * ii2) / den);
1822 I2_I.set_unsafe(
y,
x, (ii2 * r1 - r2 * ii1) / den);
1832 out_corr.setSize(actual_ly, actual_lx);
1833 for (
y = 0;
y < actual_ly;
y++)
1834 for (
x = 0;
x < actual_lx;
x++)
1852 size_t matrix_lx = outMatrix.getColCount();
1853 size_t matrix_ly = outMatrix.getRowCount();
1858 for (
unsigned int y = 0;
y < matrix_ly;
y++)
1860 unsigned char* min_pixels =
1861 (*this)(0,
y % ((IplImage*)
img)->height, 0);
1862 unsigned char* max_pixels =
1863 min_pixels + ((IplImage*)
img)->width * 3;
1864 unsigned char*
pixels = min_pixels;
1866 for (
unsigned int x = 0;
x < matrix_lx;
x++)
1869 aux += *
pixels++ * 0.59f;
1870 aux += *
pixels++ * 0.11f;
1871 outMatrix.set_unsafe(
y,
x, aux);
1878 for (
unsigned int y = 0;
y < matrix_ly;
y++)
1880 unsigned char* min_pixels =
1881 (*this)(0,
y % ((IplImage*)
img)->height, 0);
1882 unsigned char* max_pixels = min_pixels + ((IplImage*)
img)->width;
1883 unsigned char*
pixels = min_pixels;
1884 for (
unsigned int x = 0;
x < matrix_lx;
x++)
1886 outMatrix.set_unsafe(
y,
x, *
pixels++);
1902 m_externalFile = fileName;
1903 m_imgIsExternalStorage =
true;
1922 if (
img && !m_imgIsReadOnly)
1924 IplImage* ptr = (IplImage*)
img;
1925 cvReleaseImage(&ptr);
1928 m_imgIsReadOnly =
false;
1929 if (!thisIsExternalImgUnload)
1931 m_imgIsExternalStorage =
false;
1932 m_externalFile =
string();
1942 if (
img !=
nullptr)
return;
1962 "Error loading externally-stored image from: %s",
1999 IplImage* ptr = (IplImage*)
img;
2000 int options = CV_CVTIMG_FLIP;
2001 if (also_swapRB) options |= CV_CVTIMG_SWAP_RB;
2002 cvConvertImage(ptr, ptr, options);
2009 IplImage* ptr = (IplImage*)
img;
2010 cvFlip(ptr,
nullptr, 1);
2022 IplImage* ptr = (IplImage*)
img;
2023 cvConvertImage(ptr, ptr, CV_CVTIMG_SWAP_RB);
2036 #if MRPT_OPENCV_VERSION_NUM < 0x200 2040 IplImage* srcImg = getAs<IplImage>();
2042 cvCreateImage(cvGetSize(srcImg), srcImg->depth, srcImg->nChannels);
2044 cv::Mat *_mapX, *_mapY;
2045 _mapX =
static_cast<cv::Mat*
>(mapX);
2046 _mapY =
static_cast<cv::Mat*
>(mapY);
2048 IplImage _mapXX = *_mapX;
2049 IplImage _mapYY = *_mapY;
2051 cvRemap(srcImg, outImg, &_mapXX, &_mapYY, CV_INTER_CUBIC);
2068 IplImage* srcImg = getAs<IplImage>();
2070 outImg = cvCreateImage(cvGetSize(srcImg), srcImg->depth, srcImg->nChannels);
2072 double aux1[3][3], aux2[1][5];
2075 for (
int i = 0; i < 3; i++)
2076 for (
int j = 0; j < 3; j++) aux1[i][j] = cameraMatrix(i, j);
2077 for (
int i = 0; i < 5; i++) aux2[0][i] = cameraParams.
dist[i];
2079 CvMat inMat = cvMat(
2080 cameraMatrix.getRowCount(), cameraMatrix.getColCount(), CV_64F, aux1);
2081 CvMat distM = cvMat(1, 5, CV_64F, aux2);
2084 cvUndistort2(srcImg, outImg, &inMat, &distM);
2102 const IplImage* srcImg = getAs<IplImage>();
2104 outImg = cvCreateImage(cvGetSize(srcImg), srcImg->depth, srcImg->nChannels);
2106 double aux1[3][3], aux2[1][5];
2109 for (
int i = 0; i < 3; i++)
2110 for (
int j = 0; j < 3; j++) aux1[i][j] = cameraMatrix(i, j);
2111 for (
int i = 0; i < 5; i++) aux2[0][i] = cameraParams.
dist[i];
2113 CvMat inMat = cvMat(
2114 cameraMatrix.getRowCount(), cameraMatrix.getColCount(), CV_64F, aux1);
2115 CvMat distM = cvMat(1, 5, CV_64F, aux2);
2118 cvUndistort2(srcImg, outImg, &inMat, &distM);
2124 cvReleaseImage(&outImg);
2137 const IplImage* srcImg = getAs<IplImage>();
2139 outImg = cvCreateImage(cvGetSize(srcImg), srcImg->depth, srcImg->nChannels);
2142 cvSmooth(srcImg, outImg, CV_MEDIAN, W);
2144 outImg->origin = srcImg->origin;
2150 cvReleaseImage(&outImg);
2163 IplImage* srcImg = getAs<IplImage>();
2165 outImg = cvCreateImage(cvGetSize(srcImg), srcImg->depth, srcImg->nChannels);
2168 cvSmooth(srcImg, outImg, CV_MEDIAN, W);
2170 outImg->origin = srcImg->origin;
2187 const IplImage* srcImg = getAs<IplImage>();
2189 outImg = cvCreateImage(cvGetSize(srcImg), srcImg->depth, srcImg->nChannels);
2192 cvSmooth(srcImg, outImg, CV_GAUSSIAN, W, H);
2194 outImg->origin = srcImg->origin;
2200 cvReleaseImage(&outImg);
2213 IplImage* srcImg = getAs<IplImage>();
2215 outImg = cvCreateImage(cvGetSize(srcImg), srcImg->depth, srcImg->nChannels);
2218 cvSmooth(srcImg, outImg, CV_GAUSSIAN, W, H);
2220 outImg->origin = srcImg->origin;
2237 IplImage* srcImg = getAs<IplImage>();
2239 if (static_cast<unsigned int>(srcImg->width) ==
width &&
2240 static_cast<unsigned int>(srcImg->height) ==
height)
2245 cvCreateImage(cvSize(
width,
height), srcImg->depth, srcImg->nChannels);
2248 cvResize(srcImg, outImg, (
int)
interp);
2250 outImg->origin = srcImg->origin;
2268 const IplImage* srcImg = getAs<IplImage>();
2270 if (static_cast<unsigned int>(srcImg->width) ==
width &&
2271 static_cast<unsigned int>(srcImg->height) ==
height)
2280 cvCreateImage(cvSize(
width,
height), srcImg->depth, srcImg->nChannels);
2283 cvResize(srcImg, outImg, (
int)
interp);
2284 outImg->origin = srcImg->origin;
2295 double angle_radians,
unsigned int center_x,
unsigned int center_y,
2302 IplImage* srcImg = getAs<IplImage>();
2304 outImg = cvCreateImage(cvGetSize(srcImg), srcImg->depth, srcImg->nChannels);
2311 CvMat M = cvMat(2, 3, CV_32F, m);
2313 m[0] = (float)(
scale * cos(angle_radians));
2314 m[1] = (float)(
scale * sin(angle_radians));
2320 cvGetQuadrangleSubPix(srcImg, outImg, &M);
2322 outImg->origin = srcImg->origin;
2342 std::vector<TPixelCoordf>& cornerCoords,
unsigned int check_size_x,
2343 unsigned int check_size_y,
unsigned int lines_width,
unsigned int r)
2347 if (cornerCoords.size() != check_size_x * check_size_y)
return false;
2349 IplImage* ipl = this->getAs<IplImage>();
2351 unsigned int x,
y, i;
2352 CvPoint prev_pt = cvPoint(0, 0);
2353 const int line_max = 8;
2354 CvScalar line_colors[8];
2356 line_colors[0] = CV_RGB(255, 0, 0);
2357 line_colors[1] = CV_RGB(255, 128, 0);
2358 line_colors[2] = CV_RGB(255, 128, 0);
2359 line_colors[3] = CV_RGB(200, 200, 0);
2360 line_colors[4] = CV_RGB(0, 255, 0);
2361 line_colors[5] = CV_RGB(0, 200, 200);
2362 line_colors[6] = CV_RGB(0, 0, 255);
2363 line_colors[7] = CV_RGB(255, 0, 255);
2367 for (
y = 0, i = 0;
y < check_size_y;
y++)
2369 CvScalar
color = line_colors[
y % line_max];
2370 for (
x = 0;
x < check_size_x;
x++, i++)
2373 pt.x = cvRound(cornerCoords[i].
x);
2374 pt.y = cvRound(cornerCoords[i].
y);
2376 if (i != 0) cvLine(ipl, prev_pt, pt,
color, lines_width);
2379 ipl, cvPoint(pt.x -
r, pt.y -
r), cvPoint(pt.x +
r, pt.y +
r),
2380 color, lines_width);
2382 ipl, cvPoint(pt.x -
r, pt.y +
r), cvPoint(pt.x +
r, pt.y -
r),
2383 color, lines_width);
2385 if (
r > 0) cvCircle(ipl, pt,
r + 1,
color);
2389 if (i == 0 || i == cornerCoords.size() - 1)
2414 const IplImage* srcImg = getAs<IplImage>();
2415 IplImage* outImg = cvCreateImage(cvGetSize(srcImg), srcImg->depth, 3);
2417 cvCvtColor(srcImg, outImg, CV_GRAY2BGR);
2419 outImg->origin = srcImg->origin;
2434 IplImage* srcImg = getAs<IplImage>();
2436 outImg = cvCreateImage(cvGetSize(srcImg), srcImg->depth, 3);
2438 cvCvtColor(srcImg, outImg, CV_GRAY2BGR);
2440 outImg->origin = srcImg->origin;
2456 const IplImage* _im1 = im1.
getAs<IplImage>();
2457 const IplImage* _im2 = im2.
getAs<IplImage>();
2459 ASSERT_(_im1->depth == _im2->depth && _im1->nChannels == _im2->nChannels);
2461 IplImage* out = cvCreateImage(
2462 cvSize(_im1->width + _im2->width, _im1->height), _im1->depth,
2465 cvSetImageROI(out, cvRect(0, 0, _im1->width, _im1->height));
2467 cvSetImageROI(out, cvRect(_im1->width, 0, _im2->width, _im2->height));
2469 cvSetImageROI(out, cvRect(0, 0, out->width, out->height));
2472 if ((
int)_im1->nChannels != (
int)this->getChannelCount())
2477 out2 = cvCreateImage(
2478 cvSize(_im1->width + _im2->width, _im1->height), _im1->depth,
2479 this->getChannelCount());
2480 cvCvtColor(out, out2, CV_GRAY2BGR);
2496 const IplImage* srcImg = getAs<IplImage>();
2501 if (srcImg->nChannels == 1)
2503 cvEqualizeHist(srcImg, outImg.
getAs<IplImage>());
2507 IplImage* hsv = cvCreateImage(cvGetSize(srcImg), 8, 3);
2508 IplImage* h = cvCreateImage(cvGetSize(srcImg), 8, 1);
2509 IplImage*
s = cvCreateImage(cvGetSize(srcImg), 8, 1);
2510 IplImage*
v = cvCreateImage(cvGetSize(srcImg), 8, 1);
2512 cvCvtColor(srcImg, hsv, CV_BGR2HSV);
2513 cvSplit(hsv, h,
s,
v,
nullptr);
2515 cvEqualizeHist(
v,
v);
2517 cvMerge(h,
s,
v,
nullptr, hsv);
2518 cvCvtColor(hsv, outImg.
getAs<IplImage>(), CV_HSV2BGR);
2520 cvReleaseImage(&hsv);
2536 IplImage* srcImg = getAs<IplImage>();
2540 cvCreateImage(cvGetSize(srcImg), srcImg->depth, srcImg->nChannels);
2541 outImg->origin = srcImg->origin;
2543 if (srcImg->nChannels == 1)
2545 cvEqualizeHist(srcImg, outImg);
2549 IplImage* hsv = cvCreateImage(cvGetSize(srcImg), 8, 3);
2550 IplImage* h = cvCreateImage(cvGetSize(srcImg), 8, 1);
2551 IplImage*
s = cvCreateImage(cvGetSize(srcImg), 8, 1);
2552 IplImage*
v = cvCreateImage(cvGetSize(srcImg), 8, 1);
2554 cvCvtColor(srcImg, hsv, CV_BGR2HSV);
2555 cvSplit(hsv, h,
s,
v,
nullptr);
2557 cvEqualizeHist(
v,
v);
2559 cvMerge(h,
s,
v,
nullptr, hsv);
2560 cvCvtColor(hsv, outImg, CV_HSV2BGR);
2562 cvReleaseImage(&hsv);
2575 template <
unsigned int HALF_WIN_SIZE>
2580 const unsigned int min_x =
x - HALF_WIN_SIZE;
2581 const unsigned int min_y =
y - HALF_WIN_SIZE;
2587 const unsigned int WIN_SIZE = 1 + 2 * HALF_WIN_SIZE;
2589 unsigned int yy = min_y;
2590 for (
unsigned int iy = WIN_SIZE; iy; --iy, ++yy)
2592 const uint8_t* ptr =
in + widthStep * yy + min_x;
2593 unsigned int xx = min_x;
2594 for (
unsigned int ix = WIN_SIZE; ix; --ix, ++xx)
2596 const int32_t dx = ptr[+1] - ptr[-1];
2597 const int32_t dy = ptr[+widthStep] - ptr[-widthStep];
2609 const unsigned int x,
const unsigned int y,
2610 const unsigned int half_window_size)
const 2613 const IplImage* srcImg = this->getAs<IplImage>();
2616 srcImg->nChannels == 1,
2617 "KLT_response only works with grayscale images.")
2619 const unsigned int img_w = srcImg->width;
2620 const unsigned int img_h = srcImg->height;
2621 const int widthStep = srcImg->widthStep;
2624 const unsigned int min_x =
x - half_window_size;
2625 const unsigned int max_x =
x + half_window_size;
2626 const unsigned int min_y =
y - half_window_size;
2627 const unsigned int max_y =
y + half_window_size;
2631 min_x < img_w && max_x < img_w && min_y < img_h && max_y < img_h,
2632 "Window is out of image bounds")
2642 switch (half_window_size)
2645 image_KLT_response_template<2>(
2646 img_data, widthStep,
x,
y, gxx, gyy, gxy);
2649 image_KLT_response_template<3>(
2650 img_data, widthStep,
x,
y, gxx, gyy, gxy);
2653 image_KLT_response_template<4>(
2654 img_data, widthStep,
x,
y, gxx, gyy, gxy);
2657 image_KLT_response_template<5>(
2658 img_data, widthStep,
x,
y, gxx, gyy, gxy);
2661 image_KLT_response_template<6>(
2662 img_data, widthStep,
x,
y, gxx, gyy, gxy);
2665 image_KLT_response_template<7>(
2666 img_data, widthStep,
x,
y, gxx, gyy, gxy);
2669 image_KLT_response_template<8>(
2670 img_data, widthStep,
x,
y, gxx, gyy, gxy);
2673 image_KLT_response_template<9>(
2674 img_data, widthStep,
x,
y, gxx, gyy, gxy);
2677 image_KLT_response_template<10>(
2678 img_data, widthStep,
x,
y, gxx, gyy, gxy);
2681 image_KLT_response_template<11>(
2682 img_data, widthStep,
x,
y, gxx, gyy, gxy);
2685 image_KLT_response_template<12>(
2686 img_data, widthStep,
x,
y, gxx, gyy, gxy);
2689 image_KLT_response_template<13>(
2690 img_data, widthStep,
x,
y, gxx, gyy, gxy);
2693 image_KLT_response_template<14>(
2694 img_data, widthStep,
x,
y, gxx, gyy, gxy);
2697 image_KLT_response_template<15>(
2698 img_data, widthStep,
x,
y, gxx, gyy, gxy);
2701 image_KLT_response_template<16>(
2702 img_data, widthStep,
x,
y, gxx, gyy, gxy);
2705 image_KLT_response_template<32>(
2706 img_data, widthStep,
x,
y, gxx, gyy, gxy);
2710 for (
unsigned int yy = min_y; yy <= max_y; yy++)
2712 const uint8_t* ptr = img_data + widthStep * yy + min_x;
2713 for (
unsigned int xx = min_x; xx <= max_x; xx++)
2715 const int32_t dx = ptr[+1] - ptr[-1];
2716 const int32_t dy = ptr[+widthStep] - ptr[-widthStep];
2725 const float K = 0.5f / ((max_y - min_y + 1) * (max_x - min_x + 1));
2726 const float Gxx = gxx * K;
2727 const float Gxy = gxy * K;
2728 const float Gyy = gyy * K;
2734 const float t = Gxx + Gyy;
2735 const float de = Gxx * Gyy - Gxy * Gxy;
2737 return 0.5f * (
t - std::sqrt(
t *
t - 4.0f * de));
2751 strcpy(((IplImage*)
img)->channelSeq,
"RGB");
2762 strcpy(((IplImage*)
img)->channelSeq,
"BGR");
2773 #if MRPT_HAS_OPENCV && MRPT_HAS_WXWIDGETS 2776 const wxImage
b(xpm_array);
2778 const size_t lx =
b.GetWidth();
2779 const size_t ly =
b.GetHeight();
2784 catch (std::exception& e)
2786 std::cerr <<
"[CImage::loadFromXPM] " << e.what() << std::endl;
2793 #endif // MRPT_HAS_OPENCV && MRPT_HAS_WXWIDGETS 2805 std::fstream stream;
2807 if (!stream.is_open())
2809 std::cerr <<
"[CImage::loadTGA] Couldn't open file '" << fileName
2816 stream.seekg(0, std::ios_base::beg);
2819 char dumpBuffer[12];
2820 char trueColorHeader[] =
"\0\0\2\0\0\0\0\0\0\0\0\0";
2821 stream.read(dumpBuffer, 12);
2822 if (memcmp(dumpBuffer, trueColorHeader, 12) != 0)
2824 std::cerr <<
"[CImage::loadTGA] Unsupported format or invalid file.\n";
2831 stream.read((
char*)&
width, 2);
2832 stream.read((
char*)&
height, 2);
2836 std::cerr <<
"[CImage::loadTGA] Only 32 bpp format supported!\n";
2841 desc = stream.get();
2842 if (desc != 8 && desc != 32)
2844 std::cerr <<
"[CImage::loadTGA] Unsupported format or invalid file.\n";
2847 const bool origin_is_low_corner = (desc == 8);
2851 stream.read((
char*)&bytes[0],
width *
height * 4);
2859 for (
unsigned int r = 0;
r <
height;
r++)
2861 unsigned int actual_row = origin_is_low_corner ? (
height - 1 -
r) :
r;
2862 IplImage* ipl = ((IplImage*)out_RGB.
img);
2863 unsigned char*
data =
2864 (
unsigned char*)&ipl->imageData[actual_row * ipl->widthStep];
2866 IplImage* ipl_alpha = ((IplImage*)out_alpha.
img);
2867 unsigned char* data_alpha =
2868 (
unsigned char*)&ipl->imageData[actual_row * ipl_alpha->widthStep];
2872 *
data++ = bytes[idx++];
2873 *
data++ = bytes[idx++];
2874 *
data++ = bytes[idx++];
2875 *data_alpha++ = bytes[idx++];
2882 #endif // MRPT_HAS_OPENCV virtual void textOut(int x0, int y0, const std::string &str, const mrpt::utils::TColor color)
Renders 2D text using bitmap fonts.
bool is_aligned< 16 >(const void *ptr)
float getAsFloat(unsigned int col, unsigned int row, unsigned int channel) const
Returns the contents of a given pixel at the desired channel, in float format: [0,255]->[0,1] The coordinate origin is pixel(0,0)=top-left corner of the image.
void equalizeHistInPlace()
Equalize the image histogram, replacing the original image.
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei imageSize
float correlate(const CImage &img2int, int width_init=0, int height_init=0) const
Computes the correlation coefficient (returned as val), between two images This function use grayscal...
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
TImageChannels getChannelCount() const
Returns the number of channels, typically 1 (GRAY) or 3 (RGB)
static bool DISABLE_JPEG_COMPRESSION
By default, when storing images through the CSerializable interface, RGB images are JPEG-compressed t...
std::string format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
static int SERIALIZATION_JPEG_QUALITY
Unless DISABLE_JPEG_COMPRESSION=true, this sets the JPEG quality (range 1-100) of serialized RGB imag...
std::string m_externalFile
The file name of a external storage image.
This namespace provides a OS-independent interface to many useful functions: filenames manipulation...
static bool loadTGA(const std::string &fileName, mrpt::utils::CImage &out_RGB, mrpt::utils::CImage &out_alpha)
Loads a TGA true-color RGBA image as two CImage objects, one for the RGB channels plus a separate gra...
CImage scaleDouble() const
Returns a new image scaled up to double its original size.
The virtual base class which provides a unified interface for all persistent objects in MRPT...
bool m_imgIsReadOnly
Set to true only when using setFromIplImageReadOnly.
A class for storing images as grayscale or RGB bitmaps.
#define IMPLEMENTS_SERIALIZABLE(class_name, base, NameSpace)
This must be inserted in all CSerializable classes implementation files.
void flipVertical(bool also_swapRB=false)
Flips the image vertically.
GLenum GLenum GLenum GLenum GLenum scale
#define THROW_TYPED_EXCEPTION_FMT(exceptionClass, _FORMAT_STRING,...)
void rotateImage(double angle_radians, unsigned int center_x, unsigned int center_y, double scale=1.0)
Rotates the image by the given angle around the given center point, with an optional scale factor...
uint64_t Seek(uint64_t Offset, CStream::TSeekOrigin Origin=sFromBeginning) override
Introduces a pure virtual method for moving to a specified position in the streamed resource...
void unload() const noexcept
For external storage image objects only, this method unloads the image from memory (or does nothing i...
void image_SSSE3_bgr_to_gray_8u(const uint8_t *in, uint8_t *out, int w, int h)
Convert a RGB image (3cu8) into a GRAYSCALE (1c8u) image, using Y=77*R+150*G+29*B.
void rectifyImageInPlace(const mrpt::utils::TCamera &cameraParams)
Rectify (un-distort) the image according to a certain camera matrix and vector of distortion coeffici...
void copyFastFrom(CImage &o)
Moves an image from another object, erasing the origin image in the process (this is much faster than...
#define THROW_EXCEPTION(msg)
void resize(unsigned int width, unsigned int height, TImageChannels nChannels, bool originTopLeft)
Changes the size of the image, erasing previous contents (does NOT scale its current content...
void getAsMatrix(mrpt::math::CMatrixFloat &outMatrix, bool doResize=true, int x_min=0, int y_min=0, int x_max=-1, int y_max=-1) const
Returns the image as a matrix with pixel grayscale values in the range [0,1].
A pair (x,y) of pixel coordinates (integer resolution).
void rectifyImage(CImage &out_img, const mrpt::utils::TCamera &cameraParams) const
Rectify (un-distort) the image according to some camera parameters, and returns an output un-distorte...
const char * getChannelsOrder() const
Returns a string of the form "BGR","RGB" or "GRAY" indicating the channels ordering.
float getMaxAsFloat() const
Return the maximum pixel value of the image, as a float value in the range [0,1]. ...
void WriteBuffer(const void *Buffer, size_t Count)
Writes a block of bytes to the stream from Buffer.
void filterMedian(CImage &out_img, int W=3) const
Filter the image with a Median filter with a window size WxW, returning the filtered image in out_img...
void flipHorizontal()
Flips the image horizontally.
void writeToStream(mrpt::utils::CStream &out, int *getVersion) const override
Introduces a pure virtual method responsible for writing to a CStream.
for(ctr=DCTSIZE;ctr > 0;ctr--)
void colorImageInPlace()
Replaces this grayscale image with a RGB version of it.
void cross_correlation(const CImage &patch_img, size_t &u_max, size_t &v_max, double &max_val, int u_search_ini=-1, int v_search_ini=-1, int u_search_size=-1, int v_search_size=-1, CImage *out_corr_image=nullptr) const
Computes the correlation between this image and another one, encapsulating the openCV function cvMatc...
bool loadFromFile(const std::string &fileName, int isColor=-1)
Load image from a file, whose format is determined from the extension (internally uses OpenCV)...
int TImageChannels
For use in mrpt::utils::CImage.
void normalize()
Optimize the brightness range of an image without using histogram Only for one channel images...
void loadFromIplImage(void *iplImage)
Reads the image from a OpenCV IplImage object (making a COPY).
GLubyte GLubyte GLubyte GLubyte w
const T * getAs() const
Returns a pointer to a const T* containing the image - the idea is to call like "img.getAs<IplImage>()" so we can avoid here including OpenCV's headers.
virtual ~CImage()
Destructor:
CImage & operator=(const CImage &o)
Copy operator (if the image is externally stored, the writen image will be such as well)...
T square(const T x)
Inline function for the square of a number.
static std::string IMAGES_PATH_BASE(".")
void image_SSE2_scale_half_smooth_1c8u(const uint8_t *in, uint8_t *out, int w, int h)
Average each 2x2 pixels into 1x1 pixel (arithmetic average)
void cross_correlation_FFT(const CImage &in_img, math::CMatrixFloat &out_corr, int u_search_ini=-1, int v_search_ini=-1, int u_search_size=-1, int v_search_size=-1, float biasThisImg=0, float biasInImg=0) const
Computes the correlation matrix between this image and another one.
void image_SSSE3_scale_half_3c8u(const uint8_t *in, uint8_t *out, int w, int h)
Subsample each 2x2 pixel block into 1x1 pixel, taking the first pixel & ignoring the other 3...
void getAsMatrixTiled(math::CMatrix &outMatrix) const
Returns the image as a matrix, where the image is "tiled" (repeated) the required number of times to ...
This base class is used to provide a unified interface to files,memory buffers,..Please see the deriv...
This base provides a set of functions for maths stuff.
size_t getWidth() const override
Returns the width of the image in pixels.
T round2up(T val)
Round up to the nearest power of two of a given number.
void loadFromMemoryBuffer(unsigned int width, unsigned int height, bool color, unsigned char *rawpixels, bool swapRedBlue=false)
Reads the image from raw pixels buffer in memory.
float KLT_response(const unsigned int x, const unsigned int y, const unsigned int half_window_size) const
Compute the KLT response at a given pixel (x,y) - Only for grayscale images (for efficiency it avoids...
#define MRPT_UNUSED_PARAM(a)
Can be used to avoid "not used parameters" warnings from the compiler.
This CStream derived class allow using a memory buffer as a CStream.
#define MRPT_THROW_UNKNOWN_SERIALIZATION_VERSION(__V)
For use in CSerializable implementations.
void image_KLT_response_template(const uint8_t *in, const int widthStep, int x, int y, int32_t &_gxx, int32_t &_gyy, int32_t &_gxy)
IplImage * ipl_to_grayscale(const IplImage *img_src)
virtual void selectTextFont(const std::string &fontName)
Select the current font used when drawing text.
CImage grayscale() const
Returns a grayscale version of the image, or itself if it is already a grayscale image.
void scaleImage(unsigned int width, unsigned int height, TInterpolationMethod interp=IMG_INTERP_CUBIC)
Scales this image to a new size, interpolating as needed.
size_t getHeight() const override
Returns the height of the image in pixels.
void releaseIpl(bool thisIsExternalImgUnload=false) noexcept
Release the internal IPL image, if not nullptr or read-only.
std::string format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
void setChannelsOrder_RGB()
Marks the channel ordering in a color image as "RGB" (this doesn't actually modify the image data...
#define IMPLEMENTS_MEXPLUS_FROM(complete_type)
size_t getRowStride() const
Returns the row stride of the image: this is the number of bytes between two consecutive rows...
void saveToStreamAsJPEG(mrpt::utils::CStream &out, const int jpeg_quality=95) const
Save image to binary stream as a JPEG (.jpg) compressed format.
void swapRB()
Swaps red and blue channels.
void setFromIplImage(void *iplImage)
Reads the image from a OpenCV IplImage object (WITHOUT making a copy).
void changeSize(unsigned int width, unsigned int height, TImageChannels nChannels, bool originTopLeft)
Resize the buffers in "img" to accomodate a new image size and/or format.
bool loadFromXPM(const char **xpm_array, bool swap_rb=true)
Loads the image from an XPM array, as #include'd from a ".xpm" file.
void setFromIplImageReadOnly(void *iplImage)
Reads the image from a OpenCV IplImage object (WITHOUT making a copy) and from now on the image canno...
static void setImagesPathBase(const std::string &path)
GLsizei const GLchar ** string
void swap(CImage &o)
Very efficient swap of two images (just swap the internal pointers)
GLint GLint GLsizei GLsizei GLsizei GLint GLenum GLenum const GLvoid * pixels
mrpt::math::CMatrixDouble33 intrinsicParams
Matrix of intrinsic parameters (containing the focal length and principal point coordinates) ...
void setExternalStorage(const std::string &fileName) noexcept
By using this method the image is marked as referenced to an external file, which will be loaded only...
void idft2_complex(const CMatrixFloat &in_real, const CMatrixFloat &in_imag, CMatrixFloat &out_real, CMatrixFloat &out_imag)
Compute the 2D inverse Discrete Fourier Transform (DFT).
void image_SSE2_scale_half_1c8u(const uint8_t *in, uint8_t *out, int w, int h)
Subsample each 2x2 pixel block into 1x1 pixel, taking the first pixel & ignoring the other 3...
void copyFromForceLoad(const CImage &o)
Copies from another image, and, if that one is externally stored, the image file will be actually loa...
void setPixel(int x, int y, size_t color) override
Changes the value of the pixel (x,y).
void * getRawBufferData()
Method for getting a pointer to the raw stored data.
void filterMedianInPlace(int W=3)
Filter the image with a Median filter with a window size WxH, replacing "this" image by the filtered ...
TInterpolationMethod
Interpolation methods for images.
void setChannelsOrder_BGR()
Marks the channel ordering in a color image as "BGR" (this doesn't actually modify the image data...
void makeSureImageIsLoaded() const
Checks if the image is of type "external storage", and if so and not loaded yet, load it...
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
void update_patch(const CImage &patch, const unsigned int col, const unsigned int row)
Update a part of this image with the "patch" given as argument.
unsigned char * operator()(unsigned int col, unsigned int row, unsigned int channel=0) const
Returns a pointer to a given pixel information.
GLdouble GLdouble GLdouble r
CImage scaleHalfSmooth() const
Returns a new image scaled down to half its original size (averaging between every two rows) ...
mrpt::math::CArrayDouble< 5 > dist
[k1 k2 t1 t2 k3] -> k_i: parameters of radial distortion, t_i: parameters of tangential distortion (d...
virtual mxArray * writeToMatlab() const
Introduces a pure virtual method responsible for writing to a mxArray Matlab object, typically a MATLAB struct whose contents are documented in each derived class.
CImage scaleHalf() const
Returns a new image scaled down to half its original size.
void equalizeHist(CImage &outImg) const
Equalize the image histogram, saving the new image in the given output object.
void filterGaussianInPlace(int W=3, int H=3)
Filter the image with a Gaussian filter with a window size WxH, returning the filtered image in out_i...
GLenum GLenum GLvoid * row
CImage()
Default constructor: initialize an 1x1 RGB image.
void extract_patch(CImage &patch, const unsigned int col=0, const unsigned int row=0, const unsigned int width=1, const unsigned int height=1) const
Extract a patch from this image, saveing it into "patch" (its previous contents will be overwritten)...
bool drawChessboardCorners(std::vector< TPixelCoordf > &cornerCoords, unsigned int check_size_x, unsigned int check_size_y, unsigned int lines_width=1, unsigned int circles_radius=4)
Draw onto this image the detected corners of a chessboard.
bool isOriginTopLeft() const
Returns true if the coordinates origin is top-left, or false if it is bottom-left.
void changeSize(uint64_t newSize)
Change size.
A versatile "profiler" that logs the time spent within each pair of calls to enter(X)-leave(X), among other stats.
double leave(const char *func_name)
End of a named section.
A matrix of dynamic size.
static constexpr TColor blue()
int round(const T value)
Returns the closer integer (int) to x.
bool saveToFile(const std::string &fileName, int jpeg_quality=95) const
Save the image to a file, whose format is determined from the extension (internally uses OpenCV)...
static bool DISABLE_ZIP_COMPRESSION
By default, when storing images through the CSerializable interface, grayscale images will be ZIP com...
bool m_imgIsExternalStorage
Set to true only when using setExternalStorage.
bool isColor() const
Returns true if the image is RGB, false if it is grayscale.
void colorImage(CImage &ret) const
Returns a RGB version of the grayscale image, or itself if it is already a RGB image.
void compress(void *inData, size_t inDataSize, std::vector< unsigned char > &outData)
Compress an array of bytes into another one.
unsigned char * get_unsafe(unsigned int col, unsigned int row, unsigned int channel=0) const
Access to pixels without checking boundaries - Use normally the () operator better, which checks the coordinates.
void drawCircle(int x, int y, int radius, const mrpt::utils::TColor &color=mrpt::utils::TColor(255, 255, 255), unsigned int width=1) override
Draws a circle of a given radius.
bool isExternallyStored() const noexcept
See setExternalStorage().
uint64_t getTotalBytesCount() override
Returns the total size of the internal buffer.
char * strcpy(char *dest, size_t destSize, const char *source) noexcept
An OS-independent version of strcpy.
void decompress(void *inData, size_t inDataSize, std::vector< unsigned char > &outData, size_t outDataEstimatedSize)
Decompress an array of bytes into another one.
This class is a "CSerializable" wrapper for "CMatrixFloat".
TPenStyle
Definition of pen styles.
GLenum GLsizei GLsizei height
void dft2_complex(const CMatrixFloat &in_real, const CMatrixFloat &in_imag, CMatrixFloat &out_real, CMatrixFloat &out_imag)
Compute the 2D Discrete Fourier Transform (DFT) of a complex matrix, returning the real and imaginary...
void readFromStream(mrpt::utils::CStream &in, int version) override
Introduces a pure virtual method responsible for loading from a CStream This can not be used directly...
void setOriginTopLeft(bool val)
Changes the property of the image stating if the top-left corner (vs.
unsigned __int32 uint32_t
void enter(const char *func_name)
Start of a named section.
static const std::string & getImagesPathBase()
By default, ".".
#define ASSERTMSG_(f, __ERROR_MSG)
GLsizei GLsizei GLenum GLenum const GLvoid * data
Used in mrpt::utils::CImage.
void line(int x0, int y0, int x1, int y1, const mrpt::utils::TColor color, unsigned int width=1, TPenStyle penStyle=psSolid) override
Draws a line.
void * img
The internal IplImage pointer to the actual image content.
void getExternalStorageFileAbsolutePath(std::string &out_path) const
Only if isExternallyStored() returns true.
void grayscaleInPlace()
Replaces the image with a grayscale version of it.
void joinImagesHorz(const CImage &im1, const CImage &im2)
Joins two images side-by-side horizontally.
void filterGaussian(CImage &out_img, int W=3, int H=3) const
Filter the image with a Gaussian filter with a window size WxH, replacing "this" image by the filtere...
TImageSize getSize() const
Return the size of the image.
struct mxArray_tag mxArray
Forward declaration for mxArray (avoid #including as much as possible to speed up compiling) ...
Structure to hold the parameters of a pinhole camera model.
void getAsRGBMatrices(mrpt::math::CMatrixFloat &outMatrixR, mrpt::math::CMatrixFloat &outMatrixG, mrpt::math::CMatrixFloat &outMatrixB, bool doResize=true, int x_min=0, int y_min=0, int x_max=-1, int y_max=-1) const
Returns the image as RGB matrices with pixel values in the range [0,1].
void memcpy(void *dest, size_t destSize, const void *src, size_t copyCount) noexcept
An OS and compiler independent version of "memcpy".
std::string getExternalStorageFileAbsolutePath() const
Only if isExternallyStored() returns true.
void loadFromStreamAsJPEG(CStream &in)
Reads the image from a binary stream containing a binary jpeg file.