29 #include <mrpt/otherlibs/do_opencv_includes.h>
32 #include <mexplus/mxarray.h>
47 bool
CImage::DISABLE_ZIP_COMPRESSION = false;
48 bool CImage::DISABLE_JPEG_COMPRESSION = false;
49 int CImage::SERIALIZATION_JPEG_QUALITY = 95;
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,
574 ((IplImage*)
img)->imageSize);
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 <<
")";