resizeGrayScale.cc 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. #include <math.h>
  2. #include <assert.h>
  3. #include <string.h>
  4. #include "mex.h"
  5. /*
  6. * Fast image subsampling.
  7. * This is used to construct the feature pyramid.
  8. */
  9. // struct used for caching interpolation values
  10. struct alphainfo {
  11. int si, di;
  12. double alpha;
  13. };
  14. // copy src into dst using pre-computed interpolation values
  15. void alphacopy(double *src, double *dst, struct alphainfo *ofs, int n) {
  16. struct alphainfo *end = ofs + n;
  17. while (ofs != end) {
  18. dst[ofs->di] += ofs->alpha * src[ofs->si];
  19. ofs++;
  20. }
  21. }
  22. // resize along each column
  23. // result is transposed, so we can apply it twice for a complete resize
  24. void resize1dtran(double *src, int sheight, double *dst, int dheight,
  25. int width) {
  26. double scale = (double)dheight/(double)sheight;
  27. double invscale = (double)sheight/(double)dheight;
  28. // we cache the interpolation values since they can be
  29. // shared among different columns
  30. int len = (int)ceil(dheight*invscale) + 2*dheight;
  31. alphainfo ofs[len];
  32. int k = 0;
  33. for (int dy = 0; dy < dheight; dy++) {
  34. double fsy1 = dy * invscale;
  35. double fsy2 = fsy1 + invscale;
  36. int sy1 = (int)ceil(fsy1);
  37. int sy2 = (int)floor(fsy2);
  38. if (sy1 - fsy1 > 1e-3) {
  39. assert(k < len);
  40. assert(sy-1 >= 0);
  41. ofs[k].di = dy*width;
  42. ofs[k].si = sy1-1;
  43. ofs[k++].alpha = (sy1 - fsy1) * scale;
  44. }
  45. for (int sy = sy1; sy < sy2; sy++) {
  46. assert(k < len);
  47. assert(sy < sheight);
  48. ofs[k].di = dy*width;
  49. ofs[k].si = sy;
  50. ofs[k++].alpha = scale;
  51. }
  52. if (fsy2 - sy2 > 1e-3) {
  53. assert(k < len);
  54. assert(sy2 < sheight);
  55. ofs[k].di = dy*width;
  56. ofs[k].si = sy2;
  57. ofs[k++].alpha = (fsy2 - sy2) * scale;
  58. }
  59. }
  60. // resize each column
  61. bzero(dst, width*dheight*sizeof(double));
  62. for (int x = 0; x < width; x++) {
  63. double *s = src + x*sheight;
  64. double *d = dst + x;
  65. alphacopy(s, d, ofs, k);
  66. }
  67. }
  68. // main function
  69. // takes a double color image and a scaling factor
  70. // returns resized image
  71. mxArray *resize(const mxArray *mxsrc, const mxArray *mxscale) {
  72. double *src = (double *)mxGetPr(mxsrc);
  73. const int *sdims = mxGetDimensions(mxsrc);
  74. if (mxGetNumberOfDimensions(mxsrc) != 2 ||
  75. mxGetClassID(mxsrc) != mxDOUBLE_CLASS)
  76. mexErrMsgTxt("Invalid input - double gray scale image expected!");
  77. double scale = mxGetScalar(mxscale);
  78. if (scale > 1)
  79. mexErrMsgTxt("Invalid scaling factor");
  80. int ddims[2];
  81. ddims[0] = (int)round(sdims[0]*scale);
  82. ddims[1] = (int)round(sdims[1]*scale);
  83. mxArray *mxdst = mxCreateNumericArray(2, ddims, mxDOUBLE_CLASS, mxREAL);
  84. double *dst = (double *)mxGetPr(mxdst);
  85. double *tmp = (double *)mxCalloc(ddims[0]*sdims[1], sizeof(double));
  86. resize1dtran(src, sdims[0], tmp, ddims[0], sdims[1]);
  87. resize1dtran(tmp, sdims[1], dst, ddims[1], ddims[0]);
  88. mxFree(tmp);
  89. return mxdst;
  90. }
  91. // matlab entry point
  92. // dst = resize(src, scale)
  93. // image should be color with double values
  94. void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
  95. if (nrhs != 2)
  96. mexErrMsgTxt("Wrong number of inputs");
  97. if (nlhs != 1)
  98. mexErrMsgTxt("Wrong number of outputs");
  99. plhs[0] = resize(prhs[0], prhs[1]);
  100. }