reduceGrayScale.cc 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. #include <math.h>
  2. #include <assert.h>
  3. #include <string.h>
  4. #include "mex.h"
  5. // reduce(im) resizes im to half its size, using a 5-tap binomial filter for anti-aliasing
  6. // (see Burt & Adelson's Laplacian Pyramid paper)
  7. // reduce each column
  8. // result is transposed, so we can apply it twice for a complete reduction
  9. void reduce1dtran(double *src, int sheight, double *dst, int dheight,
  10. int width) {
  11. // resize each column
  12. bzero(dst, width*dheight*sizeof(double));
  13. int y;
  14. double *s, *d;
  15. for (int x = 0; x < width; x++) {
  16. s = src + x*sheight;
  17. d = dst + x;
  18. // First row
  19. *d = s[0]*.6875 + s[1]*.2500 + s[2]*.0625;
  20. for (y = 1; y < dheight-2; y++) {
  21. s += 2;
  22. d += width;
  23. *d = s[-2]*0.0625 + s[-1]*.25 + s[0]*.375 + s[1]*.25 + s[2]*.0625;
  24. }
  25. // Last two rows
  26. s += 2;
  27. d += width;
  28. if (dheight*2 <= sheight) {
  29. *d = s[-2]*0.0625 + s[-1]*.25 + s[0]*.375 + s[1]*.25 + s[2]*.0625;
  30. } else {
  31. *d = s[1]*.3125 + s[0]*.3750 + s[-1]*.2500 + s[-2]*.0625;
  32. }
  33. s += 2;
  34. d += width;
  35. *d = s[0]*.6875 + s[-1]*.2500 + s[-2]*.0625;
  36. }
  37. }
  38. // main function
  39. // takes a double color image and a scaling factor
  40. // returns resized image
  41. mxArray *reduceGrayScale(const mxArray *mxsrc) {
  42. double *src = (double *)mxGetPr(mxsrc);
  43. const int *sdims = mxGetDimensions(mxsrc);
  44. if (mxGetNumberOfDimensions(mxsrc) != 2 ||
  45. mxGetClassID(mxsrc) != mxDOUBLE_CLASS)
  46. mexErrMsgTxt("Invalid input - no gray scale double image given!");
  47. int ddims[2];
  48. ddims[0] = (int)round(sdims[0]*.5);
  49. ddims[1] = (int)round(sdims[1]*.5);
  50. if (sdims[0] < 5|| sdims[1] < 5)
  51. mexErrMsgTxt("Minimum size of image is 5x5");
  52. mxArray *mxdst = mxCreateNumericArray(2, ddims, mxDOUBLE_CLASS, mxREAL);
  53. double *dst = (double *)mxGetPr(mxdst);
  54. double *tmp = (double *)mxCalloc(ddims[0]*sdims[1], sizeof(double));
  55. reduce1dtran(src, sdims[0], tmp, ddims[0], sdims[1]);
  56. reduce1dtran(tmp, sdims[1], dst, ddims[1], ddims[0]);
  57. mxFree(tmp);
  58. return mxdst;
  59. }
  60. // matlab entry point
  61. // dst = resize(src, scale)
  62. // image should be gray scale with double values
  63. void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
  64. if (nrhs != 1)
  65. mexErrMsgTxt("Wrong number of inputs");
  66. if (nlhs != 1)
  67. mexErrMsgTxt("Wrong number of outputs");
  68. plhs[0] = reduceGrayScale(prhs[0]);
  69. }
  70. /**********
  71. d = repmat([1:6]',[1 5 3]);
  72. a = reduce(d);
  73. *********/