41 #ifndef VP_IMAGE_TOOLS_H
42 #define VP_IMAGE_TOOLS_H
44 #include <visp3/core/vpImage.h>
46 #ifdef VISP_HAVE_THREADS
50 #include <visp3/core/vpCameraParameters.h>
51 #include <visp3/core/vpImageException.h>
52 #include <visp3/core/vpMath.h>
53 #include <visp3/core/vpRect.h>
54 #include <visp3/core/vpRectOriented.h>
87 static inline void binarise(
vpImage<Type> &I, Type threshold1, Type threshold2, Type value1, Type value2, Type value3,
93 static void crop(
const vpImage<Type> &I,
double roi_top,
double roi_left,
unsigned int roi_height,
94 unsigned int roi_width,
vpImage<Type> &crop,
unsigned int v_scale = 1,
unsigned int h_scale = 1);
100 vpImage<Type> &crop,
unsigned int v_scale = 1,
unsigned int h_scale = 1);
101 template <
class Type>
103 unsigned int h_scale = 1);
104 template <
class Type>
105 static void crop(
const unsigned char *bitmap,
unsigned int width,
unsigned int height,
const vpRect &roi,
106 vpImage<Type> &crop,
unsigned int v_scale = 1,
unsigned int h_scale = 1);
125 bool saturate =
false);
133 static int inRange(
const unsigned char *hue,
const unsigned char *saturation,
const unsigned char *value,
134 const vpColVector &hsv_range,
unsigned char *mask,
unsigned int size);
135 static int inRange(
const unsigned char *hue,
const unsigned char *saturation,
const unsigned char *value,
136 const std::vector<int> &hsv_range,
unsigned char *mask,
unsigned int size);
137 static void initUndistortMap(
const vpCameraParameters &cam,
unsigned int width,
unsigned int height,
142 const vpImageInterpolationType &method = INTERPOLATION_NEAREST);
155 template <
class Type>
157 const vpImageInterpolationType &method = INTERPOLATION_NEAREST,
unsigned int nThreads = 0);
159 template <
class Type>
161 const vpImageInterpolationType &method = INTERPOLATION_NEAREST,
unsigned int nThreads = 0);
165 bool useOptimized =
true);
167 template <
class Type>
169 unsigned int nThreads = 2);
171 template <
class Type>
175 template <
class Type>
177 const vpImageInterpolationType &interpolation = INTERPOLATION_NEAREST,
178 bool fixedPointArithmetic =
true,
bool pixelCenter =
false);
180 #if defined(VISP_BUILD_DEPRECATED_FUNCTIONS)
185 template <
class Type>
186 VP_DEPRECATED
static void createSubImage(
const vpImage<Type> &I,
unsigned int i_sub,
unsigned int j_sub,
187 unsigned int nrow_sub,
unsigned int ncol_sub,
vpImage<Type> &S);
189 template <
class Type>
196 static float cubicHermite(
const float A,
const float B,
const float C,
const float D,
const float t);
198 template <
class Type>
static Type getPixelClamped(
const vpImage<Type> &I,
float u,
float v);
200 static int coordCast(
double x);
203 static double lerp(
double A,
double B,
double t);
204 static float lerp(
float A,
float B,
float t);
205 static int64_t lerp2(int64_t A, int64_t B, int64_t t, int64_t t_1);
211 template <
class Type>
213 float v,
float xFrac,
float yFrac);
215 template <
class Type>
217 float v,
float xFrac,
float yFrac);
219 template <
class Type>
223 #if defined(VISP_HAVE_SIMDLIB)
224 static void resizeSimdlib(
const vpImage<vpRGBa> &Isrc,
unsigned int resizeWidth,
unsigned int resizeHeight,
226 static void resizeSimdlib(
const vpImage<unsigned char> &Isrc,
unsigned int resizeWidth,
unsigned int resizeHeight,
230 template <
class Type>
234 template <
class Type>
236 bool centerCorner,
bool fixedPoint);
238 static bool checkFixedPoint(
unsigned int x,
unsigned int y,
const vpMatrix &T,
bool affine);
243 #if defined(VISP_BUILD_DEPRECATED_FUNCTIONS)
263 template <
class Type>
264 void vpImageTools::createSubImage(
const vpImage<Type> &I,
unsigned int roi_top,
unsigned int roi_left,
265 unsigned int roi_height,
unsigned int roi_width,
vpImage<Type> &crop)
314 template <
class Type>
316 unsigned int roi_width,
vpImage<Type> &crop,
unsigned int v_scale,
unsigned int h_scale)
318 int i_min = std::max<int>(
static_cast<int>(ceil(roi_top / v_scale)), 0);
319 int j_min = std::max<int>(
static_cast<int>(ceil(roi_left / h_scale)), 0);
320 int i_max = std::min<int>(
static_cast<int>(ceil(roi_top + roi_height) / v_scale),
static_cast<int>(I.
getHeight() / v_scale));
321 int j_max = std::min<int>(
static_cast<int>(ceil((roi_left + roi_width) / h_scale)),
static_cast<int>(I.
getWidth() / h_scale));
323 unsigned int i_min_u =
static_cast<unsigned int>(i_min);
324 unsigned int j_min_u =
static_cast<unsigned int>(j_min);
326 unsigned int r_width =
static_cast<unsigned int>(j_max - j_min);
327 unsigned int r_height =
static_cast<unsigned int>(i_max - i_min);
329 crop.resize(r_height, r_width);
331 if ((v_scale == 1) && (h_scale == 1)) {
332 for (
unsigned int i = 0; i < r_height; ++i) {
333 void *src = (
void *)(I[i + i_min_u] + j_min_u);
334 void *dst = (
void *)(
crop[i]);
335 memcpy(dst, src, r_width *
sizeof(Type));
338 else if (h_scale == 1) {
339 for (
unsigned int i = 0; i < r_height; ++i) {
340 void *src = (
void *)(I[(i + i_min_u) * v_scale] + j_min_u);
341 void *dst = (
void *)(
crop[i]);
342 memcpy(dst, src, r_width *
sizeof(Type));
346 for (
unsigned int i = 0; i < r_height; ++i) {
347 for (
unsigned int j = 0; j < r_width; ++j) {
348 crop[i][j] = I[(i + i_min_u) * v_scale][(j + j_min_u) * h_scale];
371 template <
class Type>
373 unsigned int roi_width,
vpImage<Type> &crop,
unsigned int v_scale,
unsigned int h_scale)
394 template <
class Type>
396 unsigned int h_scale)
419 template <
class Type>
421 vpImage<Type> &crop,
unsigned int v_scale,
unsigned int h_scale)
423 int i_min = std::max<int>(
static_cast<int>(ceil(roi.
getTop() / v_scale)), 0);
424 int j_min = std::max<int>(
static_cast<int>(ceil(roi.
getLeft() / h_scale)), 0);
425 int i_max = std::min<int>(
static_cast<int>(ceil((roi.
getTop() + roi.
getHeight()) / v_scale)),
static_cast<int>(height / v_scale));
426 int j_max = std::min<int>(
static_cast<int>(ceil((roi.
getLeft() + roi.
getWidth()) / h_scale)),
static_cast<int>(width / h_scale));
428 unsigned int i_min_u =
static_cast<unsigned int>(i_min);
429 unsigned int j_min_u =
static_cast<unsigned int>(j_min);
431 unsigned int r_width =
static_cast<unsigned int>(j_max - j_min);
432 unsigned int r_height =
static_cast<unsigned int>(i_max - i_min);
434 crop.resize(r_height, r_width);
436 if (v_scale == 1 && h_scale == 1) {
437 for (
unsigned int i = 0; i < r_height; ++i) {
438 void *src = (
void *)(bitmap + ((((i + i_min_u) * width) + j_min_u) *
sizeof(Type)));
439 void *dst = (
void *)(
crop[i]);
440 memcpy(dst, src, r_width *
sizeof(Type));
443 else if (h_scale == 1) {
444 for (
unsigned int i = 0; i < r_height; ++i) {
445 void *src = (
void *)(bitmap + (((((i + i_min_u) * width) * v_scale) + j_min_u) *
sizeof(Type)));
446 void *dst = (
void *)(
crop[i]);
447 memcpy(dst, src, r_width *
sizeof(Type));
451 for (
unsigned int i = 0; i < r_height; ++i) {
452 unsigned int i_src = (((i + i_min_u) * width) * v_scale) + (j_min_u * h_scale);
453 for (
unsigned int j = 0; j < r_width; ++j) {
454 void *src = (
void *)(bitmap + ((i_src + (j * h_scale)) *
sizeof(Type)));
455 void *dst = (
void *)(&
crop[i][j]);
456 memcpy(dst, src,
sizeof(Type));
472 template <
class Type>
474 Type value3,
bool useLUT)
477 std::cerr <<
"LUT not available for this type ! Will use the iteration method." << std::endl;
483 for (; p < pend; ++p) {
485 if (v < threshold1) {
488 else if (v > threshold2) {
509 unsigned char value1,
unsigned char value2,
unsigned char value3,
bool useLUT)
513 const unsigned int sizeLut = 256;
514 unsigned char lut[sizeLut];
515 for (
unsigned int i = 0; i < sizeLut; ++i) {
516 lut[i] = i < threshold1 ? value1 : (i > threshold2 ? value3 : value2);
522 unsigned char *p = I.
bitmap;
524 for (; p < pend; ++p) {
525 unsigned char v = *p;
526 if (v < threshold1) {
529 else if (v > threshold2) {
539 #ifdef VISP_HAVE_THREADS
541 #ifndef DOXYGEN_SHOULD_SKIP_THIS
542 template <
class Type>
class vpUndistortInternalType
550 unsigned int nthreads;
551 unsigned int threadid;
554 vpUndistortInternalType() : src(nullptr), dst(nullptr), width(0), height(0), cam(), nthreads(0), threadid(0) { }
556 vpUndistortInternalType(
const vpUndistortInternalType<Type> &u) { *
this = u; }
557 vpUndistortInternalType &operator=(
const vpUndistortInternalType<Type> &u)
564 nthreads = u.nthreads;
565 threadid = u.threadid;
570 static void vpUndistort_threaded(vpUndistortInternalType<Type> &undistortSharedData);
573 template <
class Type>
void vpUndistortInternalType<Type>::vpUndistort_threaded(vpUndistortInternalType<Type> &undistortSharedData)
575 int offset = (int)undistortSharedData.threadid;
576 int width = (
int)undistortSharedData.width;
577 int height = (int)undistortSharedData.height;
578 int nthreads = (
int)undistortSharedData.nthreads;
580 double u0 = undistortSharedData.cam.get_u0();
581 double v0 = undistortSharedData.cam.get_v0();
582 double px = undistortSharedData.cam.get_px();
583 double py = undistortSharedData.cam.get_py();
584 double kud = undistortSharedData.cam.get_kud();
586 double invpx = 1.0 / px;
587 double invpy = 1.0 / py;
589 double kud_px2 = kud * invpx * invpx;
590 double kud_py2 = kud * invpy * invpy;
592 Type *dst = undistortSharedData.dst + (height / nthreads * offset) * width;
593 Type *src = undistortSharedData.src;
595 for (
double v = height / nthreads * offset; v < height / nthreads * (offset + 1); ++v) {
596 double deltav = v - v0;
598 double fr1 = 1.0 + kud_py2 * deltav * deltav;
600 for (
double u = 0; u < width; ++u) {
602 double deltau = u - u0;
604 double fr2 = fr1 + kud_px2 * deltau * deltau;
606 double u_double = deltau * fr2 + u0;
607 double v_double = deltav * fr2 + v0;
612 int u_round = (int)(u_double);
613 int v_round = (int)(v_double);
618 double du_double = (u_double)-(
double)u_round;
619 double dv_double = (v_double)-(
double)v_round;
622 if ((0 <= u_round) && (0 <= v_round) && (u_round < ((width)-1)) && (v_round < ((height)-1))) {
624 const Type *_mp = &src[v_round * width + u_round];
625 v01 = (Type)(_mp[0] + ((_mp[1] - _mp[0]) * du_double));
627 v23 = (Type)(_mp[0] + ((_mp[1] - _mp[0]) * du_double));
628 *dst = (Type)(v01 + ((v23 - v01) * dv_double));
663 template <
class Type>
665 unsigned int nThreads)
667 #if defined(VISP_HAVE_THREADS)
674 undistI.
resize(height, width);
679 if (std::fabs(kud) <= std::numeric_limits<double>::epsilon()) {
685 unsigned int nthreads = nThreads;
686 std::vector<std::thread *> threadpool;
688 vpUndistortInternalType<Type> *undistortSharedData =
new vpUndistortInternalType<Type>[nthreads];
690 for (
unsigned int i = 0; i < nthreads; ++i) {
692 undistortSharedData[i].src = I.
bitmap;
693 undistortSharedData[i].dst = undistI.
bitmap;
694 undistortSharedData[i].width = I.
getWidth();
695 undistortSharedData[i].height = I.
getHeight();
696 undistortSharedData[i].cam = cam;
697 undistortSharedData[i].nthreads = nthreads;
698 undistortSharedData[i].threadid = i;
699 std::thread *undistort_thread =
new std::thread(&vpUndistortInternalType<Type>::vpUndistort_threaded, std::ref(undistortSharedData[i]));
700 threadpool.push_back(undistort_thread);
704 for (
unsigned int i = 0; i < nthreads; ++i) {
705 threadpool[i]->join();
708 for (
unsigned int i = 0; i < nthreads; ++i) {
709 delete threadpool[i];
712 delete[] undistortSharedData;
721 undistI.
resize(height, width);
732 if (std::fabs(kud) <= std::numeric_limits<double>::epsilon()) {
738 double invpx = 1.0 / px;
739 double invpy = 1.0 / py;
741 double kud_px2 = kud * invpx * invpx;
742 double kud_py2 = kud * invpy * invpy;
744 Type *dst = undistI.
bitmap;
745 for (
double v = 0; v < height; ++v) {
746 double deltav = v - v0;
750 double fr1 = 1.0 + (kud_py2 * deltav * deltav);
752 for (
double u = 0; u < width; ++u) {
756 double deltau = u - u0;
760 double fr2 = fr1 + (kud_px2 * deltau * deltau);
762 double u_double = (deltau * fr2) + u0;
763 double v_double = (deltav * fr2) + v0;
770 int u_round =
static_cast<int>(u_double);
771 int v_round =
static_cast<int>(v_double);
778 double du_double = u_double-
static_cast<double>(u_round);
779 double dv_double = v_double-
static_cast<double>(v_round);
782 if ((0 <= u_round) && (0 <= v_round) && (u_round < ((
static_cast<int>(width)) - 1)) && (v_round < ((
static_cast<int>(height)) - 1))) {
784 const Type *v_mp = &I[
static_cast<unsigned int>(v_round)][
static_cast<unsigned int>(u_round)];
785 v01 =
static_cast<Type
>(v_mp[0] + ((v_mp[1] - v_mp[0]) * du_double));
787 v23 =
static_cast<Type
>(v_mp[0] + ((v_mp[1] - v_mp[0]) * du_double));
788 *dst =
static_cast<Type
>(v01 + ((v23 - v01) * dv_double));
816 template <
class Type>
820 remap(I, mapU, mapV, mapDu, mapDv, newI);
832 newI.
resize(height, width);
834 for (
unsigned int i = 0; i < height; ++i) {
835 memcpy(newI.
bitmap + (i * width), I.
bitmap + ((height - 1 - i) * width), width *
sizeof(Type));
880 const unsigned int halfHeight = height / 2;
881 for (
unsigned int i = 0; i < halfHeight; ++i) {
882 memcpy(Ibuf.
bitmap, I.
bitmap + (i * width), width *
sizeof(Type));
884 memcpy(I.
bitmap + (i * width), I.
bitmap + ((height - 1 - i) * width), width *
sizeof(Type));
885 memcpy(I.
bitmap + ((height - 1 - i) * width), Ibuf.
bitmap, width *
sizeof(Type));
889 template <
class Type> Type vpImageTools::getPixelClamped(
const vpImage<Type> &I,
float u,
float v)
893 x = std::max<int>(0, std::min<int>(x,
static_cast<int>(I.
getWidth()) - 1));
894 y = std::max<int>(0, std::min<int>(y,
static_cast<int>(I.
getHeight()) - 1));
901 template <
class Type>
903 float v,
float xFrac,
float yFrac)
906 Type p00 = getPixelClamped(I, u - 1, v - 1);
907 Type p01 = getPixelClamped(I, u + 0, v - 1);
908 Type p02 = getPixelClamped(I, u + 1, v - 1);
909 Type p03 = getPixelClamped(I, u + 2, v - 1);
912 Type p10 = getPixelClamped(I, u - 1, v + 0);
913 Type p11 = getPixelClamped(I, u + 0, v + 0);
914 Type p12 = getPixelClamped(I, u + 1, v + 0);
915 Type p13 = getPixelClamped(I, u + 2, v + 0);
918 Type p20 = getPixelClamped(I, u - 1, v + 1);
919 Type p21 = getPixelClamped(I, u + 0, v + 1);
920 Type p22 = getPixelClamped(I, u + 1, v + 1);
921 Type p23 = getPixelClamped(I, u + 2, v + 1);
924 Type p30 = getPixelClamped(I, u - 1, v + 2);
925 Type p31 = getPixelClamped(I, u + 0, v + 2);
926 Type p32 = getPixelClamped(I, u + 1, v + 2);
927 Type p33 = getPixelClamped(I, u + 2, v + 2);
929 float col0 = cubicHermite(p00, p01, p02, p03, xFrac);
930 float col1 = cubicHermite(p10, p11, p12, p13, xFrac);
931 float col2 = cubicHermite(p20, p21, p22, p23, xFrac);
932 float col3 = cubicHermite(p30, p31, p32, p33, xFrac);
933 float value = cubicHermite(col0, col1, col2, col3, yFrac);
934 Ires[i][j] = vpMath::saturate<Type>(value);
939 float u,
float v,
float xFrac,
float yFrac)
942 vpRGBa p00 = getPixelClamped(I, u - 1, v - 1);
943 vpRGBa p01 = getPixelClamped(I, u + 0, v - 1);
944 vpRGBa p02 = getPixelClamped(I, u + 1, v - 1);
945 vpRGBa p03 = getPixelClamped(I, u + 2, v - 1);
948 vpRGBa p10 = getPixelClamped(I, u - 1, v + 0);
949 vpRGBa p11 = getPixelClamped(I, u + 0, v + 0);
950 vpRGBa p12 = getPixelClamped(I, u + 1, v + 0);
951 vpRGBa p13 = getPixelClamped(I, u + 2, v + 0);
954 vpRGBa p20 = getPixelClamped(I, u - 1, v + 1);
955 vpRGBa p21 = getPixelClamped(I, u + 0, v + 1);
956 vpRGBa p22 = getPixelClamped(I, u + 1, v + 1);
957 vpRGBa p23 = getPixelClamped(I, u + 2, v + 1);
960 vpRGBa p30 = getPixelClamped(I, u - 1, v + 2);
961 vpRGBa p31 = getPixelClamped(I, u + 0, v + 2);
962 vpRGBa p32 = getPixelClamped(I, u + 1, v + 2);
963 vpRGBa p33 = getPixelClamped(I, u + 2, v + 2);
965 const int nbChannels = 3;
966 for (
int c = 0; c < nbChannels; ++c) {
967 float col0 = cubicHermite(
static_cast<float>(
reinterpret_cast<unsigned char *
>(&p00)[c]),
968 static_cast<float>(
reinterpret_cast<unsigned char *
>(&p01)[c]),
969 static_cast<float>(
reinterpret_cast<unsigned char *
>(&p02)[c]),
970 static_cast<float>(
reinterpret_cast<unsigned char *
>(&p03)[c]), xFrac);
971 float col1 = cubicHermite(
static_cast<float>(
reinterpret_cast<unsigned char *
>(&p10)[c]),
972 static_cast<float>(
reinterpret_cast<unsigned char *
>(&p11)[c]),
973 static_cast<float>(
reinterpret_cast<unsigned char *
>(&p12)[c]),
974 static_cast<float>(
reinterpret_cast<unsigned char *
>(&p13)[c]), xFrac);
975 float col2 = cubicHermite(
static_cast<float>(
reinterpret_cast<unsigned char *
>(&p20)[c]),
976 static_cast<float>(
reinterpret_cast<unsigned char *
>(&p21)[c]),
977 static_cast<float>(
reinterpret_cast<unsigned char *
>(&p22)[c]),
978 static_cast<float>(
reinterpret_cast<unsigned char *
>(&p23)[c]), xFrac);
979 float col3 = cubicHermite(
static_cast<float>(
reinterpret_cast<unsigned char *
>(&p30)[c]),
980 static_cast<float>(
reinterpret_cast<unsigned char *
>(&p31)[c]),
981 static_cast<float>(
reinterpret_cast<unsigned char *
>(&p32)[c]),
982 static_cast<float>(
reinterpret_cast<unsigned char *
>(&p33)[c]), xFrac);
983 float value = cubicHermite(col0, col1, col2, col3, yFrac);
985 reinterpret_cast<unsigned char *
>(&Ires[i][j])[c] = vpMath::saturate<unsigned char>(value);
989 template <
class Type>
991 float v,
float xFrac,
float yFrac)
993 int u0 =
static_cast<int>(u);
994 int v0 =
static_cast<int>(v);
996 int u1 = std::min<int>(
static_cast<int>(I.
getWidth()) - 1, u0 + 1);
1000 int v2 = std::min<int>(
static_cast<int>(I.
getHeight()) - 1, v0 + 1);
1005 float col0 = lerp(I[v0][u0], I[v1][u1], xFrac);
1006 float col1 = lerp(I[v2][u2], I[v3][u3], xFrac);
1007 float value = lerp(col0, col1, yFrac);
1009 Ires[i][j] = vpMath::saturate<Type>(value);
1014 unsigned int j,
float u,
float v,
float xFrac,
float yFrac)
1016 int u0 =
static_cast<int>(u);
1017 int v0 =
static_cast<int>(v);
1019 int u1 = std::min<int>(
static_cast<int>(I.
getWidth()) - 1, u0 + 1);
1023 int v2 = std::min<int>(
static_cast<int>(I.
getHeight()) - 1, v0 + 1);
1028 const int nbChannels = 3;
1029 for (
int c = 0; c < nbChannels; ++c) {
1030 float col0 = lerp(
static_cast<float>(
reinterpret_cast<const unsigned char *
>(&I[v0][u0])[c]),
1031 static_cast<float>(
reinterpret_cast<const unsigned char *
>(&I[v1][u1])[c]), xFrac);
1032 float col1 = lerp(
static_cast<float>(
reinterpret_cast<const unsigned char *
>(&I[v2][u2])[c]),
1033 static_cast<float>(
reinterpret_cast<const unsigned char *
>(&I[v3][u3])[c]), xFrac);
1034 float value = lerp(col0, col1, yFrac);
1036 reinterpret_cast<unsigned char *
>(&Ires[i][j])[c] = vpMath::saturate<unsigned char>(value);
1040 template <
class Type>
1044 Ires[i][j] = getPixelClamped(I, u, v);
1065 template <
class Type>
1069 Ires.
resize(height, width);
1091 template <
class Type>
1094 #
if defined(_OPENMP)
1099 const unsigned int minWidth = 2, minHeight = 2;
1101 std::cerr <<
"Input or output image is too small!" << std::endl;
1106 std::cerr <<
"INTERPOLATION_AREA is not implemented for this type." << std::endl;
1112 const float half = 0.5f;
1113 const int ires_height =
static_cast<int>(Ires.
getHeight());
1114 #if defined(_OPENMP)
1116 omp_set_num_threads(
static_cast<int>(nThreads));
1118 #pragma omp parallel for schedule(dynamic)
1120 for (
int i = 0; i < ires_height; ++i) {
1121 const float v = ((i + half) * scaleY) - half;
1122 const float v0 = std::floor(v);
1123 const float yFrac = v - v0;
1125 unsigned int ires_width =
static_cast<unsigned int>(Ires.
getWidth());
1126 for (
unsigned int j = 0; j < ires_width; ++j) {
1127 const float u = ((j + half) * scaleX) - half;
1128 const float u0 = std::floor(u);
1129 const float xFrac = u - u0;
1132 resizeNearest(I, Ires,
static_cast<unsigned int>(i), j, u, v);
1135 resizeBilinear(I, Ires,
static_cast<unsigned int>(i), j, u0, v0, xFrac, yFrac);
1138 resizeBicubic(I, Ires,
static_cast<unsigned int>(i), j, u, v, xFrac, yFrac);
1144 #if defined(VISP_HAVE_SIMDLIB)
1149 #
if defined(_OPENMP)
1154 const unsigned int minWidth = 2, minHeight = 2;
1157 std::cerr <<
"Input or output image is too small!" << std::endl;
1170 const float half = 0.5f;
1171 const int ires_height =
static_cast<int>(Ires.
getHeight());
1172 #if defined(_OPENMP)
1174 omp_set_num_threads(
static_cast<int>(nThreads));
1176 #pragma omp parallel for schedule(dynamic)
1178 for (
int i = 0; i < ires_height; ++i) {
1179 float v = ((i + half) * scaleY) - half;
1180 float yFrac = v -
static_cast<int>(v);
1182 unsigned int ires_width =
static_cast<unsigned int>(Ires.
getWidth());
1183 for (
unsigned int j = 0; j < ires_width; ++j) {
1184 float u = ((j + half) * scaleX) - half;
1185 float xFrac = u -
static_cast<int>(u);
1188 resizeNearest(I, Ires,
static_cast<unsigned int>(i), j, u, v);
1191 resizeBicubic(I, Ires,
static_cast<unsigned int>(i), j, u, v, xFrac, yFrac);
1202 #
if defined(_OPENMP)
1207 const unsigned int minWidth = 2, minHeight = 2;
1210 std::cerr <<
"Input or output image is too small!" << std::endl;
1223 const float half = 0.5f;
1224 const int ires_height =
static_cast<int>(Ires.
getHeight());
1225 #if defined(_OPENMP)
1227 omp_set_num_threads(
static_cast<int>(nThreads));
1229 #pragma omp parallel for schedule(dynamic)
1231 for (
int i = 0; i < ires_height; ++i) {
1232 float v = ((i + half) * scaleY) - half;
1233 float yFrac = v -
static_cast<int>(v);
1235 unsigned int ires_width =
static_cast<unsigned int>(Ires.
getWidth());
1236 for (
unsigned int j = 0; j < ires_width; ++j) {
1237 float u = ((j + half) * scaleX) - half;
1238 float xFrac = u -
static_cast<int>(u);
1241 resizeNearest(I, Ires,
static_cast<unsigned int>(i), j, u, v);
1244 resizeBicubic(I, Ires,
static_cast<unsigned int>(i), j, u, v, xFrac, yFrac);
1252 #include <visp3/core/vpImageTools_warp.h>
Implementation of a generic 2D array used as base class for matrices and vectors.
Generic class defining intrinsic camera parameters.
Implementation of column vector and the associated operations.
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition of the vpImage class member functions.
unsigned int getWidth() const
void resize(unsigned int h, unsigned int w)
resize the image : Image initialization
void performLut(const Type(&lut)[256], unsigned int nbThreads=1)
Type * bitmap
points toward the bitmap
unsigned int getHeight() const
static int round(double x)
Implementation of a matrix and operations on matrices.
Defines an oriented rectangle in the plane.
Defines a rectangle in the plane.
Implementation of row vector and the associated operations.