1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192 |
- #include <math.h>
- #include <assert.h>
- #include <string.h>
- #include "mex.h"
- // reduce(im) resizes im to half its size, using a 5-tap binomial filter for anti-aliasing
- // (see Burt & Adelson's Laplacian Pyramid paper)
- // reduce each column
- // result is transposed, so we can apply it twice for a complete reduction
- void reduce1dtran(double *src, int sheight, double *dst, int dheight,
- int width, int chan) {
- // resize each column of each color channel
- bzero(dst, chan*width*dheight*sizeof(double));
- int y;
- double *s, *d;
- for (int c = 0; c < chan; c++) {
- for (int x = 0; x < width; x++) {
- s = src + c*width*sheight + x*sheight;
- d = dst + c*dheight*width + x;
- // First row
- *d = s[0]*.6875 + s[1]*.2500 + s[2]*.0625;
- for (y = 1; y < dheight-2; y++) {
- s += 2;
- d += width;
- *d = s[-2]*0.0625 + s[-1]*.25 + s[0]*.375 + s[1]*.25 + s[2]*.0625;
- }
- // Last two rows
- s += 2;
- d += width;
- if (dheight*2 <= sheight) {
- *d = s[-2]*0.0625 + s[-1]*.25 + s[0]*.375 + s[1]*.25 + s[2]*.0625;
- } else {
- *d = s[1]*.3125 + s[0]*.3750 + s[-1]*.2500 + s[-2]*.0625;
- }
- s += 2;
- d += width;
- *d = s[0]*.6875 + s[-1]*.2500 + s[-2]*.0625;
- }
- }
- }
- // main function
- // takes a double color image and a scaling factor
- // returns resized image
- mxArray *reduce(const mxArray *mxsrc) {
- double *src = (double *)mxGetPr(mxsrc);
- const int *sdims = mxGetDimensions(mxsrc);
- if (mxGetNumberOfDimensions(mxsrc) != 3 ||
- mxGetClassID(mxsrc) != mxDOUBLE_CLASS)
- mexErrMsgTxt("Invalid input");
- int ddims[3];
- ddims[0] = (int)round(sdims[0]*.5);
- ddims[1] = (int)round(sdims[1]*.5);
- ddims[2] = sdims[2];
- if (sdims[0] < 5|| sdims[1] < 5)
- mexErrMsgTxt("Minimum size of image is 5x5");
- mxArray *mxdst = mxCreateNumericArray(3, ddims, mxDOUBLE_CLASS, mxREAL);
- double *dst = (double *)mxGetPr(mxdst);
- double *tmp = (double *)mxCalloc(ddims[0]*sdims[1]*sdims[2], sizeof(double));
- reduce1dtran(src, sdims[0], tmp, ddims[0], sdims[1], sdims[2]);
- reduce1dtran(tmp, sdims[1], dst, ddims[1], ddims[0], sdims[2]);
- mxFree(tmp);
- return mxdst;
- }
- // matlab entry point
- // dst = resize(src, scale)
- // image should be color with double values
- void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
- if (nrhs != 1)
- mexErrMsgTxt("Wrong number of inputs");
- if (nlhs != 1)
- mexErrMsgTxt("Wrong number of outputs");
- plhs[0] = reduce(prhs[0]);
- }
- /**********
- d = repmat([1:6]',[1 5 3]);
- a = reduce(d);
- *********/
|