30 #ifndef _D_IMAGE_TRANSFORM_HPP
31 #define _D_IMAGE_TRANSFORM_HPP
33 #include "DBaseImageOperations.hpp"
34 #include "DLineArith.hpp"
83 template <
class T1,
class T2>
84 RES_T
copy(
const Image<T1> &imIn,
size_t startX,
size_t startY,
size_t startZ,
85 size_t sizeX,
size_t sizeY,
size_t sizeZ,
Image<T2> &imOut,
86 size_t outStartX = 0,
size_t outStartY = 0,
size_t outStartZ = 0)
88 ASSERT_ALLOCATED(&imIn, &imOut);
94 size_t outW = imOut.getWidth();
95 size_t outH = imOut.getHeight();
96 size_t outD = imOut.getDepth();
98 ASSERT(startX < inW && startY < inH && startZ < inD);
99 ASSERT(outStartX < outW && outStartY < outH && outStartZ < outD);
101 size_t realSx = min(min(sizeX, inW - startX), outW - outStartX);
102 size_t realSy = min(min(sizeY, inH - startY), outH - outStartY);
103 size_t realSz = min(min(sizeZ, inD - startZ), outD - outStartZ);
110 for (
size_t z = 0; z < realSz; z++) {
115 int nthreads = Core::getInstance()->getNumberOfThreads();
120 #pragma omp for schedule(dynamic, nthreads) nowait
122 for (
size_t y = 0; y < realSy; y++)
123 copyLine<T1, T2>(lnIn[y] + startX, realSx, lnOut[y] + outStartX);
141 template <
class T1,
class T2>
142 RES_T
copy(
const Image<T1> &imIn,
size_t startX,
size_t startY,
size_t sizeX,
143 size_t sizeY,
Image<T2> &imOut,
size_t outStartX = 0,
144 size_t outStartY = 0,
size_t outStartZ = 0)
146 return copy(imIn, startX, startY, 0, sizeX, sizeY, 1, imOut, outStartX,
147 outStartY, outStartZ);
159 template <
class T1,
class T2>
160 RES_T
copy(
const Image<T1> &imIn,
size_t startX,
size_t startY,
size_t startZ,
161 Image<T2> &imOut,
size_t outStartX = 0,
size_t outStartY = 0,
162 size_t outStartZ = 0)
165 imIn.
getDepth(), imOut, outStartX, outStartY, outStartZ);
176 template <
class T1,
class T2>
178 Image<T2> &imOut,
size_t outStartX = 0,
size_t outStartY = 0,
179 size_t outStartZ = 0)
182 imOut, outStartX, outStartY, outStartZ);
193 template <
class T1,
class T2>
195 size_t outStartY,
size_t outStartZ = 0)
198 imIn.
getDepth(), imOut, outStartX, outStartY, outStartZ);
213 template <
class T1,
class T2>
218 if (
typeid(imIn) ==
typeid(imOut))
219 return copy(imIn, imOut);
221 ASSERT_ALLOCATED(&imIn, &imOut);
223 if (!haveSameSize(&imIn, &imOut, NULL))
224 return copy<T1, T2>(imIn, 0, 0, 0, imOut, 0, 0, 0);
244 ASSERT_ALLOCATED(&imIn, &imOut);
267 ASSERT_ALLOCATED(&imIn);
269 ASSERT((imOut.setSize(imIn) == RES_OK));
270 return copy<T>(imIn, imOut);
298 RES_T
crop(
const Image<T> &imIn,
size_t startX,
size_t startY,
size_t startZ,
299 size_t sizeX,
size_t sizeY,
size_t sizeZ,
Image<T> &imOut)
301 ASSERT_ALLOCATED(&imIn);
307 size_t realSx = min(sizeX, inW - startX);
308 size_t realSy = min(sizeY, inH - startY);
309 size_t realSz = min(sizeZ, inD - startZ);
311 imOut.setSize(realSx, realSy, realSz);
312 return copy(imIn, startX, startY, startZ, realSx, realSy, realSz, imOut, 0,
328 RES_T
crop(
Image<T> &imInOut,
size_t startX,
size_t startY,
size_t startZ,
329 size_t sizeX,
size_t sizeY,
size_t sizeZ)
332 return crop(tmpIm, startX, startY, startZ, sizeX, sizeY, sizeZ, imInOut);
349 RES_T
crop(
const Image<T> &imIn,
size_t startX,
size_t startY,
size_t sizeX,
352 return crop(imIn, startX, startY, 0, sizeX, sizeY, 1, imOut);
368 RES_T
crop(
Image<T> &imInOut,
size_t startX,
size_t startY,
size_t sizeX,
371 return crop(imInOut, startX, startY, 0, sizeX, sizeY, 1);
398 ASSERT_ALLOCATED(&imIn)
400 if (&imIn == &imOut) {
402 return addBorder(tmpIm, bSize, imOut, borderValue);
411 imOut.setSize(s[0] + 2 * bSize, s[1] + 2 * bSize, s[2] + 2 * bSize);
412 ASSERT_ALLOCATED(&imOut)
413 fill(imOut, borderValue);
414 copy(imIn, 0, 0, 0, s[0], s[1], s[2], imOut, bSize, bSize, bSize);
416 imOut.setSize(s[0] + 2 * bSize, s[1] + 2 * bSize, 1);
417 ASSERT_ALLOCATED(&imOut)
418 fill(imOut, borderValue);
419 copy(imIn, 0, 0, s[0], s[1], imOut, bSize, bSize);
445 template <
class T>
class FlipClassFunc
448 void copyReverse(T *in,
size_t width, T *out)
450 for (
size_t i = 0; i < width; i++)
451 out[i] = in[width - 1 - i];
455 RES_T flipIt(Image<T> &imIn, Image<T> &imOut,
string direction)
457 ASSERT_ALLOCATED(&imIn, &imOut);
458 ASSERT_SAME_SIZE(&imIn, &imOut);
460 if (&imIn == &imOut) {
461 Image<T> imTmp = Image<T>(imIn,
true);
462 return flipIt(imTmp, imOut, direction);
465 bool vflip = (direction ==
"vertical");
467 typename Image<T>::sliceType *slicesIn = imIn.getSlices();
468 typename Image<T>::sliceType *slicesOut = imOut.getSlices();
470 size_t width = imIn.getWidth();
471 size_t height = imIn.getHeight();
472 size_t depth = imIn.getDepth();
474 ImageFreezer freeze(imOut);
476 int nthreads = Core::getInstance()->getNumberOfThreads();
477 #pragma omp parallel for num_threads(nthreads)
479 for (
size_t k = 0; k < depth; k++) {
480 typename Image<T>::sliceType linesIn;
481 typename Image<T>::sliceType linesOut;
482 linesIn = slicesIn[k];
483 linesOut = slicesOut[k];
486 for (
size_t j = 0; j < height; j++)
487 copyLine<T>(linesIn[j], width, linesOut[height - 1 - j]);
489 for (
size_t j = 0; j < height; j++)
490 copyReverse(linesIn[j], width, linesOut[j]);
509 string direction =
"vertical";
510 FlipClassFunc<T> flip;
511 return flip.flipIt(imIn, imOut,
"vertical");
537 string direction =
"horizontal";
538 FlipClassFunc<T> flip;
539 return flip.flipIt(imIn, imOut, direction);
563 template <
class T>
class ImageRotateFunct
574 RES_T Rotate(Image<T> &imIn,
int count, Image<T> &imOut)
578 return RotateX90(imIn, count, imOut);
582 RES_T RotateX90(Image<T> &imIn,
int count, Image<T> &imOut)
584 ASSERT_ALLOCATED(&imIn, &imOut);
587 int angle = count * 90;
590 ImageFreezer freeze(imOut);
591 return copy(imIn, imOut);
594 off_t w = imIn.getWidth();
595 off_t h = imIn.getHeight();
596 off_t d = imIn.getDepth();
599 if (angle == 90 || angle == 270) {
600 imOut.setSize(h, w, d);
602 imOut.setSize(w, h, d);
605 ImageFreezer freeze(imOut);
607 typedef typename ImDtTypes<T>::lineType lineType;
608 lineType pixIn = imIn.getPixels();
609 lineType pixOut = imOut.getPixels();
614 #pragma omp parallel for
616 for (off_t k = 0; k < d; k++) {
617 off_t offset = k * w * h;
618 T *sIn = (T *) (pixIn + offset);
619 T *sOut = (T *) (pixOut + offset);
620 for (off_t j = 0; j < h; j++) {
621 for (off_t i = 0; i < w; i++) {
622 sOut[i * h + (w - 1 - j)] = sIn[j * w + i];
629 #pragma omp parallel for
631 for (off_t k = 0; k < d; k++) {
632 off_t offset = k * w * h;
633 T *sIn = (T *) (pixIn + offset);
634 T *sOut = (T *) (pixOut + offset);
635 for (off_t j = 0; j < h; j++) {
636 for (off_t i = 0; i < w; i++) {
637 sOut[(h - 1 - j) * w + (w - 1 - i)] = sIn[j * w + i];
644 #pragma omp parallel for
646 for (off_t k = 0; k < d; k++) {
647 off_t offset = k * w * h;
648 T *sIn = (T *) (pixIn + offset);
649 T *sOut = (T *) (pixOut + offset);
650 for (off_t j = 0; j < h; j++) {
651 for (off_t i = 0; i < w; i++) {
652 sOut[(w - 1 - i) * h + j] = sIn[j * w + i];
686 ImageRotateFunct<T> imr;
688 if (&imIn == &imOut) {
690 return imr.Rotate(imTmp, count, imOut);
693 return imr.Rotate(imIn, count, imOut);
729 ASSERT_ALLOCATED(&imIn)
730 ASSERT_SAME_SIZE(&imIn, &imOut)
733 typename ImDtTypes<T>::lineType borderBuf =
740 for (
size_t k = 0; k < depth; k++) {
741 typename Image<T>::sliceType lOut = imOut.getSlices()[k];
744 for (
size_t j = 0; j < height; j++, lOut++) {
747 if (z < 0 || z >= (
int) depth || y < 0 || y >= (
int) height)
748 copyLine<T>(borderBuf, lineLen, *lOut);
750 shiftLine<T>(imIn.
getSlices()[z][y], dx, lineLen, *lOut, borderValue);
773 translate<T>(imIn, dx, dy, dz, imOut);
791 return translate<T>(imIn, dx, dy, 0, imOut, borderValue);
804 translate<T>(imIn, dx, dy, 0, imOut);
829 template <
class T>
class ImageResizeFunc
832 ImageResizeFunc(
string method)
834 if (method !=
"linear" && method !=
"trilinear" && method !=
"closest")
835 this->method =
"trilinear";
837 this->method = method;
842 method =
"trilinear";
852 RES_T
resize(Image<T> &imIn,
size_t width,
size_t height,
size_t depth,
853 Image<T> &imOut,
string method =
"trilinear")
855 ASSERT_ALLOCATED(&imIn, &imOut)
856 if (&imIn == &imOut) {
857 Image<T> tmpIm(imIn,
true);
858 return resize(tmpIm, width, height, depth, imIn);
861 size_t dz = imIn.getDepth();
862 if (method ==
"auto") {
866 method = dz > 1 ?
"trilinear" :
"bilinear";
869 if (method ==
"closest") {
871 return resize3DClosest(imIn, width, height, depth, imOut);
873 return resize2DClosest(imIn, width, height, imOut);
876 if (method ==
"bilinear" || method ==
"trilinear") {
878 return resizeTrilinear(imIn, width, height, depth, imOut);
880 return resizeBilinear(imIn, width, height, imOut);
882 ERR_MSG(
"* Unknown method " + method);
886 RES_T
resize(Image<T> &imIn,
size_t width,
size_t height, Image<T> &imOut,
887 string method =
"trilinear")
889 ASSERT_ALLOCATED(&imIn, &imOut)
891 size_t depth = imIn.getDepth();
892 return resize(imIn, width, height, depth, imOut, method);
898 RES_T
scale(Image<T> &imIn,
double kx,
double ky,
double kz,
899 Image<T> &imOut,
string method =
"trilinear")
901 ASSERT_ALLOCATED(&imIn, &imOut)
903 if (&imIn == &imOut) {
904 Image<T> tmpIm(imIn,
true);
905 return scale(tmpIm, kx, ky, kz, imIn);
908 size_t width = imIn.getWidth();
909 size_t height = imIn.getHeight();
910 size_t depth = imIn.getDepth();
913 width = max(1L, lround(kx * width));
915 height = max(1L, lround(ky * height));
917 depth = max(1L, lround(kz * depth));
919 return resize(imIn, width, height, depth, imOut, method);
922 RES_T
scale(Image<T> &imIn,
size_t kx,
size_t ky, Image<T> &imOut,
923 string method =
"trilinear")
925 return scale(imIn, kx, ky, 1., imOut, method);
940 RES_T resize2DClosest(Image<T> &imIn,
size_t sx,
size_t sy, Image<T> &imOut)
942 size_t width = imIn.getWidth();
943 size_t height = imIn.getHeight();
944 size_t depth = imIn.getDepth();
947 return resize3DClosest(imIn, sx, sy, depth, imOut);
950 imOut.setSize(sx, sy, 1);
951 ImageFreezer freeze(imOut);
953 double cx = ((double) (width - 1)) / (sx - 1);
954 double cy = ((double) (height - 1)) / (sy - 1);
956 T *pixIn = imIn.getPixels();
957 T *pixOut = imOut.getPixels();
959 for (
size_t j = 0; j < sy; j++) {
961 int nthreads = Core::getInstance()->getNumberOfThreads();
962 #pragma omp parallel for num_threads(nthreads)
964 for (
size_t i = 0; i < sx; i++) {
965 size_t xo = round(cx * i);
966 size_t yo = round(cy * j);
968 xo = min(xo, width - 1);
969 yo = min(yo, height - 1);
971 T v = pixIn[yo * width + xo];
972 pixOut[j * sx + i] = v;
982 RES_T resize3DClosest(Image<T> &imIn,
size_t sx,
size_t sy,
size_t sz,
985 size_t width = imIn.getWidth();
986 size_t height = imIn.getHeight();
987 size_t depth = imIn.getDepth();
990 return resize2DClosest(imIn, sx, sy, imOut);
992 imOut.setSize(sx, sy, sz);
994 ImageFreezer freeze(imOut);
996 double cx = ((double) (width - 1)) / (sx - 1);
997 double cy = ((double) (height - 1)) / (sy - 1);
998 double cz = ((double) (depth - 1)) / (sz - 1);
1000 T *pixIn = imIn.getPixels();
1001 T *pixOut = imOut.getPixels();
1003 for (
size_t k = 0; k < sz; k++) {
1004 for (
size_t j = 0; j < sy; j++) {
1006 int nthreads = Core::getInstance()->getNumberOfThreads();
1007 #pragma omp parallel for num_threads(nthreads)
1009 for (
size_t i = 0; i < sx; i++) {
1010 size_t xo = round(cx * i);
1011 size_t yo = round(cy * j);
1012 size_t zo = round(cz * k);
1014 xo = min(xo, width - 1);
1015 yo = min(yo, height - 1);
1016 zo = min(zo, depth - 1);
1018 T v = pixIn[(zo * depth + yo) * width + xo];
1019 pixOut[(k * sy + j) * sx + i] = v;
1037 RES_T resizeBilinear(Image<T> &imIn,
size_t sx,
size_t sy, Image<T> &imOut)
1039 off_t width = imIn.getWidth();
1040 off_t height = imIn.getHeight();
1041 off_t depth = imIn.getDepth();
1044 return resizeTrilinear(imIn, sx, sy, depth, imOut);
1047 imOut.setSize(sx, sy, 1);
1048 ImageFreezer freeze(imOut);
1050 double cx = ((double) (width - 1)) / (sx - 1);
1051 double cy = ((double) (height - 1)) / (sy - 1);
1053 T *pixIn = imIn.getPixels();
1054 T *pixOut = imOut.getPixels();
1056 for (
size_t j = 0; j < sy; j++) {
1059 int nthreads = Core::getInstance()->getNumberOfThreads();
1060 #pragma omp parallel for num_threads(nthreads)
1062 for (
size_t i = 0; i < sx; i++) {
1063 Point<double> P(cx * i, cy * j, 0);
1065 off_t xl = (off_t) floor(P.x);
1066 off_t xh = (xl + 1) < width ? xl + 1 : xl;
1067 off_t yl = (off_t) floor(P.y);
1068 off_t yh = (yl + 1) < height ? yl + 1 : yl;
1070 double cxl = xh > xl ? (P.x - xl) : 1.;
1071 double cxh = 1. - cxl;
1072 double cyl = yh > yl ? (P.y - yl) : 1.;
1073 double cyh = 1. - cyl;
1075 T vp = pixIn[yl * dy + xl] * cxh * cyh +
1076 pixIn[yl * dy + xh] * cxl * cyh +
1077 pixIn[yh * dy + xl] * cxh * cyl +
1078 pixIn[yh * dy + xh] * cxl * cyl;
1080 pixOut[j * sx + i] = vp;
1089 RES_T resizeTrilinear(Image<T> &imIn,
size_t sx,
size_t sy,
size_t sz,
1092 off_t width = imIn.getWidth();
1093 off_t height = imIn.getHeight();
1094 off_t depth = imIn.getDepth();
1097 return resizeBilinear(imIn, sx, sy, imOut);
1100 imOut.setSize(sx, sy, sz);
1101 ImageFreezer freeze(imOut);
1103 double cx = ((double) (width - 1)) / (sx - 1);
1104 double cy = ((double) (height - 1)) / (sy - 1);
1105 double cz = ((double) (depth - 1)) / (sz - 1);
1107 T *pixIn = imIn.getPixels();
1108 T *pixOut = imOut.getPixels();
1110 for (
size_t k = 0; k < sz; k++) {
1111 off_t dz = width * height;
1112 for (
size_t j = 0; j < sy; j++) {
1115 int nthreads = Core::getInstance()->getNumberOfThreads();
1116 #pragma omp parallel for num_threads(nthreads)
1118 for (
size_t i = 0; i < sx; i++) {
1119 Point<double> P(cx * i, cy * j, cz * k);
1121 off_t xl = floor(P.x);
1122 off_t xh = (xl + 1) < width ? xl + 1 : xl;
1123 off_t yl = floor(P.y);
1124 off_t yh = (yl + 1) < height ? yl + 1 : yl;
1125 off_t zl = floor(P.z);
1126 off_t zh = (zl + 1) < depth ? zl + 1 : zl;
1128 double cxl = xh > xl ? (P.x - xl) : 1.;
1129 double cxh = 1. - cxl;
1130 double cyl = yh > yl ? (P.y - yl) : 1.;
1131 double cyh = 1. - cyl;
1132 double czl = zh > zl ? (P.z - zl) : 1.;
1133 double czh = 1. - czl;
1135 T vp = pixIn[zl * dz + yl * dy + xl] * cxh * cyh * czh +
1136 pixIn[zl * dz + yl * dy + xh] * cxl * cyh * czh +
1137 pixIn[zl * dz + yh * dy + xl] * cxh * cyl * czh +
1138 pixIn[zl * dz + yh * dy + xh] * cxl * cyl * czh +
1139 pixIn[zh * dz + yl * dy + xl] * cxh * cyh * czl +
1140 pixIn[zh * dz + yl * dy + xh] * cxl * cyh * czl +
1141 pixIn[zh * dz + yh * dy + xl] * cxh * cyl * czl +
1142 pixIn[zh * dz + yh * dy + xh] * cxl * cyl * czl;
1144 pixOut[(k * sy + j) * sx + i] = vp;
1179 template <
typename T>
1181 Image<T> &imOut,
string method =
"trilinear")
1183 ASSERT_ALLOCATED(&imIn, &imOut)
1184 ImageResizeFunc<T> func(method);
1185 return func.resize(imIn, sx, sy, sz, imOut, method);
1201 template <
typename T>
1203 string method =
"trilinear")
1205 ASSERT_ALLOCATED(&imIn, &imOut)
1206 size_t depth = imOut.getDepth();
1208 ImageResizeFunc<T> func(method);
1209 return func.resize(imIn, sx, sy, depth, imOut, method);
1226 template <
typename T>
1228 string method =
"trilinear")
1230 ASSERT_ALLOCATED(&imIn, &imOut)
1231 size_t width = imOut.getWidth();
1232 size_t height = imOut.getHeight();
1233 size_t depth = imOut.getDepth();
1235 ImageResizeFunc<T> func(method);
1236 return func.resize(imIn, width, height, depth, imOut, method);
1264 template <
typename T>
1266 Image<T> &imOut,
string method =
"trilinear")
1268 ASSERT_ALLOCATED(&imIn, &imOut)
1269 ImageResizeFunc<T> func(method);
1270 return func.scale(imIn, kx, ky, kz, imOut, method);
1285 template <
typename T>
1287 string method =
"trilinear")
1289 ASSERT_ALLOCATED(&imIn, &imOut)
1290 ImageResizeFunc<T> func(method);
1291 return func.scale(imIn, kx, ky, 1., imOut, method);
1307 template <
typename T>
1309 string method =
"trilinear")
1311 ASSERT_ALLOCATED(&imIn, &imOut)
1312 ImageResizeFunc<T> func(method);
1313 return func.scale(imIn, k, k, k, imOut, method);
1327 RES_T resizeClosest(Image<T> &imIn,
size_t sx,
size_t sy, Image<T> &imOut)
1329 ASSERT_ALLOCATED(&imIn)
1331 if (&imIn == &imOut) {
1332 Image<T> tmpIm(imIn,
true);
1333 return resizeClosest(tmpIm, sx, sy, imIn);
1336 ImageFreezer freeze(imOut);
1338 imOut.setSize(sx, sy);
1340 ASSERT_ALLOCATED(&imOut)
1342 size_t w = imIn.getWidth();
1343 size_t h = imIn.getHeight();
1345 typedef typename Image<T>::lineType lineType;
1347 lineType pixIn = imIn.getPixels();
1348 lineType pixOut = imOut.getPixels();
1350 size_t A, B, C, D,
maxVal = numeric_limits<T>::max();
1353 double x_ratio = ((double) (w)) / sx;
1354 double y_ratio = ((double) (h)) / sy;
1355 double x_diff, y_diff;
1358 for (
size_t i = 0; i < sy; i++) {
1359 for (
size_t j = 0; j < sx; j++) {
1360 x = (int) (x_ratio * j);
1361 y = (int) (y_ratio * i);
1362 x_diff = (x_ratio * j) - x;
1363 y_diff = (y_ratio * i) - y;
1366 A = size_t(pixIn[index]) &
maxVal;
1368 B = size_t(pixIn[index]) &
maxVal;
1370 B = size_t(pixIn[index + 1]) &
maxVal;
1373 C = size_t(pixIn[index + w]) &
maxVal;
1375 C = size_t(pixIn[index]) &
maxVal;
1383 D = size_t(pixIn[myindex]) &
maxVal;
1386 if ((x_diff < 0.5) && (y_diff < 0.5)) {
1387 pixOut[offset++] = A;
1388 }
else if (x_diff < 0.5) {
1389 pixOut[offset++] = C;
1390 }
else if (y_diff < 0.5) {
1391 pixOut[offset++] = B;
1393 pixOut[offset++] = D;
1405 template <
class T> RES_T resizeClosest(Image<T> &imIn, Image<T> &imOut)
1407 return resizeClosest(imIn, imOut.getWidth(), imOut.getHeight(), imOut);
1413 template <
class T> RES_T resizeClosest(Image<T> &imIn, UINT sx, UINT sy)
1415 ASSERT_ALLOCATED(&imIn)
1416 Image<T> tmpIm(imIn,
true);
1417 imIn.setSize(sx, sy);
1418 return resizeClosest<T>(tmpIm, imIn);
1429 RES_T
resize(Image<T> &imIn,
size_t sx,
size_t sy, Image<T> &imOut)
1431 ASSERT_ALLOCATED(&imIn)
1433 if (&imIn == &imOut) {
1434 Image<T> tmpIm(imIn,
true);
1435 return resize(tmpIm, sx, sy, imIn);
1438 ImageFreezer freeze(imOut);
1440 imOut.setSize(sx, sy);
1442 ASSERT_ALLOCATED(&imOut)
1444 size_t w = imIn.getWidth();
1445 size_t h = imIn.getHeight();
1447 typedef typename Image<T>::lineType lineType;
1449 lineType pixIn = imIn.getPixels();
1450 lineType pixOut = imOut.getPixels();
1452 size_t A, B, C, D,
maxVal = numeric_limits<T>::max();
1455 double x_ratio = ((double) (w - 1)) / sx;
1456 double y_ratio = ((double) (h - 1)) / sy;
1457 double x_diff, y_diff;
1460 for (
size_t i = 0; i < sy; i++) {
1461 for (
size_t j = 0; j < sx; j++) {
1462 x = (int) (x_ratio * j);
1463 y = (int) (y_ratio * i);
1464 x_diff = (x_ratio * j) - x;
1465 y_diff = (y_ratio * i) - y;
1468 A = size_t(pixIn[index]) &
maxVal;
1469 B = size_t(pixIn[index + 1]) &
maxVal;
1470 C = size_t(pixIn[index + w]) &
maxVal;
1471 D = size_t(pixIn[index + w + 1]) &
maxVal;
1475 T(A * (1. - x_diff) * (1. - y_diff) + B * (x_diff) * (1. - y_diff) +
1476 C * (y_diff) * (1. - x_diff) + D * (x_diff * y_diff));
1487 template <
class T> RES_T
resize(Image<T> &imIn, Image<T> &imOut)
1489 return resize(imIn, imOut.getWidth(), imOut.getHeight(), imOut);
1495 template <
class T> RES_T
resize(Image<T> &imIn, UINT sx, UINT sy)
1498 ASSERT_ALLOCATED(&imIn)
1499 Image<T> tmpIm(imIn,
true);
1501 imIn.setSize(sx, sy);
1502 return resize<T>(tmpIm, imIn);
1510 RES_T
scale(Image<T> &imIn,
double cx,
double cy, Image<T> &imOut)
1512 return resize<T>(imIn,
size_t(imIn.getWidth() * cx),
1513 size_t(imIn.getHeight() * cy), imOut);
1519 template <
class T> RES_T
scale(Image<T> &imIn,
double cx,
double cy)
1521 ASSERT_ALLOCATED(&imIn)
1522 Image<T> tmpIm(imIn,
true);
1523 return resize(tmpIm, cx, cy, imIn);
1531 RES_T scaleClosest(Image<T> &imIn,
double cx,
double cy, Image<T> &imOut)
1533 return resizeClosest<T>(imIn,
size_t(imIn.getWidth() * cx),
1534 size_t(imIn.getHeight() * cy), imOut);
1541 template <
class T> RES_T scaleClosest(Image<T> &imIn,
double cx,
double cy)
1543 ASSERT_ALLOCATED(&imIn)
1544 Image<T> tmpIm(imIn,
true);
1545 return resizeClosest(tmpIm, cx, cy, imIn);
size_t getDepth() const
Get image depth (Z)
Definition: DBaseImage.h:90
void getSize(size_t *w, size_t *h, size_t *d) const
Get image size.
Definition: DBaseImage.h:118
size_t getWidth() const
Get image width.
Definition: DBaseImage.h:80
size_t getPixelCount() const
Get the number of pixels.
Definition: DBaseImage.h:160
UINT getDimension() const
Get dimension (2D or 3D)
Definition: DBaseImage.h:102
size_t getHeight() const
Get image height.
Definition: DBaseImage.h:85
Definition: DBaseImage.h:386
volType getSlices() const
Get an array containing the start offset of each slice.
Definition: DImage.hpp:117
lineType getPixels() const
Get the pixels as a 1D array.
Definition: DImage.hpp:105
Definition: DImage.hpp:484
Definition: DBaseImageOperations.hpp:73
RES_T fill(Image< T > &imOut, const T &value)
fill() - Fill an image with a given value.
Definition: DImageArith.hpp:1456
bool isBinary(const Image< T > &imIn)
isBinary() - Test if an image is binary.
Definition: DMeasures.hpp:1402
T maxVal(const Image< T > &imIn, bool onlyNonZero=false)
maxVal() - Max value of an image
Definition: DMeasures.hpp:348
Definition: DTypes.hpp:88
Definition: DBaseImageOperations.hxx:39