c++ - How to compile including a .h file using mex in MATLAB? -
i'm trying compile piece of code download website.
but there issues when compile mex
function i'm using mex -i./ -l/lib convolve.cpp
(.h , .cpp file in same folder,my current folder)
i don't know it's correct or not.
but matlab says
error using mex /tmp/mex_100625252862836_11288/convolve.o: in function `internal_reduce(double*, int, int, double*, double*, int, int, int, int, int, int, int, int, double*, char*)': convolve.cpp:(.text+0xa2): undefined reference `edge_function(char*)' /tmp/mex_100625252862836_11288/convolve.o: in function `internal_expand(double*, double*, double*, int, int, int, int, int, int, int, int, double*, int, int, char*)': convolve.cpp:(.text+0xae4): undefined reference `edge_function(char*)' collect2: error: ld returned 1 exit status
this .h file
/* ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; file: convolve.h ;;; author: simoncelli ;;; description: header file convolve.c ;;; creation date: ;;; ---------------------------------------------------------------- ;;; object-based vision , image understanding system (obvius), ;;; copyright 1988, vision science group, media laboratory, ;;; massachusetts institute of technology. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; */ #include <stdio.h> #include <stdlib.h> #define abs(x) (((x)>=0) ? (x) : (-(x))) #define root2 1.4142135623730951 #define reduce 0 #define expand 1 #define == #define isnt != #define , && #define or || typedef int (*fptr)(register double *,register int ,int ,int ,int ,register double *,int); typedef struct { char *name; fptr func; } edge_handler; fptr edge_function(char *edges); int internal_reduce(register double *image,register int x_dim,int y_dim, double *filt, register double *temp,register int x_fdim,int y_fdim, int x_start,register int x_step, int x_stop, int y_start,register int y_step,int y_stop, register double *result, char *edges); int internal_expand(register double *image,double *filt,register double *temp,register int x_fdim,int y_fdim, int x_start,register int x_step,int x_stop,int y_start,register int y_step,int y_stop, register double *result,register int x_dim,int y_dim,char *edges); int internal_wrap_reduce(double *image,register int x_dim,register int y_dim, register double *filt,register int x_fdim,register int y_fdim, int x_start,int x_step,int x_stop,int y_start,int y_step,int y_stop, register double *result); int internal_wrap_expand(double *image, register double *filt,register int x_fdim,register int y_fdim, int x_start,int x_step,int x_stop,int y_start,int y_step,int y_stop, register double *result,register int x_dim,register int y_dim);
and .cpp file
/* ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; file: convolve.c ;;; author: eero simoncelli ;;; description: general convolution code 2d images ;;; creation date: spring, 1987. ;;; modifications: ;;; 10/89: approximately optimized choice of register vars on sparcs. ;;; 6/96: switched array types double float. ;;; 2/97: made more robust , readable. added stop arguments. ;;; 8/97: bug: when calling internal_reduce edges in {reflect1,repeat, ;;; extend} , filter dimension. solution: embed filter ;;; in upper-left corner of filter odd y , x dimensions. ;;; ---------------------------------------------------------------- ;;; object-based vision , image understanding system (obvius), ;;; copyright 1988, vision science group, media laboratory, ;;; massachusetts institute of technology. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; */ #include <stdio.h> #include <math.h> #include "convolve.h" /* -------------------------------------------------------------------- correlate filt image, subsampling according start, step, , stop parameters, values placed result array. result dimensions should ceil((stop-start)/step). temp should pointer temporary double array size of filter. edges string specifying how handle boundaries -- see edges.c. convolution done in 9 sections, border sections use specially computed edge-handling filters (see edges.c). origin of filter assumed (floor(x_fdim/2), floor(y_fdim/2)). ------------------------------------------------------------------------ */ /* abstract out inner product computation */ #define inprod(xcnr,ycnr) \ { \ sum=0.0; \ (im_pos=ycnr*x_dim+xcnr, filt_pos=0, x_filt_stop=x_fdim; \ x_filt_stop<=filt_size; \ im_pos+=(x_dim-x_fdim), x_filt_stop+=x_fdim) \ (; \ filt_pos<x_filt_stop; \ filt_pos++, im_pos++) \ sum+= image[im_pos]*temp[filt_pos]; \ result[res_pos] = sum; \ } int internal_reduce(register double *image,register int x_dim,int y_dim, double *filt, register double *temp,register int x_fdim,int y_fdim, int x_start,register int x_step, int x_stop, int y_start,register int y_step,int y_stop, register double *result, char *edges) /*register double *image, *temp; register int x_fdim, x_dim; register double *result; register int x_step, y_step; int x_start, y_start; int x_stop, y_stop; double *filt; int y_dim, y_fdim; char *edges;*/ { register double sum; register int filt_pos, im_pos, x_filt_stop; register int x_pos, filt_size = x_fdim*y_fdim; register int y_pos, res_pos; register int y_ctr_stop = y_dim - ((y_fdim==1)?0:y_fdim); register int x_ctr_stop = x_dim - ((x_fdim==1)?0:x_fdim); register int x_res_dim = (x_stop-x_start+x_step-1)/x_step; int x_ctr_start = ((x_fdim==1)?0:1); int y_ctr_start = ((y_fdim==1)?0:1); int x_fmid = x_fdim/2; int y_fmid = y_fdim/2; int base_res_pos; fptr reflect = edge_function(edges); /* edge-handling function */ if (!reflect) return(-1); /* shift start/stop coords filter upper left hand corner */ x_start -= x_fmid; y_start -= y_fmid; x_stop -= x_fmid; y_stop -= y_fmid; if (x_stop < x_ctr_stop) x_ctr_stop = x_stop; if (y_stop < y_ctr_stop) y_ctr_stop = y_stop; (res_pos=0, y_pos=y_start; /* top rows */ y_pos<y_ctr_start; y_pos+=y_step) { (x_pos=x_start; /* top-left corner */ x_pos<x_ctr_start; x_pos+=x_step, res_pos++) { (*reflect)(filt,x_fdim,y_fdim,x_pos-1,y_pos-1,temp,reduce); inprod(0,0) } (*reflect)(filt,x_fdim,y_fdim,0,y_pos-1,temp,reduce); (; /* top edge */ x_pos<x_ctr_stop; x_pos+=x_step, res_pos++) inprod(x_pos,0) (; /* top-right corner */ x_pos<x_stop; x_pos+=x_step, res_pos++) { (*reflect)(filt,x_fdim,y_fdim,x_pos-x_ctr_stop+1,y_pos-1,temp,reduce); inprod(x_ctr_stop,0) } } /* end top rows */ y_ctr_start = y_pos; /* hold location of top */ (base_res_pos=res_pos, x_pos=x_start; /* left edge */ x_pos<x_ctr_start; x_pos+=x_step, base_res_pos++) { (*reflect)(filt,x_fdim,y_fdim,x_pos-1,0,temp,reduce); (y_pos=y_ctr_start, res_pos=base_res_pos; y_pos<y_ctr_stop; y_pos+=y_step, res_pos+=x_res_dim) inprod(0,y_pos) } (*reflect)(filt,x_fdim,y_fdim,0,0,temp,reduce); (; /* center */ x_pos<x_ctr_stop; x_pos+=x_step, base_res_pos++) (y_pos=y_ctr_start, res_pos=base_res_pos; y_pos<y_ctr_stop; y_pos+=y_step, res_pos+=x_res_dim) inprod(x_pos,y_pos) (; /* right edge */ x_pos<x_stop; x_pos+=x_step, base_res_pos++) { (*reflect)(filt,x_fdim,y_fdim,x_pos-x_ctr_stop+1,0,temp,reduce); (y_pos=y_ctr_start, res_pos=base_res_pos; y_pos<y_ctr_stop; y_pos+=y_step, res_pos+=x_res_dim) inprod(x_ctr_stop,y_pos) } (res_pos-=(x_res_dim-1); y_pos<y_stop; /* bottom rows */ y_pos+=y_step) { (x_pos=x_start; /* bottom-left corner */ x_pos<x_ctr_start; x_pos+=x_step, res_pos++) { (*reflect)(filt,x_fdim,y_fdim,x_pos-1,y_pos-y_ctr_stop+1,temp,reduce); inprod(0,y_ctr_stop) } (*reflect)(filt,x_fdim,y_fdim,0,y_pos-y_ctr_stop+1,temp,reduce); (; /* bottom edge */ x_pos<x_ctr_stop; x_pos+=x_step, res_pos++) inprod(x_pos,y_ctr_stop) (; /* bottom-right corner */ x_pos<x_stop; x_pos+=x_step, res_pos++) { (*reflect)(filt,x_fdim,y_fdim,x_pos-x_ctr_stop+1,y_pos-y_ctr_stop+1,temp,reduce); inprod(x_ctr_stop,y_ctr_stop) } } /* end bottom */ return(0); } /* end of internal_reduce */ /* -------------------------------------------------------------------- upsample image according start,step, , stop parameters , convolve filt, adding values result array. image dimensions should ceil((stop-start)/step). see description of internal_reduce (above). warning: subroutine destructively modifies result array! ------------------------------------------------------------------------ */ /* abstract out inner product computation */ #define inprod2(xcnr,ycnr) \ { \ val = image[im_pos]; \ (res_pos=ycnr*x_dim+xcnr, filt_pos=0, x_filt_stop=x_fdim; \ x_filt_stop<=filt_size; \ res_pos+=(x_dim-x_fdim), x_filt_stop+=x_fdim) \ (; \ filt_pos<x_filt_stop; \ filt_pos++, res_pos++) \ result[res_pos] += val*temp[filt_pos]; \ } int internal_expand(register double *image,double *filt,register double *temp,register int x_fdim,int y_fdim, int x_start,register int x_step,int x_stop,int y_start,register int y_step,int y_stop, register double *result,register int x_dim,int y_dim,char *edges) /*register double *result, *temp; register int x_fdim, x_dim; register int x_step, y_step; register double *image; int x_start, y_start; double *filt; int y_fdim, y_dim; char *edges;*/ { register double val; register int filt_pos, res_pos, x_filt_stop; register int x_pos, filt_size = x_fdim*y_fdim; register int y_pos, im_pos; register int x_ctr_stop = x_dim - ((x_fdim==1)?0:x_fdim); int y_ctr_stop = (y_dim - ((y_fdim==1)?0:y_fdim)); int x_ctr_start = ((x_fdim==1)?0:1); int y_ctr_start = ((y_fdim==1)?0:1); int x_fmid = x_fdim/2; int y_fmid = y_fdim/2; int base_im_pos, x_im_dim = (x_stop-x_start+x_step-1)/x_step; fptr reflect = edge_function(edges); /* edge-handling function */ if (!reflect) return(-1); /* shift start/stop coords filter upper left hand corner */ x_start -= x_fmid; y_start -= y_fmid; x_stop -= x_fmid; y_stop -= y_fmid; if (x_stop < x_ctr_stop) x_ctr_stop = x_stop; if (y_stop < y_ctr_stop) y_ctr_stop = y_stop; (im_pos=0, y_pos=y_start; /* top rows */ y_pos<y_ctr_start; y_pos+=y_step) { (x_pos=x_start; /* top-left corner */ x_pos<x_ctr_start; x_pos+=x_step, im_pos++) { (*reflect)(filt,x_fdim,y_fdim,x_pos-1,y_pos-1,temp,expand); inprod2(0,0) } (*reflect)(filt,x_fdim,y_fdim,0,y_pos-1,temp,expand); (; /* top edge */ x_pos<x_ctr_stop; x_pos+=x_step, im_pos++) inprod2(x_pos,0) (; /* top-right corner */ x_pos<x_stop; x_pos+=x_step, im_pos++) { (*reflect)(filt,x_fdim,y_fdim,x_pos-x_ctr_stop+1,y_pos-1,temp,expand); inprod2(x_ctr_stop,0) } } /* end top rows */ y_ctr_start = y_pos; /* hold location of top */ (base_im_pos=im_pos, x_pos=x_start; /* left edge */ x_pos<x_ctr_start; x_pos+=x_step, base_im_pos++) { (*reflect)(filt,x_fdim,y_fdim,x_pos-1,0,temp,expand); (y_pos=y_ctr_start, im_pos=base_im_pos; y_pos<y_ctr_stop; y_pos+=y_step, im_pos+=x_im_dim) inprod2(0,y_pos) } (*reflect)(filt,x_fdim,y_fdim,0,0,temp,expand); (; /* center */ x_pos<x_ctr_stop; x_pos+=x_step, base_im_pos++) (y_pos=y_ctr_start, im_pos=base_im_pos; y_pos<y_ctr_stop; y_pos+=y_step, im_pos+=x_im_dim) inprod2(x_pos,y_pos) (; /* right edge */ x_pos<x_stop; x_pos+=x_step, base_im_pos++) { (*reflect)(filt,x_fdim,y_fdim,x_pos-x_ctr_stop+1,0,temp,expand); (y_pos=y_ctr_start, im_pos=base_im_pos; y_pos<y_ctr_stop; y_pos+=y_step, im_pos+=x_im_dim) inprod2(x_ctr_stop,y_pos) } (im_pos-=(x_im_dim-1); y_pos<y_stop; /* bottom rows */ y_pos+=y_step) { (x_pos=x_start; /* bottom-left corner */ x_pos<x_ctr_start; x_pos+=x_step, im_pos++) { (*reflect)(filt,x_fdim,y_fdim,x_pos-1,y_pos-y_ctr_stop+1,temp,expand); inprod2(0,y_ctr_stop) } (*reflect)(filt,x_fdim,y_fdim,0,y_pos-y_ctr_stop+1,temp,expand); (; /* bottom edge */ x_pos<x_ctr_stop; x_pos+=x_step, im_pos++) inprod2(x_pos,y_ctr_stop) (; /* bottom-right corner */ x_pos<x_stop; x_pos+=x_step, im_pos++) { (*reflect)(filt,x_fdim,y_fdim,x_pos-x_ctr_stop+1,y_pos-y_ctr_stop+1,temp,expand); inprod2(x_ctr_stop,y_ctr_stop) } } /* end bottom */ return(0); } /* end of internal_expand */ /* local variables: */ /* buffer-read-only: t */ /* end: */
a lot if me.
(i'm using g++ c++ language compilation)
ubuntu14.04,matlab 2015a 'edges.cpp' file 'edge_function' implemented.
/* ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; file: edges.c ;;; author: eero simoncelli ;;; description: boundary handling routines use convolve.c ;;; creation date: spring 1987. ;;; modified, 6/96, operate on double float arrays. ;;; modified dgp, 4/1/97, support think c. ;;; modified, 8/97: reflect1, reflect2, repeat, extend upgraded ;;; work non-symmetric filters. added qreflect2 handle ;;; even-length qmf's broke under reflect2 modification. ;;; ---------------------------------------------------------------- ;;; object-based vision , image understanding system (obvius), ;;; copyright 1988, vision science group, media laboratory, ;;; massachusetts institute of technology. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; */ /* file contains functions determine how edges handled when performing convolutions of images linear filters. edge handling function local , linear may defined, except (unfortunately) constants cannot added. treat edges if image surrounded gray field, must paste gray image, convolve, , crop out... main convolution functions called internal_reduce , internal_expand , defined in file convolve.c. idea convolution function calls edge handling function computes new filter based on old filter , distance edge of image. example, reflection done reflecting filter through appropriate axis , summing. defined functions listed below. */ #include <stdio.h> #include <math.h> #include <string.h> #include "convolve.h" #define sgn(a) ( ((a)>0)?1:(((a)<0)?-1:0) ) #define clip(a,mn,mx) ( ((a)<(mn))?(mn):(((a)>=(mx))?(mx-1):(a)) ) int nocompute(register double *filt,register int x_dim,int y_dim,int x_pos,int y_pos,register double *result,int r_or_e); int reflect1(register double *filt,register int x_dim,int y_dim,int x_pos,int y_pos,register double *result,int r_or_e); int reflect2(register double *filt,register int x_dim,int y_dim,int x_pos,int y_pos,register double *result,int r_or_e); int repeat(register double *filt,register int x_dim,int y_dim,int x_pos,int y_pos,register double *result,int r_or_e); int zero(register double *filt,register int x_dim,int y_dim,int x_pos,int y_pos,register double *result,int r_or_e); int extend(register double *filt,register int x_dim,int y_dim,int x_pos,int y_pos,register double *result,int r_or_e); int ereflect(register double *filt,register int x_dim,int y_dim,int x_pos,int y_pos,register double *result,int r_or_e); int predict(register double *filt,register int x_dim,int y_dim,int x_pos,int y_pos,register double *result,int r_or_e); int qreflect2(double *filt,int x_dim,int y_dim,int x_pos,int y_pos,double *result,int r_or_e); /* lookup table matching descriptive string edge-handling function */ #if !think_c static edge_handler edge_foos[] = { { "dont-compute", nocompute }, /* 0 output filter touching edge */ { "zero", 0 }, /* 0 outside of image */ { "repeat", repeat }, /* repeat edge pixel */ { "reflect1", reflect1 }, /* reflect edge pixels */ { "reflect2", reflect2 }, /* reflect image, including edge pixels */ { "qreflect2", qreflect2 }, /* reflect image, including edge pixels even-length qmf decompositions */ { "extend", extend }, /* extend (reflect & invert) */ { "ereflect", ereflect }, /* orthogonal qmf reflection */ }; #else /* stupid, think c won't allow initialization of static variables in code resource string addresses. way. 68k code matlab 4 mex file can created think c. however, matlab 5, we'll able use metrowerks codewarrior both 68k , ppc, cludge can dropped when drop support matlab 4. denis pelli, 4/1/97. */ static edge_handler edge_foos[8]; void initializetable(edge_handler edge_foos[]) { static int i=0; if(i>0) return; edge_foos[i].name="dont-compute"; edge_foos[i++].func=nocompute; edge_foos[i].name="zero"; edge_foos[i++].func=zero; edge_foos[i].name="repeat"; edge_foos[i++].func=repeat; edge_foos[i].name="reflect1"; edge_foos[i++].func=reflect1; edge_foos[i].name="reflect2"; edge_foos[i++].func=reflect2; edge_foos[i].name="qreflect2"; edge_foos[i++].func=qreflect2; edge_foos[i].name="extend"; edge_foos[i++].func=extend; edge_foos[i].name="ereflect"; edge_foos[i++].func=ereflect; } #endif /* function looks edge handler id string in structure above, , returns associated function */ fptr edge_function(char *edges) { int i; #if think_c initializetable(edge_foos); #endif (i = 0; i<sizeof(edge_foos)/sizeof(edge_handler); i++) if (strcmp(edges,edge_foos[i].name) 0) return(edge_foos[i].func); printf("error: '%s' not name of valid edge-handler!\n",edges); (i=0; i<sizeof(edge_foos)/sizeof(edge_handler); i++) { if (i 0) printf(" options are: "); else printf(", "); printf("%s",edge_foos[i].name); } printf("\n"); return(0); }
you missing function definition (edge_function actually) either part of external library or defined in separate .cpp/.c file.
Comments
Post a Comment