29 #include <mrpt/otherlibs/do_opencv_includes.h> 32 #include <mexplus/mxarray.h> 60 #define IMAGE_ALLOC_PERFLOG 0 62 #if IMAGE_ALLOC_PERFLOG 72 :
img(nullptr), m_imgIsReadOnly(false), m_imgIsExternalStorage(false)
82 :
img(nullptr), m_imgIsReadOnly(false), m_imgIsExternalStorage(false)
95 :
img(nullptr), m_imgIsReadOnly(false), m_imgIsExternalStorage(false)
108 if (
this == &o)
return *
this;
118 "Source image in = operator has nullptr IplImage*");
119 img = cvCloneImage((IplImage*)o.
img);
156 "Error loading externally-stored image from: %s",
171 if (
this == &o)
return;
203 :
img(nullptr), m_imgIsReadOnly(false), m_imgIsExternalStorage(false)
211 img = cvCloneImage((IplImage*)iplImage);
235 IplImage* ipl =
static_cast<IplImage*
>(
img);
236 if (static_cast<unsigned int>(ipl->width) ==
width &&
237 static_cast<unsigned int>(ipl->height) ==
height &&
238 ipl->nChannels == nChannels &&
239 ipl->origin == (originTopLeft ? 0 : 1))
249 #if IMAGE_ALLOC_PERFLOG 251 alloc_tims.enter(sLog.c_str());
254 img = cvCreateImage(cvSize(
width,
height), IPL_DEPTH_8U, nChannels);
255 ((IplImage*)
img)->origin = originTopLeft ? 0 : 1;
257 #if IMAGE_ALLOC_PERFLOG 258 alloc_tims.leave(sLog.c_str());
262 THROW_EXCEPTION(
"The MRPT has been compiled with MRPT_HAS_OPENCV=0 !");
276 IplImage* newImg = cvLoadImage(fileName.c_str(),
isColor);
277 if (newImg !=
nullptr)
288 THROW_EXCEPTION(
"The MRPT has been compiled with MRPT_HAS_OPENCV=0 !");
303 #if MRPT_OPENCV_VERSION_NUM > 0x110 305 p[0] = CV_IMWRITE_JPEG_QUALITY;
308 return (0 != cvSaveImage(fileName.c_str(),
img,
p));
310 return (0 != cvSaveImage(fileName.c_str(),
img));
313 THROW_EXCEPTION(
"The MRPT has been compiled with MRPT_HAS_OPENCV=0 !");
329 img = cvCloneImage((IplImage*)iplImage);
331 THROW_EXCEPTION(
"The MRPT has been compiled with MRPT_HAS_OPENCV=0 !");
346 ASSERTMSG_(iplImage != this->
img,
"Trying to assign read-only to itself.");
348 img = (IplImage*)iplImage;
352 THROW_EXCEPTION(
"The MRPT has been compiled with MRPT_HAS_OPENCV=0 !");
371 img = (IplImage*)iplImage;
373 THROW_EXCEPTION(
"The MRPT has been compiled with MRPT_HAS_OPENCV=0 !");
387 unsigned char* rawpixels,
bool swapRedBlue)
396 if (
color && swapRedBlue)
399 unsigned char* ptr_src = rawpixels;
400 unsigned char* ptr_dest =
401 reinterpret_cast<unsigned char*
>(((IplImage*)
img)->imageData);
402 const int bytes_per_row_out = ((IplImage*)
img)->widthStep;
404 for (
int h =
height; h--;)
406 for (
unsigned int i = 0; i <
width;
407 i++, ptr_src += 3, ptr_dest += 3)
409 unsigned char t0 = ptr_src[0], t1 = ptr_src[1], t2 = ptr_src[2];
414 ptr_dest += bytes_per_row_out -
width * 3;
419 if (((IplImage*)
img)->widthStep ==
420 ((IplImage*)
img)->
width * ((IplImage*)
img)->nChannels)
424 ((IplImage*)
img)->imageData, rawpixels,
430 unsigned char* ptr_src = rawpixels;
431 unsigned char* ptr_dest =
432 reinterpret_cast<unsigned char*
>(((IplImage*)
img)->imageData);
434 int bytes_per_row_out = ((IplImage*)
img)->widthStep;
435 for (
unsigned int y = 0;
y <
height;
y++)
437 memcpy(ptr_dest, ptr_src, bytes_per_row);
438 ptr_src += bytes_per_row;
439 ptr_dest += bytes_per_row_out;
444 THROW_EXCEPTION(
"The MRPT has been compiled with MRPT_HAS_OPENCV=0 !");
453 unsigned int col,
unsigned int row,
unsigned int channel)
const 457 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG) 462 IplImage* ipl = ((IplImage*)
img);
464 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG) 466 if (
row >= (
unsigned int)ipl->height || col >= (
unsigned int)ipl->width ||
467 channel >= (
unsigned int)ipl->nChannels)
471 "Pixel coordinates/channel out of bounds: row=%u/%u col=%u/%u " 473 row, ipl->height, col, ipl->width, channel, ipl->nChannels));
477 return (
unsigned char*)&ipl
478 ->imageData[
row * ipl->widthStep + col * ipl->nChannels + channel];
479 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG) 492 unsigned int col,
unsigned int row,
unsigned int channel)
const 496 IplImage* ipl = ((IplImage*)
img);
497 return (
unsigned char*)&ipl
498 ->imageData[
row * ipl->widthStep + col * ipl->nChannels + channel];
531 const bool hasColor =
isColor();
549 bool imageStoredAsZip =
552 out << imageStoredAsZip;
555 if (imageStoredAsZip)
557 std::vector<unsigned char> tempBuf;
559 ((IplImage*)
img)->imageData,
573 ((IplImage*)
img)->imageData,
612 out << neg_width << neg_height;
615 const IplImage* ipl =
static_cast<const IplImage*
>(
img);
616 const size_t bytes_per_row = ipl->width * 3;
619 &ipl->imageData[0], bytes_per_row * ipl->height);
638 "[CImage] Cannot deserialize image since MRPT has been " 639 "compiled without OpenCV");
658 in >>
width >>
height >> nChannels >> originTopLeft >> imgLength;
661 in.ReadBuffer(((IplImage*)
img)->imageData, imgLength);
722 bool imageIsZIP =
true;
726 if (version == 4 &&
imageSize <= 16 * 1024)
742 size_t outDataActualSize;
744 in, zipDataLen, ((IplImage*)
img)->imageData,
745 outDataBufferSize, outDataActualSize);
746 ASSERT_(outDataActualSize == outDataBufferSize);
748 MRPT_TODO(
"Implement deserialization case:");
756 ((IplImage*)
img)->imageData,
763 bool loadJPEG =
true;
786 const IplImage* ipl =
787 static_cast<const IplImage*
>(
img);
788 const size_t bytes_per_row = ipl->width * 3;
789 for (
int y = 0;
y < ipl->height;
y++)
791 const size_t nRead =
in.ReadBuffer(
792 &ipl->imageData[
y * ipl->widthStep],
794 if (nRead != bytes_per_row)
796 "Error: Truncated data stream " 797 "while parsing raw image?")
841 cv::Mat cvImg = cv::cvarrToMat(this->getAs<IplImage>());
842 return mexplus::from(cvImg);
856 s.x = ((IplImage*)
img)->width;
857 s.y = ((IplImage*)
img)->height;
869 return ((IplImage*)
img)->width;
883 return ((IplImage*)
img)->widthStep;
897 return ((IplImage*)
img)->height;
911 return ((IplImage*)
img)->nChannels > 1;
925 return static_cast<unsigned int>(((IplImage*)
img)->nChannels);
939 return ((IplImage*)
img)->origin == 0;
949 unsigned int col,
unsigned int row,
unsigned int channel)
const 953 return (*(*
this)(col,
row, channel)) / 255.0f;
965 unsigned char*
pixels = (*this)(col,
row, 0);
972 return (*(*
this)(col,
row, 0 )) / 255.0f;
985 for (
x = 0;
x < cx;
x++)
1005 IplImage* img_dest =
1006 cvCreateImage(cvSize(img_src->width, img_src->height), IPL_DEPTH_8U, 1);
1007 img_dest->origin = img_src->origin;
1011 if (is_aligned<16>(img_src->imageData) && (img_src->width & 0xF) == 0 &&
1012 img_src->widthStep == img_src->width * img_src->nChannels &&
1013 img_dest->widthStep == img_dest->width * img_dest->nChannels)
1015 ASSERT_(is_aligned<16>(img_dest->imageData));
1017 (
const uint8_t*)img_src->imageData, (
uint8_t*)img_dest->imageData,
1018 img_src->width, img_src->height);
1024 cvCvtColor(img_src, img_dest, CV_BGR2GRAY);
1037 const IplImage* ipl = this->getAs<const IplImage>();
1039 if (ipl->nChannels == 1)
1059 const IplImage* ipl = this->getAs<const IplImage>();
1061 if (ipl->nChannels == 1)
return;
1076 const IplImage* img_src = ((IplImage*)
img);
1077 const int w = img_src->width;
1078 const int h = img_src->height;
1081 IplImage* img_dest =
1082 cvCreateImage(cvSize(
w >> 1, h >> 1), IPL_DEPTH_8U, img_src->nChannels);
1083 img_dest->origin = img_src->origin;
1084 memcpy(img_dest->colorModel, img_src->colorModel, 4);
1085 memcpy(img_dest->channelSeq, img_src->channelSeq, 4);
1086 img_dest->dataOrder = img_src->dataOrder;
1090 if (img_src->nChannels == 3 && is_aligned<16>(img_src->imageData) &&
1091 is_aligned<16>(img_dest->imageData) && (
w & 0xF) == 0 &&
1092 img_src->widthStep == img_src->width * img_src->nChannels &&
1093 img_dest->widthStep == img_dest->width * img_dest->nChannels)
1096 (
const uint8_t*)img_src->imageData, (
uint8_t*)img_dest->imageData,
1104 if (img_src->nChannels == 1 && is_aligned<16>(img_src->imageData) &&
1105 is_aligned<16>(img_dest->imageData) && (
w & 0xF) == 0 &&
1106 img_src->widthStep == img_src->width * img_src->nChannels &&
1107 img_dest->widthStep == img_dest->width * img_dest->nChannels)
1110 (
const uint8_t*)img_src->imageData, (
uint8_t*)img_dest->imageData,
1133 const IplImage* img_src = ((IplImage*)
img);
1134 const int w = img_src->width;
1135 const int h = img_src->height;
1138 IplImage* img_dest =
1139 cvCreateImage(cvSize(
w >> 1, h >> 1), IPL_DEPTH_8U, img_src->nChannels);
1140 img_dest->origin = img_src->origin;
1141 memcpy(img_dest->colorModel, img_src->colorModel, 4);
1142 memcpy(img_dest->channelSeq, img_src->channelSeq, 4);
1143 img_dest->dataOrder = img_src->dataOrder;
1147 if (img_src->nChannels == 1 && is_aligned<16>(img_src->imageData) &&
1148 is_aligned<16>(img_dest->imageData) && (
w & 0xF) == 0 &&
1149 img_src->widthStep == img_src->width * img_src->nChannels &&
1150 img_dest->widthStep == img_dest->width * img_dest->nChannels)
1153 (
const uint8_t*)img_src->imageData, (
uint8_t*)img_dest->imageData,
1185 return ((IplImage*)
img)->channelSeq;
1195 unsigned int width,
unsigned int height,
unsigned int bytesPerRow,
1196 unsigned char*
red,
unsigned char*
green,
unsigned char*
blue)
1205 for (
unsigned int y = 0;
y <
height;
y++)
1208 unsigned char* dest = (
unsigned char*)((IplImage*)
img)->imageData +
1209 ((IplImage*)
img)->widthStep *
y;
1212 unsigned char* srcR =
red + bytesPerRow *
y;
1213 unsigned char* srcG =
green + bytesPerRow *
y;
1214 unsigned char* srcB =
blue + bytesPerRow *
y;
1216 for (
unsigned int x = 0;
x <
width;
x++)
1218 *(dest++) = *(srcB++);
1219 *(dest++) = *(srcG++);
1220 *(dest++) = *(srcR++);
1236 ((IplImage*)
img)->origin =
val ? 0 : 1;
1247 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG) 1253 IplImage* ipl = ((IplImage*)
img);
1255 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG) 1262 if (ipl->nChannels == 1)
1264 *((
unsigned char*)&ipl->imageData[
y * ipl->widthStep +
x]) =
1265 (
unsigned char)
color;
1269 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG) 1271 if (ipl->dataOrder != 0)
1273 "Please, use interleaved images like normal people!!! :-)");
1275 unsigned char* dest =
1276 (
unsigned char*)&ipl->imageData[
y * ipl->widthStep + 3 *
x];
1277 unsigned char*
src = (
unsigned char*)&
color;
1286 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG) 1303 IplImage* ipl = ((IplImage*)
img);
1307 ipl, cvPoint(x0, y0), cvPoint(x1, y1),
1321 IplImage* ipl = ((IplImage*)
img);
1333 const CImage& patch,
const unsigned int col_,
const unsigned int row_)
1336 IplImage* ipl_int = ((IplImage*)
img);
1337 IplImage* ipl_ext = ((IplImage*)patch.
img);
1341 if (row_ + ipl_ext->height >
getHeight() ||
1342 col_ + ipl_ext->width >
getWidth())
1346 for (
unsigned int i = 0; i < patch.
getHeight(); i++)
1349 &ipl_int->imageData[(i + row_) * ipl_int->widthStep +
1350 col_ * ipl_int->nChannels],
1351 &ipl_ext->imageData[i * ipl_ext->widthStep], ipl_ext->widthStep);
1360 CImage& patch,
const unsigned int col_,
const unsigned int row_,
1361 const unsigned int col_num,
const unsigned int row_num)
const 1366 IplImage* ipl_int = ((IplImage*)
img);
1369 if ((ipl_int->width < (
int)(col_ + col_num)) ||
1370 (ipl_int->height < (
int)(row_ + row_num)))
1374 "Trying to extract patch out of image boundaries: Image " 1375 "size=%ix%i, Patch size=%ux%u, extraction location=(%u,%u)",
1376 ipl_int->width, ipl_int->height, col_num, row_num, col_, row_))
1379 patch.
resize(col_num, row_num, ((IplImage*)
img)->nChannels,
true);
1380 IplImage* ipl_ext = ((IplImage*)patch.
img);
1383 for (
unsigned int i = 0; i < row_num; i++)
1386 &ipl_ext->imageData[i * ipl_ext->widthStep],
1387 &ipl_int->imageData[(i + row_) * ipl_int->widthStep +
1388 col_ * ipl_int->nChannels],
1389 ipl_ext->widthStep);
1399 const CImage& img2,
int width_init,
int height_init)
const 1406 THROW_EXCEPTION(
"Correlation Error!, image to correlate out of bounds");
1410 float syy = 0.0f, sxy = 0.0f, sxx = 0.0f, m1 = 0.0f, m2 = 0.0f,
1418 for (j = 0; j < img2.
getWidth(); j++)
1433 for (j = 0; j < img2.
getWidth(); j++)
1435 x1 = *(*this)(j + width_init, i + height_init) -
1445 return sxy / sqrt(sxx * syy);
1455 const CImage& patch_img,
size_t& x_max,
size_t& y_max,
double& max_val,
1456 int x_search_ini,
int y_search_ini,
int x_search_size,
int y_search_size,
1457 CImage* out_corr_image)
const 1465 CvPoint min_point, max_point;
1468 (x_search_ini < 0 || y_search_ini < 0 || x_search_size < 0 ||
1471 const IplImage *im, *patch_im;
1475 const IplImage* im_ = this->getAs<IplImage>();
1476 const IplImage* patch_im_ = patch_img.
getAs<IplImage>();
1478 IplImage* aux = cvCreateImage(cvGetSize(im_), 8, 1);
1479 IplImage* aux2 = cvCreateImage(cvGetSize(patch_im_), 8, 1);
1480 cvCvtColor(im_, aux, CV_BGR2GRAY);
1481 cvCvtColor(patch_im_, aux2, CV_BGR2GRAY);
1487 im = this->getAs<IplImage>();
1488 patch_im = patch_img.
getAs<IplImage>();
1493 x_search_size = im->width - patch_im->width;
1494 y_search_size = im->height - patch_im->height;
1498 if ((x_search_ini + x_search_size + patch_im->width - 1) > im->width)
1500 (x_search_ini + x_search_size + patch_im->width - 1) - im->width;
1502 if ((y_search_ini + y_search_size + patch_im->height - 1) > im->height)
1504 (y_search_ini + y_search_size + patch_im->height - 1) - im->height;
1506 ASSERT_((x_search_ini + x_search_size + patch_im->width - 1) <= im->width);
1508 (y_search_ini + y_search_size + patch_im->height - 1) <= im->height);
1509 IplImage* result = cvCreateImage(
1510 cvSize(x_search_size + 1, y_search_size + 1), IPL_DEPTH_32F, 1);
1512 const IplImage* ipl_ext;
1516 IplImage* aux = cvCreateImage(
1518 patch_im->width + x_search_size,
1519 patch_im->height + y_search_size),
1521 for (
unsigned int i = 0; i < (
unsigned int)y_search_size; i++)
1524 &aux->imageData[i * aux->widthStep],
1525 &im->imageData[(i + y_search_ini) * im->widthStep +
1526 x_search_ini * im->nChannels],
1527 aux->width * aux->nChannels);
1540 cvMatchTemplate(ipl_ext, patch_im, result, CV_TM_CCORR_NORMED);
1544 cvMinMaxLoc(result, &mini, &max_val, &min_point, &max_point,
nullptr);
1545 x_max = max_point.x + x_search_ini + (
round(patch_im->width - 1) / 2);
1546 y_max = max_point.y + y_search_ini + (
round(patch_im->height - 1) / 2);
1551 IplImage* aux =
const_cast<IplImage*
>(ipl_ext);
1552 cvReleaseImage(&aux);
1560 cvReleaseImage(&result);
1562 THROW_EXCEPTION(
"The MRPT has been compiled with MRPT_HAS_OPENCV=0 !");
1575 IplImage* ipl = getAs<IplImage>();
1578 ipl->nChannels == 1,
1579 "CImage::normalize() only defined for grayscale images.");
1582 for (
int y = 0;
y < ipl->height;
y++)
1585 ipl->imageData +
y * ipl->widthStep);
1586 for (
int x = 0;
x < ipl->width;
x++)
1589 if (min_ >
val) min_ =
val;
1590 if (max_ <
val) max_ =
val;
1595 const double s = 255.0 / ((double)max_ - (
double)min_);
1600 for (
int y = 0;
y < ipl->height;
y++)
1603 reinterpret_cast<uint8_t*
>(ipl->imageData +
y * ipl->widthStep);
1604 for (
int x = 0;
x < ipl->width;
x++)
1617 CMatrixFloat& outMatrix,
bool doResize,
int x_min,
int y_min,
int x_max,
1627 if (x_max == -1) x_max = ((IplImage*)
img)->width - 1;
1628 if (y_max == -1) y_max = ((IplImage*)
img)->height - 1;
1630 ASSERT_(x_min >= 0 && x_min < ((IplImage*)
img)->
width && x_min < x_max);
1633 int lx = (x_max - x_min + 1);
1634 int ly = (y_max - y_min + 1);
1636 if (doResize || (
int)outMatrix.rows() < ly || (int)outMatrix.cols() < lx)
1637 outMatrix.setSize(y_max - y_min + 1, x_max - x_min + 1);
1642 for (
int y = 0;
y < ly;
y++)
1646 for (
int x = 0;
x < lx;
x++)
1648 aux = *
pixels++ * 0.3f * (1.0f / 255);
1649 aux += *
pixels++ * 0.59f * (1.0f / 255);
1650 aux += *
pixels++ * 0.11f * (1.0f / 255);
1651 outMatrix.set_unsafe(
y,
x, aux);
1657 for (
int y = 0;
y < ly;
y++)
1660 for (
int x = 0;
x < lx;
x++)
1661 outMatrix.set_unsafe(
y,
x, (*
pixels++) * (1.0f / 255));
1675 int x_max,
int y_max)
const 1684 if (x_max == -1) x_max = ((IplImage*)
img)->width - 1;
1685 if (y_max == -1) y_max = ((IplImage*)
img)->height - 1;
1687 ASSERT_(x_min >= 0 && x_min < ((IplImage*)
img)->
width && x_min < x_max);
1690 int lx = (x_max - x_min + 1);
1691 int ly = (y_max - y_min + 1);
1693 if (doResize || (
int)outMatrixR.rows() < ly || (int)outMatrixR.cols() < lx)
1694 outMatrixR.setSize(y_max - y_min + 1, x_max - x_min + 1);
1695 if (doResize || (
int)outMatrixG.rows() < ly || (int)outMatrixG.cols() < lx)
1696 outMatrixG.setSize(y_max - y_min + 1, x_max - x_min + 1);
1697 if (doResize || (
int)outMatrixB.rows() < ly || (int)outMatrixB.cols() < lx)
1698 outMatrixB.setSize(y_max - y_min + 1, x_max - x_min + 1);
1702 for (
int y = 0;
y < ly;
y++)
1706 for (
int x = 0;
x < lx;
x++)
1708 aux = *
pixels++ * (1.0f / 255);
1709 outMatrixR.set_unsafe(
y,
x, aux);
1710 aux = *
pixels++ * (1.0f / 255);
1711 outMatrixG.set_unsafe(
y,
x, aux);
1712 aux = *
pixels++ * (1.0f / 255);
1713 outMatrixB.set_unsafe(
y,
x, aux);
1719 for (
int y = 0;
y < ly;
y++)
1722 for (
int x = 0;
x < lx;
x++)
1724 outMatrixR.set_unsafe(
y,
x, (*
pixels) * (1.0f / 255));
1725 outMatrixG.set_unsafe(
y,
x, (*
pixels) * (1.0f / 255));
1726 outMatrixB.set_unsafe(
y,
x, (*
pixels++) * (1.0f / 255));
1740 int v_search_ini,
int u_search_size,
int v_search_size,
float biasThisImg,
1741 float biasInImg)
const 1749 if (u_search_ini == -1) u_search_ini = 0;
1750 if (v_search_ini == -1) v_search_ini = 0;
1751 if (u_search_size == -1) u_search_size =
getWidth();
1752 if (v_search_size == -1) v_search_size =
getHeight();
1754 int u_search_end = u_search_ini + u_search_size - 1;
1755 int v_search_end = v_search_ini + v_search_size - 1;
1762 size_t actual_lx = max(u_search_size, (
int)in_img.
getWidth());
1763 size_t actual_ly = max(v_search_size, (
int)in_img.
getHeight());
1769 CMatrix i1(ly, lx), i2(ly, lx);
1775 i2.fill(biasThisImg);
1779 i2,
false, u_search_ini, v_search_ini, u_search_ini + u_search_size - 1,
1780 v_search_ini + v_search_size - 1);
1784 i2.array() -= biasThisImg;
1785 i1.array() -= biasInImg;
1791 CMatrix I1_R, I1_I, I2_R, I2_I, ZEROS(ly, lx);
1799 for (
y = 0;
y < ly;
y++)
1800 for (
x = 0;
x < lx;
x++)
1802 float r1 = I1_R.get_unsafe(
y,
x);
1803 float r2 = I2_R.get_unsafe(
y,
x);
1805 float ii1 = I1_I.get_unsafe(
y,
x);
1806 float ii2 = I2_I.get_unsafe(
y,
x);
1809 I2_R.set_unsafe(
y,
x, (r1 * r2 + ii1 * ii2) / den);
1810 I2_I.set_unsafe(
y,
x, (ii2 * r1 - r2 * ii1) / den);
1820 out_corr.setSize(actual_ly, actual_lx);
1821 for (
y = 0;
y < actual_ly;
y++)
1822 for (
x = 0;
x < actual_lx;
x++)
1840 size_t matrix_lx = outMatrix.cols();
1841 size_t matrix_ly = outMatrix.rows();
1846 for (
unsigned int y = 0;
y < matrix_ly;
y++)
1848 unsigned char* min_pixels =
1849 (*this)(0,
y % ((IplImage*)
img)->height, 0);
1850 unsigned char* max_pixels =
1851 min_pixels + ((IplImage*)
img)->width * 3;
1852 unsigned char*
pixels = min_pixels;
1854 for (
unsigned int x = 0;
x < matrix_lx;
x++)
1857 aux += *
pixels++ * 0.59f;
1858 aux += *
pixels++ * 0.11f;
1859 outMatrix.set_unsafe(
y,
x, aux);
1866 for (
unsigned int y = 0;
y < matrix_ly;
y++)
1868 unsigned char* min_pixels =
1869 (*this)(0,
y % ((IplImage*)
img)->height, 0);
1870 unsigned char* max_pixels = min_pixels + ((IplImage*)
img)->width;
1871 unsigned char*
pixels = min_pixels;
1872 for (
unsigned int x = 0;
x < matrix_lx;
x++)
1874 outMatrix.set_unsafe(
y,
x, *
pixels++);
1890 m_externalFile = fileName;
1891 m_imgIsExternalStorage =
true;
1910 if (
img && !m_imgIsReadOnly)
1912 IplImage* ptr = (IplImage*)
img;
1913 cvReleaseImage(&ptr);
1916 m_imgIsReadOnly =
false;
1917 if (!thisIsExternalImgUnload)
1919 m_imgIsExternalStorage =
false;
1920 m_externalFile =
string();
1930 if (
img !=
nullptr)
return;
1950 "Error loading externally-stored image from: %s",
1987 IplImage* ptr = (IplImage*)
img;
1988 int options = CV_CVTIMG_FLIP;
1989 if (also_swapRB) options |= CV_CVTIMG_SWAP_RB;
1990 cvConvertImage(ptr, ptr, options);
1997 IplImage* ptr = (IplImage*)
img;
1998 cvFlip(ptr,
nullptr, 1);
2010 IplImage* ptr = (IplImage*)
img;
2011 cvConvertImage(ptr, ptr, CV_CVTIMG_SWAP_RB);
2024 #if MRPT_OPENCV_VERSION_NUM < 0x200 2028 IplImage* srcImg = getAs<IplImage>();
2030 cvCreateImage(cvGetSize(srcImg), srcImg->depth, srcImg->nChannels);
2032 cv::Mat *_mapX, *_mapY;
2033 _mapX =
static_cast<cv::Mat*
>(mapX);
2034 _mapY =
static_cast<cv::Mat*
>(mapY);
2036 IplImage _mapXX = *_mapX;
2037 IplImage _mapYY = *_mapY;
2039 cvRemap(srcImg, outImg, &_mapXX, &_mapYY, CV_INTER_CUBIC);
2056 IplImage* srcImg = getAs<IplImage>();
2058 outImg = cvCreateImage(cvGetSize(srcImg), srcImg->depth, srcImg->nChannels);
2060 double aux1[3][3], aux2[1][5];
2063 for (
int i = 0; i < 3; i++)
2064 for (
int j = 0; j < 3; j++) aux1[i][j] = cameraMatrix(i, j);
2065 for (
int i = 0; i < 5; i++) aux2[0][i] = cameraParams.
dist[i];
2067 CvMat inMat = cvMat(cameraMatrix.rows(), cameraMatrix.cols(), CV_64F, aux1);
2068 CvMat distM = cvMat(1, 5, CV_64F, aux2);
2071 cvUndistort2(srcImg, outImg, &inMat, &distM);
2089 const IplImage* srcImg = getAs<IplImage>();
2091 outImg = cvCreateImage(cvGetSize(srcImg), srcImg->depth, srcImg->nChannels);
2093 double aux1[3][3], aux2[1][5];
2096 for (
int i = 0; i < 3; i++)
2097 for (
int j = 0; j < 3; j++) aux1[i][j] = cameraMatrix(i, j);
2098 for (
int i = 0; i < 5; i++) aux2[0][i] = cameraParams.
dist[i];
2100 CvMat inMat = cvMat(cameraMatrix.rows(), cameraMatrix.cols(), CV_64F, aux1);
2101 CvMat distM = cvMat(1, 5, CV_64F, aux2);
2104 cvUndistort2(srcImg, outImg, &inMat, &distM);
2110 cvReleaseImage(&outImg);
2123 const IplImage* srcImg = getAs<IplImage>();
2125 outImg = cvCreateImage(cvGetSize(srcImg), srcImg->depth, srcImg->nChannels);
2128 cvSmooth(srcImg, outImg, CV_MEDIAN, W);
2130 outImg->origin = srcImg->origin;
2136 cvReleaseImage(&outImg);
2149 IplImage* srcImg = getAs<IplImage>();
2151 outImg = cvCreateImage(cvGetSize(srcImg), srcImg->depth, srcImg->nChannels);
2154 cvSmooth(srcImg, outImg, CV_MEDIAN, W);
2156 outImg->origin = srcImg->origin;
2173 const IplImage* srcImg = getAs<IplImage>();
2175 outImg = cvCreateImage(cvGetSize(srcImg), srcImg->depth, srcImg->nChannels);
2178 cvSmooth(srcImg, outImg, CV_GAUSSIAN, W, H);
2180 outImg->origin = srcImg->origin;
2186 cvReleaseImage(&outImg);
2199 IplImage* srcImg = getAs<IplImage>();
2201 outImg = cvCreateImage(cvGetSize(srcImg), srcImg->depth, srcImg->nChannels);
2204 cvSmooth(srcImg, outImg, CV_GAUSSIAN, W, H);
2206 outImg->origin = srcImg->origin;
2223 IplImage* srcImg = getAs<IplImage>();
2225 if (static_cast<unsigned int>(srcImg->width) ==
width &&
2226 static_cast<unsigned int>(srcImg->height) ==
height)
2231 cvCreateImage(cvSize(
width,
height), srcImg->depth, srcImg->nChannels);
2234 cvResize(srcImg, outImg, (
int)
interp);
2236 outImg->origin = srcImg->origin;
2254 const IplImage* srcImg = getAs<IplImage>();
2256 if (static_cast<unsigned int>(srcImg->width) ==
width &&
2257 static_cast<unsigned int>(srcImg->height) ==
height)
2266 cvCreateImage(cvSize(
width,
height), srcImg->depth, srcImg->nChannels);
2269 cvResize(srcImg, outImg, (
int)
interp);
2270 outImg->origin = srcImg->origin;
2281 double angle_radians,
unsigned int center_x,
unsigned int center_y,
2288 IplImage* srcImg = getAs<IplImage>();
2290 outImg = cvCreateImage(cvGetSize(srcImg), srcImg->depth, srcImg->nChannels);
2297 CvMat M = cvMat(2, 3, CV_32F, m);
2299 m[0] = (float)(
scale * cos(angle_radians));
2300 m[1] = (float)(
scale * sin(angle_radians));
2306 cvGetQuadrangleSubPix(srcImg, outImg, &M);
2308 outImg->origin = srcImg->origin;
2328 std::vector<TPixelCoordf>& cornerCoords,
unsigned int check_size_x,
2329 unsigned int check_size_y,
unsigned int lines_width,
unsigned int r)
2333 if (cornerCoords.size() != check_size_x * check_size_y)
return false;
2335 IplImage* ipl = this->getAs<IplImage>();
2337 unsigned int x,
y, i;
2338 CvPoint prev_pt = cvPoint(0, 0);
2339 const int line_max = 8;
2340 CvScalar line_colors[8];
2342 line_colors[0] = CV_RGB(255, 0, 0);
2343 line_colors[1] = CV_RGB(255, 128, 0);
2344 line_colors[2] = CV_RGB(255, 128, 0);
2345 line_colors[3] = CV_RGB(200, 200, 0);
2346 line_colors[4] = CV_RGB(0, 255, 0);
2347 line_colors[5] = CV_RGB(0, 200, 200);
2348 line_colors[6] = CV_RGB(0, 0, 255);
2349 line_colors[7] = CV_RGB(255, 0, 255);
2353 for (
y = 0, i = 0;
y < check_size_y;
y++)
2355 CvScalar
color = line_colors[
y % line_max];
2356 for (
x = 0;
x < check_size_x;
x++, i++)
2359 pt.x = cvRound(cornerCoords[i].
x);
2360 pt.y = cvRound(cornerCoords[i].
y);
2362 if (i != 0) cvLine(ipl, prev_pt, pt,
color, lines_width);
2365 ipl, cvPoint(pt.x -
r, pt.y -
r), cvPoint(pt.x +
r, pt.y +
r),
2366 color, lines_width);
2368 ipl, cvPoint(pt.x -
r, pt.y +
r), cvPoint(pt.x +
r, pt.y -
r),
2369 color, lines_width);
2371 if (
r > 0) cvCircle(ipl, pt,
r + 1,
color);
2375 if (i == 0 || i == cornerCoords.size() - 1)
2400 const IplImage* srcImg = getAs<IplImage>();
2401 IplImage* outImg = cvCreateImage(cvGetSize(srcImg), srcImg->depth, 3);
2403 cvCvtColor(srcImg, outImg, CV_GRAY2BGR);
2405 outImg->origin = srcImg->origin;
2420 IplImage* srcImg = getAs<IplImage>();
2422 outImg = cvCreateImage(cvGetSize(srcImg), srcImg->depth, 3);
2424 cvCvtColor(srcImg, outImg, CV_GRAY2BGR);
2426 outImg->origin = srcImg->origin;
2442 const IplImage* _im1 = im1.
getAs<IplImage>();
2443 const IplImage* _im2 = im2.
getAs<IplImage>();
2445 ASSERT_(_im1->depth == _im2->depth && _im1->nChannels == _im2->nChannels);
2447 IplImage* out = cvCreateImage(
2448 cvSize(_im1->width + _im2->width, _im1->height), _im1->depth,
2451 cvSetImageROI(out, cvRect(0, 0, _im1->width, _im1->height));
2453 cvSetImageROI(out, cvRect(_im1->width, 0, _im2->width, _im2->height));
2455 cvSetImageROI(out, cvRect(0, 0, out->width, out->height));
2458 if ((
int)_im1->nChannels != (
int)this->getChannelCount())
2463 out2 = cvCreateImage(
2464 cvSize(_im1->width + _im2->width, _im1->height), _im1->depth,
2465 this->getChannelCount());
2466 cvCvtColor(out, out2, CV_GRAY2BGR);
2482 const IplImage* srcImg = getAs<IplImage>();
2486 if (srcImg->nChannels == 1)
2488 cvEqualizeHist(srcImg, outImg.
getAs<IplImage>());
2492 IplImage* hsv = cvCreateImage(cvGetSize(srcImg), 8, 3);
2493 IplImage* h = cvCreateImage(cvGetSize(srcImg), 8, 1);
2494 IplImage*
s = cvCreateImage(cvGetSize(srcImg), 8, 1);
2495 IplImage*
v = cvCreateImage(cvGetSize(srcImg), 8, 1);
2497 cvCvtColor(srcImg, hsv, CV_BGR2HSV);
2498 cvSplit(hsv, h,
s,
v,
nullptr);
2500 cvEqualizeHist(
v,
v);
2502 cvMerge(h,
s,
v,
nullptr, hsv);
2503 cvCvtColor(hsv, outImg.
getAs<IplImage>(), CV_HSV2BGR);
2505 cvReleaseImage(&hsv);
2521 IplImage* srcImg = getAs<IplImage>();
2525 cvCreateImage(cvGetSize(srcImg), srcImg->depth, srcImg->nChannels);
2526 outImg->origin = srcImg->origin;
2528 if (srcImg->nChannels == 1)
2530 cvEqualizeHist(srcImg, outImg);
2534 IplImage* hsv = cvCreateImage(cvGetSize(srcImg), 8, 3);
2535 IplImage* h = cvCreateImage(cvGetSize(srcImg), 8, 1);
2536 IplImage*
s = cvCreateImage(cvGetSize(srcImg), 8, 1);
2537 IplImage*
v = cvCreateImage(cvGetSize(srcImg), 8, 1);
2539 cvCvtColor(srcImg, hsv, CV_BGR2HSV);
2540 cvSplit(hsv, h,
s,
v,
nullptr);
2542 cvEqualizeHist(
v,
v);
2544 cvMerge(h,
s,
v,
nullptr, hsv);
2545 cvCvtColor(hsv, outImg, CV_HSV2BGR);
2547 cvReleaseImage(&hsv);
2560 template <
unsigned int HALF_WIN_SIZE>
2565 const unsigned int min_x =
x - HALF_WIN_SIZE;
2566 const unsigned int min_y =
y - HALF_WIN_SIZE;
2572 const unsigned int WIN_SIZE = 1 + 2 * HALF_WIN_SIZE;
2574 unsigned int yy = min_y;
2575 for (
unsigned int iy = WIN_SIZE; iy; --iy, ++yy)
2577 const uint8_t* ptr =
in + widthStep * yy + min_x;
2578 unsigned int xx = min_x;
2579 for (
unsigned int ix = WIN_SIZE; ix; --ix, ++xx)
2581 const int32_t dx = ptr[+1] - ptr[-1];
2582 const int32_t dy = ptr[+widthStep] - ptr[-widthStep];
2594 const unsigned int x,
const unsigned int y,
2595 const unsigned int half_window_size)
const 2598 const IplImage* srcImg = this->getAs<IplImage>();
2601 srcImg->nChannels == 1,
2602 "KLT_response only works with grayscale images.");
2604 const unsigned int img_w = srcImg->width;
2605 const unsigned int img_h = srcImg->height;
2606 const int widthStep = srcImg->widthStep;
2609 const unsigned int min_x =
x - half_window_size;
2610 const unsigned int max_x =
x + half_window_size;
2611 const unsigned int min_y =
y - half_window_size;
2612 const unsigned int max_y =
y + half_window_size;
2616 min_x < img_w && max_x < img_w && min_y < img_h && max_y < img_h,
2617 "Window is out of image bounds");
2627 switch (half_window_size)
2630 image_KLT_response_template<2>(
2631 img_data, widthStep,
x,
y, gxx, gyy, gxy);
2634 image_KLT_response_template<3>(
2635 img_data, widthStep,
x,
y, gxx, gyy, gxy);
2638 image_KLT_response_template<4>(
2639 img_data, widthStep,
x,
y, gxx, gyy, gxy);
2642 image_KLT_response_template<5>(
2643 img_data, widthStep,
x,
y, gxx, gyy, gxy);
2646 image_KLT_response_template<6>(
2647 img_data, widthStep,
x,
y, gxx, gyy, gxy);
2650 image_KLT_response_template<7>(
2651 img_data, widthStep,
x,
y, gxx, gyy, gxy);
2654 image_KLT_response_template<8>(
2655 img_data, widthStep,
x,
y, gxx, gyy, gxy);
2658 image_KLT_response_template<9>(
2659 img_data, widthStep,
x,
y, gxx, gyy, gxy);
2662 image_KLT_response_template<10>(
2663 img_data, widthStep,
x,
y, gxx, gyy, gxy);
2666 image_KLT_response_template<11>(
2667 img_data, widthStep,
x,
y, gxx, gyy, gxy);
2670 image_KLT_response_template<12>(
2671 img_data, widthStep,
x,
y, gxx, gyy, gxy);
2674 image_KLT_response_template<13>(
2675 img_data, widthStep,
x,
y, gxx, gyy, gxy);
2678 image_KLT_response_template<14>(
2679 img_data, widthStep,
x,
y, gxx, gyy, gxy);
2682 image_KLT_response_template<15>(
2683 img_data, widthStep,
x,
y, gxx, gyy, gxy);
2686 image_KLT_response_template<16>(
2687 img_data, widthStep,
x,
y, gxx, gyy, gxy);
2690 image_KLT_response_template<32>(
2691 img_data, widthStep,
x,
y, gxx, gyy, gxy);
2695 for (
unsigned int yy = min_y; yy <= max_y; yy++)
2697 const uint8_t* ptr = img_data + widthStep * yy + min_x;
2698 for (
unsigned int xx = min_x; xx <= max_x; xx++)
2700 const int32_t dx = ptr[+1] - ptr[-1];
2701 const int32_t dy = ptr[+widthStep] - ptr[-widthStep];
2710 const float K = 0.5f / ((max_y - min_y + 1) * (max_x - min_x + 1));
2711 const float Gxx = gxx * K;
2712 const float Gxy = gxy * K;
2713 const float Gyy = gyy * K;
2719 const float t = Gxx + Gyy;
2720 const float de = Gxx * Gyy - Gxy * Gxy;
2722 return 0.5f * (
t - std::sqrt(
t *
t - 4.0f * de));
2736 strcpy(((IplImage*)
img)->channelSeq,
"RGB");
2747 strcpy(((IplImage*)
img)->channelSeq,
"BGR");
2762 std::fstream stream;
2764 if (!stream.is_open())
2766 std::cerr <<
"[CImage::loadTGA] Couldn't open file '" << fileName
2773 stream.seekg(0, std::ios_base::beg);
2776 char dumpBuffer[12];
2777 char trueColorHeader[] =
"\0\0\2\0\0\0\0\0\0\0\0\0";
2778 stream.read(dumpBuffer, 12);
2779 if (memcmp(dumpBuffer, trueColorHeader, 12) != 0)
2781 std::cerr <<
"[CImage::loadTGA] Unsupported format or invalid file.\n";
2788 stream.read((
char*)&
width, 2);
2789 stream.read((
char*)&
height, 2);
2793 std::cerr <<
"[CImage::loadTGA] Only 32 bpp format supported!\n";
2798 desc = stream.get();
2799 if (desc != 8 && desc != 32)
2801 std::cerr <<
"[CImage::loadTGA] Unsupported format or invalid file.\n";
2804 const bool origin_is_low_corner = (desc == 8);
2808 stream.read((
char*)&bytes[0],
width *
height * 4);
2816 for (
unsigned int r = 0;
r <
height;
r++)
2818 unsigned int actual_row = origin_is_low_corner ? (
height - 1 -
r) :
r;
2819 IplImage* ipl = ((IplImage*)out_RGB.
img);
2820 unsigned char*
data =
2821 (
unsigned char*)&ipl->imageData[actual_row * ipl->widthStep];
2823 IplImage* ipl_alpha = ((IplImage*)out_alpha.
img);
2824 unsigned char* data_alpha =
2825 (
unsigned char*)&ipl->imageData[actual_row * ipl_alpha->widthStep];
2827 for (
unsigned int c = 0;
c <
width;
c++)
2829 *
data++ = bytes[idx++];
2830 *
data++ = bytes[idx++];
2831 *
data++ = bytes[idx++];
2832 *data_alpha++ = bytes[idx++];
2839 #endif // MRPT_HAS_OPENCV 2844 o <<
"(" <<
p.x <<
"," <<
p.y <<
")";
2849 o <<
"(" <<
p.x <<
"," <<
p.y <<
")";
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.
void drawCircle(int x, int y, int radius, const mrpt::img::TColor &color=mrpt::img::TColor(255, 255, 255), unsigned int width=1) override
Draws a circle of a given radius.
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei imageSize
void line(int x0, int y0, int x1, int y1, const mrpt::img::TColor color, unsigned int width=1, TPenStyle penStyle=psSolid) override
Draws a line.
Used in mrpt::img::CImage.
void decompress(void *inData, size_t inDataSize, std::vector< unsigned char > &outData, size_t outDataEstimatedSize)
Decompress an array of bytes into another one.
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.
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.
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...
TPenStyle
Definition of pen styles.
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.
void rectifyImageInPlace(const mrpt::img::TCamera &cameraParams)
Rectify (un-distort) the image according to a certain camera matrix and vector of distortion coeffici...
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].
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...
#define THROW_EXCEPTION(msg)
uint8_t serializeGetVersion() const override
Must return the current versioning number of the object.
#define IMPLEMENTS_SERIALIZABLE(class_name, base, NameSpace)
This must be inserted in all CSerializable classes implementation files.
GLenum GLenum GLenum GLenum GLenum scale
void copyFromForceLoad(const CImage &o)
Copies from another image, and, if that one is externally stored, the image file will be actually loa...
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 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.
float getMaxAsFloat() const
Return the maximum pixel value of the image, as a float value in the range [0,1]. ...
CImage & operator=(const CImage &o)
Copy operator (if the image is externally stored, the writen image will be such as well)...
void flipHorizontal()
Flips the image horizontally.
TImageChannels getChannelCount() const
Returns the number of channels, typically 1 (GRAY) or 3 (RGB)
static constexpr TColor blue()
size_t getHeight() const override
Returns the height of the image in pixels.
A pair (x,y) of pixel coordinates (subpixel resolution).
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...
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...
void makeSureImageIsLoaded() const
Checks if the image is of type "external storage", and if so and not loaded yet, load it...
void WriteBuffer(const void *Buffer, size_t Count)
Writes a block of bytes to the stream from Buffer.
void joinImagesHorz(const CImage &im1, const CImage &im2)
Joins two images side-by-side horizontally.
bool isExternallyStored() const noexcept
See setExternalStorage().
void grayscaleInPlace()
Replaces the image with a grayscale version of it.
static int SERIALIZATION_JPEG_QUALITY
Unless DISABLE_JPEG_COMPRESSION=true, this sets the JPEG quality (range 1-100) of serialized RGB imag...
void unload() const noexcept
For external storage image objects only, this method unloads the image from memory (or does nothing i...
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.
GLubyte GLubyte GLubyte GLubyte w
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...
void swap(CImage &o)
Very efficient swap of two images (just swap the internal pointers)
int TImageChannels
For use in mrpt::img::CImage.
void colorImageInPlace()
Replaces this grayscale image with a RGB version of it.
static std::string IMAGES_PATH_BASE(".")
#define MRPT_THROW_UNKNOWN_SERIALIZATION_VERSION(__V)
For use in CSerializable implementations.
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)
uint64_t getTotalBytesCount() const override
Returns the total size of the internal buffer.
T square(const T x)
Inline function for the square of a number.
void swapRB()
Swaps red and blue channels.
mrpt::math::CMatrixDouble33 intrinsicParams
Matrix of intrinsic parameters (containing the focal length and principal point coordinates) ...
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...
#define ASSERT_(f)
Defines an assertion mechanism.
bool m_imgIsReadOnly
Set to true only when using setFromIplImageReadOnly.
bool loadFromFile(const std::string &fileName, int isColor=-1)
Load image from a file, whose format is determined from the extension (internally uses OpenCV)...
This base provides a set of functions for maths stuff.
size_t getWidth() const override
Returns the width of the image in pixels.
void setChannelsOrder_BGR()
Marks the channel ordering in a color image as "BGR" (this doesn't actually modify the image data...
mrpt::system::CTimeLogger CTimeLogger
unsigned char * operator()(unsigned int col, unsigned int row, unsigned int channel=0) const
Returns a pointer to a given pixel information.
virtual void selectTextFont(const std::string &fontName)
Select the current font used when drawing text.
void * getRawBufferData()
Method for getting a pointer to the raw stored data.
This CStream derived class allow using a memory buffer as a CStream.
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)
void getExternalStorageFileAbsolutePath(std::string &out_path) const
Only if isExternallyStored() returns true.
void saveToStreamAsJPEG(mrpt::io::CStream &out, const int jpeg_quality=95) const
Save image to binary stream as a JPEG (.jpg) compressed format.
CImage scaleHalfSmooth() const
Returns a new image scaled down to half its original size (averaging between every two rows) ...
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...
TInterpolationMethod
Interpolation methods for images.
void normalize()
Optimize the brightness range of an image without using histogram Only for one channel images...
uint64_t Seek(int64_t Offset, CStream::TSeekOrigin Origin=sFromBeginning) override
Introduces a pure virtual method for moving to a specified position in the streamed resource...
A pair (x,y) of pixel coordinates (integer resolution).
T round2up(T val)
Round up to the nearest power of two of a given number.
CImage scaleHalf() const
Returns a new image scaled down to half its original size.
#define IMPLEMENTS_MEXPLUS_FROM(complete_type)
const char * getChannelsOrder() const
Returns a string of the form "BGR","RGB" or "GRAY" indicating the channels ordering.
Structure to hold the parameters of a pinhole camera model.
#define ASSERTMSG_(f, __ERROR_MSG)
Defines an assertion mechanism.
void loadFromStreamAsJPEG(mrpt::io::CStream &in)
Reads the image from a binary stream containing a binary jpeg file.
void serializeFrom(mrpt::serialization::CArchive &in, uint8_t serial_version) override
Pure virtual method for reading (deserializing) from an abstract archive.
void setOriginTopLeft(bool val)
Changes the property of the image stating if the top-left corner (vs.
TImageSize getSize() const
Return the size of the image.
GLsizei const GLchar ** string
GLint GLint GLsizei GLsizei GLsizei GLint GLenum GLenum const GLvoid * pixels
void getAsMatrixTiled(math::CMatrix &outMatrix) const
Returns the image as a matrix, where the image is "tiled" (repeated) the required number of times to ...
void copyFastFrom(CImage &o)
Moves an image from another object, erasing the origin image in the process (this is much faster than...
struct mxArray_tag mxArray
Forward declaration for mxArray (avoid #including as much as possible to speed up compiling) ...
CImage grayscale() const
Returns a grayscale version of the image, or itself if it is already a grayscale image.
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 colorImage(CImage &ret) const
Returns a RGB version of the grayscale image, or itself if it is already a RGB image.
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...
std::array< double, 5 > dist
[k1 k2 t1 t2 k3] -> k_i: parameters of radial distortion, t_i: parameters of tangential distortion (d...
void filterMedianInPlace(int W=3)
Filter the image with a Median filter with a window size WxH, replacing "this" image by the filtered ...
void setPixel(int x, int y, size_t color) override
Changes the value of the pixel (x,y).
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
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...
CImage()
Default constructor: initialize an 1x1 RGB image.
void scaleImage(unsigned int width, unsigned int height, TInterpolationMethod interp=IMG_INTERP_CUBIC)
Scales this image to a new size, interpolating as needed.
Virtual base class for "archives": classes abstracting I/O streams.
GLdouble GLdouble GLdouble r
bool isColor() const
Returns true if the image is RGB, false if it is grayscale.
void rectifyImage(CImage &out_img, const mrpt::img::TCamera &cameraParams) const
Rectify (un-distort) the image according to some camera parameters, and returns an output un-distorte...
bool isOriginTopLeft() const
Returns true if the coordinates origin is top-left, or false if it is bottom-left.
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...
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.
bool m_imgIsExternalStorage
Set to true only when using setExternalStorage.
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...
std::string format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
GLenum GLenum GLvoid * row
CImage scaleDouble() const
Returns a new image scaled up to double its original size.
virtual ~CImage()
Destructor:
size_t getRowStride() const
Returns the row stride of the image: this is the number of bytes between two consecutive rows...
void changeSize(uint64_t newSize)
Change size.
void serializeTo(mrpt::serialization::CArchive &out) const override
Pure virtual method for writing (serializing) to an abstract archive.
void loadFromIplImage(void *iplImage)
Reads the image from a OpenCV IplImage object (making a COPY).
A matrix of dynamic size.
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)...
virtual void textOut(int x0, int y0, const std::string &str, const mrpt::img::TColor color)
Renders 2D text using bitmap fonts.
void releaseIpl(bool thisIsExternalImgUnload=false) noexcept
Release the internal IPL image, if not nullptr or read-only.
void equalizeHist(CImage &outImg) const
Equalize the image histogram, saving the new image in the given output object.
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)...
char * strcpy(char *dest, size_t destSize, const char *source) noexcept
An OS-independent version of strcpy.
This class is a "CSerializable" wrapper for "CMatrixFloat".
std::ostream & operator<<(std::ostream &o, const TColor &c)
void compress(void *inData, size_t inDataSize, std::vector< unsigned char > &outData)
Compress an array of bytes into another one.
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...
static bool DISABLE_JPEG_COMPRESSION
By default, when storing images through the CSerializable interface, RGB images are JPEG-compressed t...
unsigned __int32 uint32_t
void equalizeHistInPlace()
Equalize the image histogram, replacing the original image.
std::string getExternalStorageFileAbsolutePath() const
Only if isExternallyStored() returns true.
GLsizei GLsizei GLenum GLenum const GLvoid * data
std::string m_externalFile
The file name of a external storage image.
static void setImagesPathBase(const std::string &path)
void setFromIplImage(void *iplImage)
Reads the image from a OpenCV IplImage object (WITHOUT making a copy).
void flipVertical(bool also_swapRB=false)
Flips the image vertically.
#define THROW_TYPED_EXCEPTION_FMT(exceptionClass, _FORMAT_STRING,...)
static bool DISABLE_ZIP_COMPRESSION
By default, when storing images through the CSerializable interface, grayscale images will be ZIP com...
static bool loadTGA(const std::string &fileName, mrpt::img::CImage &out_RGB, mrpt::img::CImage &out_alpha)
Loads a TGA true-color RGBA image as two CImage objects, one for the RGB channels plus a separate gra...
void setChannelsOrder_RGB()
Marks the channel ordering in a color image as "RGB" (this doesn't actually modify the image data...
void setFromIplImageReadOnly(void *iplImage)
Reads the image from a OpenCV IplImage object (WITHOUT making a copy) and from now on the image canno...
A class for storing images as grayscale or RGB bitmaps.
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 memcpy(void *dest, size_t destSize, const void *src, size_t copyCount) noexcept
An OS and compiler independent version of "memcpy".
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.
#define MRPT_UNUSED_PARAM(a)
Determines whether this is an X86 or AMD64 platform.
void * img
The internal IplImage pointer to the actual image content.
static const std::string & getImagesPathBase()
By default, ".".
int round(const T value)
Returns the closer integer (int) to x.