35 #include <visp3/core/vpCPUFeatures.h>
36 #include <visp3/core/vpImageConvert.h>
37 #include <visp3/core/vpImageTools.h>
38 #include <visp3/core/vpImageException.h>
40 #if defined(VISP_HAVE_SIMDLIB)
41 #include <Simd/SimdLib.hpp>
105 unsigned char B_star)
113 double factor =
static_cast<double>((B_star - A_star) /
static_cast<double>((B - A)));
116 unsigned int i_width = I.
getWidth();
117 for (
unsigned int i = 0; i < i_height; ++i) {
118 for (
unsigned int j = 0; j < i_width; ++j) {
128 I[i][j] =
static_cast<unsigned char>(A_star + (factor * (v - A)));
157 #if defined(VISP_HAVE_SIMDLIB)
160 const int val_255 = 255;
161 unsigned int i1_size = I1.
getSize();
162 for (
unsigned int i = 0; i < i1_size; ++i) {
164 Idiff.
bitmap[i] =
static_cast<unsigned char>(std::max<unsigned char>(std::min<unsigned char>(diff, val_255), 0));
186 "Cannot compute image difference. The two images "
187 "(%ux%u) and (%ux%u) have not the same size",
195 #if defined(VISP_HAVE_SIMDLIB)
196 SimdImageDifference(
reinterpret_cast<unsigned char *
>(I1.
bitmap),
reinterpret_cast<unsigned char *
>(I2.
bitmap),
197 I1.
getSize() * 4,
reinterpret_cast<unsigned char *
>(Idiff.
bitmap));
199 const unsigned int val_4 = 4;
200 const int val_255 = 255;
201 unsigned int i1_size = I1.
getSize();
202 for (
unsigned int i = 0; i < (i1_size * val_4); ++i) {
237 for (
unsigned int b = 0; b < n; ++b) {
261 for (
unsigned int b = 0; b < n; ++b) {
290 for (
unsigned int b = 0; b < n; ++b) {
327 #if defined(VISP_HAVE_SIMDLIB)
328 typedef Simd::View<Simd::Allocator> View;
333 Simd::OperationBinary8u(img1, img2, imgAdd,
334 saturate ? SimdOperationBinary8uSaturatedAddition : SimdOperationBinary8uAddition);
336 unsigned char *ptr_I1 = I1.
bitmap;
337 unsigned char *ptr_I2 = I2.
bitmap;
338 unsigned char *ptr_Ires = Ires.
bitmap;
339 unsigned int ires_size = Ires.
getSize();
340 for (
unsigned int cpt = 0; cpt < ires_size; ++cpt, ++ptr_I1, ++ptr_I2, ++ptr_Ires) {
341 *ptr_Ires = saturate ? vpMath::saturate<unsigned char>(
static_cast<short int>(*ptr_I1) +
static_cast<short int>(*ptr_I2)) : ((*ptr_I1) + (*ptr_I2));
370 #if defined(VISP_HAVE_SIMDLIB)
371 typedef Simd::View<Simd::Allocator> View;
376 Simd::OperationBinary8u(img1, img2, imgAdd,
377 saturate ? SimdOperationBinary8uSaturatedSubtraction : SimdOperationBinary8uSubtraction);
379 unsigned char *ptr_I1 = I1.
bitmap;
380 unsigned char *ptr_I2 = I2.
bitmap;
381 unsigned char *ptr_Ires = Ires.
bitmap;
382 unsigned int ires_size = Ires.
getSize();
383 for (
unsigned int cpt = 0; cpt < ires_size; ++cpt, ++ptr_I1, ++ptr_I2, ++ptr_Ires) {
384 *ptr_Ires = saturate ?
385 vpMath::saturate<unsigned char>(
static_cast<short int>(*ptr_I1) -
static_cast<short int>(*ptr_I2)) :
386 ((*ptr_I1) - (*ptr_I2));
406 mapU.
resize(height, width,
false,
false);
407 mapV.
resize(height, width,
false,
false);
408 mapDu.
resize(height, width,
false,
false);
409 mapDv.
resize(height, width,
false,
false);
412 bool is_KannalaBrandt =
415 float u0 =
static_cast<float>(cam.
get_u0());
416 float v0 =
static_cast<float>(cam.
get_v0());
417 float px =
static_cast<float>(cam.
get_px());
418 float py =
static_cast<float>(cam.
get_py());
420 std::vector<double> dist_coefs;
422 if (!is_KannalaBrandt) {
423 kud =
static_cast<float>(cam.
get_kud());
429 if ((!is_KannalaBrandt) && (std::fabs(
static_cast<double>(kud)) <= std::numeric_limits<double>::epsilon())) {
431 for (
unsigned int i = 0; i < height; ++i) {
432 for (
unsigned int j = 0; j < width; ++j) {
433 mapU[i][j] =
static_cast<int>(j);
434 mapV[i][j] =
static_cast<int>(i);
444 float kud_px2 = 0., kud_py2 = 0., deltau_px, deltav_py = 0;
446 float deltav, deltau;
447 float u_float, v_float;
448 int u_round, v_round;
450 double theta, theta_d;
451 double theta2, theta4, theta6, theta8;
452 const unsigned int index_0 = 0;
453 const unsigned int index_1 = 1;
454 const unsigned int index_2 = 2;
455 const unsigned int index_3 = 3;
460 if (!is_KannalaBrandt) {
461 kud_px2 = kud * invpx * invpx;
462 kud_py2 = kud * invpy * invpy;
465 for (
unsigned int v = 0; v < height; ++v) {
468 if (!is_KannalaBrandt) {
469 fr1 = 1.0f + (kud_py2 * deltav * deltav);
472 deltav_py = deltav * invpy;
475 for (
unsigned int u = 0; u < width; ++u) {
478 if (!is_KannalaBrandt) {
479 fr2 = fr1 + (kud_px2 * deltau * deltau);
481 u_float = (deltau * fr2) + u0;
482 v_float = (deltav * fr2) + v0;
486 deltau_px = deltau * invpx;
492 theta6 = theta2 * theta4;
495 theta_d = theta * (1 + (dist_coefs[index_0] * theta2) + (dist_coefs[index_1] * theta4) + (dist_coefs[index_2] * theta6) +
496 (dist_coefs[index_3] * theta8));
499 scale = (std::fabs(r) < std::numeric_limits<double>::epsilon()) ? 1.0 : (theta_d / r);
500 u_float =
static_cast<float>((deltau * scale) + u0);
501 v_float =
static_cast<float>((deltav * scale) + v0);
504 u_round =
static_cast<int>(u_float);
505 v_round =
static_cast<int>(v_float);
507 mapU[v][u] = u_round;
508 mapV[v][u] = v_round;
510 mapDu[v][u] = u_float - u_round;
511 mapDv[v][u] = v_float - v_round;
530 std::cerr <<
"Error, input image is empty." << std::endl;
538 unsigned int ii_width = II.
getWidth();
539 for (
unsigned int i = 1; i < ii_height; ++i) {
540 for (
unsigned int j = 1; j < ii_width; ++j) {
541 II[i][j] = (I[i - 1][j - 1] + II[i - 1][j] + II[i][j - 1]) - II[i - 1][j - 1];
542 IIsq[i][j] = (
vpMath::sqr(I[i - 1][j - 1]) + IIsq[i - 1][j] + IIsq[i][j - 1]) - IIsq[i - 1][j - 1];
558 "Error: in vpImageTools::normalizedCorrelation(): "
559 "image dimension mismatch between I1=%ux%u and I2=%ux%u",
570 #if defined(VISP_HAVE_SIMDLIB)
571 SimdNormalizedCorrelation(I1.
bitmap, a, I2.
bitmap, b, I1.
getSize(), a2, b2, ab, useOptimized);
573 unsigned int i1_size = I1.
getSize();
574 for (
unsigned int cpt = 0; cpt < i1_size; ++cpt) {
582 return ab / sqrt(a2 * b2);
596 for (
unsigned int i = 0; i < height; ++i) {
597 for (
unsigned int j = 0; j < width; ++j) {
601 for (
unsigned int j = 0; j < width; ++j) {
614 unsigned int i_width = I.
getWidth();
615 for (
unsigned int i = 0; i < i_height; ++i) {
616 for (
unsigned int j = 0; j < i_width; ++j) {
617 I(i, j, I(i, j) / s);
631 int x1 =
static_cast<int>(floor(point.
get_i()));
632 int x2 =
static_cast<int>(ceil(point.
get_i()));
633 int y1 =
static_cast<int>(floor(point.
get_j()));
634 int y2 =
static_cast<int>(ceil(point.
get_j()));
641 v1 = ((x2 - point.
get_i()) * I(x1, y1)) + ((point.
get_i() - x1) * I(x2, y1));
642 v2 = ((x2 - point.
get_i()) * I(x1, y2)) + ((point.
get_i() - x1) * I(x2, y2));
647 return ((y2 - point.
get_j()) * v1) + ((point.
get_j() - y1) * v2);
665 return interpolationNearest(I, point);
669 "vpImageTools::interpolate(): bi-cubic interpolation is not implemented.");
690 double cos_t = cos(t);
691 double sin_t = sin(t);
693 for (
unsigned int x = 0; x < x_d; ++x) {
694 double x_cos_t = x * cos_t;
695 double x_sin_t = x * sin_t;
696 for (
unsigned int y = 0; y < y_d; ++y) {
698 static_cast<unsigned char>(
interpolate(src,
vpImagePoint(x1 + x_cos_t + (y * sin_t), (y1 - x_sin_t) + (y * cos_t)),
717 double cos_t = cos(t);
718 double sin_t = sin(t);
720 for (
unsigned int x = 0; x < x_d; ++x) {
721 double x_cos_t = x * cos_t;
722 double x_sin_t = x * sin_t;
723 for (
unsigned int y = 0; y < y_d; ++y) {
750 std::cerr <<
"Error, input image is empty." << std::endl;
755 std::cerr <<
"Error, template image is empty." << std::endl;
760 std::cerr <<
"Error, template image is bigger than input image." << std::endl;
779 const double sum2 = (((II_tpl[height_tpl][width_tpl] + II_tpl[0][0]) - II_tpl[0][width_tpl]) - II_tpl[height_tpl][0]);
780 const double mean2 = sum2 / I_tpl.
getSize();
781 unsigned int i_tpl_double_size = I_tpl_double.
getSize();
782 for (
unsigned int cpt = 0; cpt < i_tpl_double_size; ++cpt) {
783 I_tpl_double.
bitmap[cpt] -= mean2;
786 #if defined(_OPENMP) && (_OPENMP >= 200711)
787 #pragma omp parallel for schedule(dynamic)
788 for (
unsigned int i = 0; i < I.
getHeight() - height_tpl; i += step_v) {
789 for (
unsigned int j = 0; j < I.
getWidth() - width_tpl; j += step_u) {
795 int end =
static_cast<int>((I.
getHeight() - height_tpl) / step_v) + 1;
796 std::vector<unsigned int> vec_step_v(
static_cast<size_t>(end));
798 for (
unsigned int cpt = 0, idx = 0; cpt < (i_height - height_tpl); cpt += step_v, ++idx) {
799 vec_step_v[
static_cast<size_t>(idx)] = cpt;
802 #pragma omp parallel for schedule(dynamic)
804 for (
int cpt = 0; cpt < end; ++cpt) {
805 unsigned int i_width = I.
getWidth();
806 for (
unsigned int j = 0; j < (i_width - width_tpl); j += step_u) {
807 I_score[vec_step_v[cpt]][j] =
817 unsigned int i_width = I.
getWidth();
818 for (
unsigned int i = 0; i < (i_height - height_tpl); i += step_v) {
819 for (
unsigned int j = 0; j < (i_width - width_tpl); j += step_u) {
836 float vpImageTools::cubicHermite(
const float A,
const float B,
const float C,
const float D,
const float t)
838 float a = (((-A + (3.0f * B)) - (3.0f * C)) + D) / 2.0f;
839 float b = (A + (2.0f * C)) - (((5.0f * B) + D) / 2.0f);
840 float c = (-A + C) / 2.0f;
843 return (a * t * t * t) + (b * t * t) + (c * t) + d;
846 int vpImageTools::coordCast(
double x) {
return x < 0 ? -1 :
static_cast<int>(x); }
848 double vpImageTools::lerp(
double A,
double B,
double t) {
return (A * (1.0 - t)) + (B * t); }
850 float vpImageTools::lerp(
float A,
float B,
float t) {
return (A * (1.0f - t)) + (B * t); }
852 int64_t vpImageTools::lerp2(int64_t A, int64_t B, int64_t t, int64_t t_1) {
return (A * t_1) + (B * t); }
857 unsigned int i0,
unsigned int j0)
861 #if defined(VISP_HAVE_SIMDLIB)
865 unsigned int i2_width = I2.
getWidth();
866 for (
unsigned int i = 0; i < i2_height; ++i) {
867 for (
unsigned int j = 0; j < i2_width; ++j) {
868 ab += (I1[i0 + i][j0 + j]) * I2[i][j];
875 (((II[i0 + height_tpl][j0 + width_tpl] + II[i0][j0]) - II[i0][j0 + width_tpl]) - II[i0 + height_tpl][j0]);
876 const double sum2 = (((II_tpl[height_tpl][width_tpl] + II_tpl[0][0]) - II_tpl[0][width_tpl]) - II_tpl[height_tpl][0]);
885 return ab / sqrt(a2 * b2);
902 const int I_height =
static_cast<int>(I.
getHeight());
905 #pragma omp parallel for schedule(dynamic)
907 for (
int i_ = 0; i_ < I_height; ++i_) {
908 const unsigned int i =
static_cast<unsigned int>(i_);
909 unsigned int i_width = I.
getWidth();
910 for (
unsigned int j = 0; j < i_width; ++j) {
912 int u_round = mapU[i][j];
913 int v_round = mapV[i][j];
915 float du = mapDu[i][j];
916 float dv = mapDv[i][j];
918 if ((0 <= u_round) && (0 <= v_round) && (u_round < (
static_cast<int>(I.
getWidth()) - 1)) &&
919 (v_round < (I_height - 1))) {
921 float col0 = lerp(I[v_round][u_round], I[v_round][u_round + 1], du);
922 float col1 = lerp(I[v_round + 1][u_round], I[v_round + 1][u_round + 1], du);
923 float value = lerp(col0, col1, dv);
925 Iundist[i][j] =
static_cast<unsigned char>(value);
948 const int I_height =
static_cast<int>(I.
getHeight());
950 #pragma omp parallel for schedule(dynamic)
952 for (
int i = 0; i < I_height; ++i) {
953 #if defined(VISP_HAVE_SIMDLIB)
955 mapV.
data, mapDu.
data, mapDv.
data,
reinterpret_cast<unsigned char *
>(Iundist.
bitmap));
957 const unsigned int i_ =
static_cast<unsigned int>(i);
958 unsigned int i_width = I.
getWidth();
959 for (
unsigned int j = 0; j < i_width; ++j) {
961 int u_round = mapU[i_][j];
962 int v_round = mapV[i_][j];
964 float du = mapDu[i_][j];
965 float dv = mapDv[i_][j];
967 if ((0 <= u_round) && (0 <= v_round) && (u_round < (
static_cast<int>(I.
getWidth()) - 1))
968 && (v_round < (I_height - 1))) {
970 float col0 = lerp(I[v_round][u_round].R, I[v_round][u_round + 1].R, du);
971 float col1 = lerp(I[v_round + 1][u_round].R, I[v_round + 1][u_round + 1].R, du);
972 float value = lerp(col0, col1, dv);
974 Iundist[i][j].R =
static_cast<unsigned char>(value);
976 col0 = lerp(I[v_round][u_round].G, I[v_round][u_round + 1].G, du);
977 col1 = lerp(I[v_round + 1][u_round].G, I[v_round + 1][u_round + 1].G, du);
978 value = lerp(col0, col1, dv);
980 Iundist[i][j].G =
static_cast<unsigned char>(value);
982 col0 = lerp(I[v_round][u_round].B, I[v_round][u_round + 1].B, du);
983 col1 = lerp(I[v_round + 1][u_round].B, I[v_round + 1][u_round + 1].B, du);
984 value = lerp(col0, col1, dv);
986 Iundist[i][j].B =
static_cast<unsigned char>(value);
988 col0 = lerp(I[v_round][u_round].A, I[v_round][u_round + 1].A, du);
989 col1 = lerp(I[v_round + 1][u_round].A, I[v_round + 1][u_round + 1].A, du);
990 value = lerp(col0, col1, dv);
992 Iundist[i][j].A =
static_cast<unsigned char>(value);
1002 #if defined(VISP_HAVE_SIMDLIB)
1003 void vpImageTools::resizeSimdlib(
const vpImage<vpRGBa> &Isrc,
unsigned int resizeWidth,
unsigned int resizeHeight,
1006 Idst.
resize(resizeHeight, resizeWidth);
1008 typedef Simd::View<Simd::Allocator> View;
1012 Simd::Resize(src, dst, method ==
INTERPOLATION_LINEAR ? SimdResizeMethodBilinear : SimdResizeMethodArea);
1018 Idst.
resize(resizeHeight, resizeWidth);
1020 typedef Simd::View<Simd::Allocator> View;
1024 Simd::Resize(src, dst, method ==
INTERPOLATION_LINEAR ? SimdResizeMethodBilinear : SimdResizeMethodArea);
1028 bool vpImageTools::checkFixedPoint(
unsigned int x,
unsigned int y,
const vpMatrix &T,
bool affine)
1030 const unsigned int index_0 = 0;
1031 const unsigned int index_1 = 1;
1032 const unsigned int index_2 = 2;
1033 double a0 = T[index_0][index_0];
1034 double a1 = T[index_0][index_1];
1035 double a2 = T[index_0][index_2];
1036 double a3 = T[index_1][index_0];
1037 double a4 = T[index_1][index_1];
1038 double a5 = T[index_1][index_2];
1039 double a6 = affine ? 0.0 : T[index_2][index_0];
1040 double a7 = affine ? 0.0 : T[index_2][index_1];
1041 double a8 = affine ? 1.0 : T[index_2][index_2];
1043 double w = (a6 * x) + (a7 * y) + a8;
1044 double x2 = ((a0 * x) + (a1 * y) + a2) / w;
1045 double y2 = ((a3 * x) + (a4 * y) + a5) / w;
1047 const double limit = 1 << 15;
1062 "Error in vpImageTools::inMask(): image (%dx%d) and mask (%dx%d) size doesn't match",
1067 int cpt_in_mask = 0;
1068 int size_ =
static_cast<int>(I.
getSize());
1069 #if defined(_OPENMP)
1070 #pragma omp parallel for reduction(+:cpt_in_mask)
1072 for (
int i = 0; i < size_; ++i) {
1073 if (mask.
bitmap[i] == 0) {
1074 I_mask.
bitmap[i] = black;
1095 "Error in vpImageTools::inMask(): image (%dx%d) and mask (%dx%d) size doesn't match",
1099 int cpt_in_mask = 0;
1100 int size_ =
static_cast<int>(I.
getSize());
1101 #if defined(_OPENMP)
1102 #pragma omp parallel for reduction(+:cpt_in_mask)
1104 for (
int i = 0; i < size_; ++i) {
1105 if (mask.
bitmap[i] == 0) {
1133 const vpColVector &hsv_range,
unsigned char *mask,
unsigned int size)
1135 const std::size_t val_6 = 6;
1136 if ((hue ==
nullptr) || (saturation ==
nullptr) || (value ==
nullptr)) {
1138 "Error in vpImageTools::inRange(): hsv pointer are empty"));
1140 else if (hsv_range.
size() != val_6) {
1142 "Error in vpImageTools::inRange(): wrong values vector size (%d)", hsv_range.
size()));
1144 const unsigned int index_0 = 0;
1145 const unsigned int index_1 = 1;
1146 const unsigned int index_2 = 2;
1147 const unsigned int index_3 = 3;
1148 const unsigned int index_4 = 4;
1149 const unsigned int index_5 = 5;
1150 const unsigned char val_uchar_255 = 255;
1151 unsigned char h_low =
static_cast<unsigned char>(hsv_range[index_0]);
1152 unsigned char h_high =
static_cast<unsigned char>(hsv_range[index_1]);
1153 unsigned char s_low =
static_cast<unsigned char>(hsv_range[index_2]);
1154 unsigned char s_high =
static_cast<unsigned char>(hsv_range[index_3]);
1155 unsigned char v_low =
static_cast<unsigned char>(hsv_range[index_4]);
1156 unsigned char v_high =
static_cast<unsigned char>(hsv_range[index_5]);
1157 int size_ =
static_cast<int>(size);
1158 int cpt_in_range = 0;
1159 #if defined(_OPENMP)
1160 #pragma omp parallel for reduction(+:cpt_in_range)
1162 for (
int i = 0; i < size_; ++i) {
1163 bool check_h_low_high_hue = (h_low <= hue[i]) && (hue[i] <= h_high);
1164 bool check_s_low_high_saturation = (s_low <= saturation[i]) && (saturation[i] <= s_high);
1165 bool check_v_low_high_value = (v_low <= value[i]) && (value[i] <= v_high);
1166 if (check_h_low_high_hue && check_s_low_high_saturation && check_v_low_high_value) {
1167 mask[i] = val_uchar_255;
1174 return cpt_in_range;
1195 const std::vector<int> &hsv_range,
unsigned char *mask,
unsigned int size)
1197 const std::size_t val_6 = 6;
1198 if ((hue ==
nullptr) || (saturation ==
nullptr) || (value ==
nullptr)) {
1200 "Error in vpImageTools::inRange(): hsv pointer are empty"));
1202 else if (hsv_range.size() != val_6) {
1204 "Error in vpImageTools::inRange(): wrong values vector size (%d)", hsv_range.size()));
1206 const unsigned int index_0 = 0;
1207 const unsigned int index_1 = 1;
1208 const unsigned int index_2 = 2;
1209 const unsigned int index_3 = 3;
1210 const unsigned int index_4 = 4;
1211 const unsigned int index_5 = 5;
1212 unsigned char h_low =
static_cast<unsigned char>(hsv_range[index_0]);
1213 unsigned char h_high =
static_cast<unsigned char>(hsv_range[index_1]);
1214 unsigned char s_low =
static_cast<unsigned char>(hsv_range[index_2]);
1215 unsigned char s_high =
static_cast<unsigned char>(hsv_range[index_3]);
1216 unsigned char v_low =
static_cast<unsigned char>(hsv_range[index_4]);
1217 unsigned char v_high =
static_cast<unsigned char>(hsv_range[index_5]);
1218 int size_ =
static_cast<int>(size);
1219 int cpt_in_range = 0;
1221 const unsigned char val_uc_255 = 255;
1222 #if defined(_OPENMP)
1223 #pragma omp parallel for reduction(+:cpt_in_range)
1225 for (
int i = 0; i < size_; ++i) {
1226 bool check_h_low_high_hue = (h_low <= hue[i]) && (hue[i] <= h_high);
1227 bool check_s_low_high_saturation = (s_low <= saturation[i]) && (saturation[i] <= s_high);
1228 bool check_v_low_high_value = (v_low <= value[i]) && (value[i] <= v_high);
1229 if (check_h_low_high_hue && check_s_low_high_saturation && check_v_low_high_value) {
1230 mask[i] = val_uc_255;
1237 return cpt_in_range;
Implementation of a generic 2D array used as base class for matrices and vectors.
Type * data
Address of the first element of the data array.
void resize(unsigned int nrows, unsigned int ncols, bool flagNullify=true, bool recopy_=true)
unsigned int size() const
Return the number of elements of the 2D array.
Generic class defining intrinsic camera parameters.
std::vector< double > getKannalaBrandtDistortionCoefficients() const
vpCameraParametersProjType
@ ProjWithKannalaBrandtDistortion
Projection with Kannala-Brandt distortion model.
vpCameraParametersProjType get_projModel() const
Implementation of column vector and the associated operations.
error that can be emitted by ViSP classes.
@ dimensionError
Bad dimension.
@ notImplementedError
Not implemented.
static void convert(const vpImage< unsigned char > &src, vpImage< vpRGBa > &dest)
Error that can be emitted by the vpImage class and its derivatives.
@ notInitializedError
Image not initialized.
@ incorrectInitializationError
Wrong image initialization.
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
double getSum(const vpImage< bool > *p_mask=nullptr, unsigned int *nbValidPoints=nullptr) const
Compute the sum of image intensities.
unsigned int getWidth() const
void resize(unsigned int h, unsigned int w)
resize the image : Image initialization
unsigned int getSize() const
Type * bitmap
points toward the bitmap
unsigned int getHeight() const
double getMeanValue(const vpImage< bool > *p_mask=nullptr, unsigned int *nbValidPoints=nullptr) const
Return the mean value of the bitmap.
static Type maximum(const Type &a, const Type &b)
static double sqr(double x)
static Type abs(const Type &x)
static int round(double x)
static Type minimum(const Type &a, const Type &b)
Implementation of a matrix and operations on matrices.
unsigned char B
Blue component.
unsigned char R
Red component.
unsigned char G
Green component.
unsigned char A
Additional component.
Defines an oriented rectangle in the plane.
double getHeight() const
Get the rectangle height.
double getOrientation() const
Get the rectangle orientation (rad).
double getWidth() const
Get the rectangle width.
vpImagePoint getTopLeft() const
Get the top-left corner.
Defines a rectangle in the plane.
Implementation of row vector and the associated operations.
void resize(unsigned int i, bool flagNullify=true)