00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "eus.h"
00011 #include "pix.h"
00012 #define abs(x) ((x)<0?-(x):x)
00013 #define imgvec(img,x,y) (&((img)->imgary[(y)*(img)->twidth + x]))
00014
00015 #pragma init (init_object_module)
00016 pointer image_correlation();
00017
00018 static void init_object_module()
00019 { add_module_initializer("image_correlation", image_correlation);}
00020
00021
00022
00023 static void set_pixparams(piximg, eusary)
00024 pixel_image *piximg;
00025 pointer eusary;
00026 { pointer imgp;
00027 imgp=eusary->c.ary.entity;
00028
00029 piximg->imgary=
00030 (elmtypeof(imgp)==ELM_FOREIGN)?
00031 ((unsigned char *)imgp->c.ivec.iv[0]) :
00032 (imgp->c.str.chars);
00033
00034 piximg->depth=8;
00035 piximg->twidth=intval(eusary->c.ary.dim[1]);
00036 piximg->theight=intval(eusary->c.ary.dim[0]);
00037 piximg->tsize=piximg->twidth*piximg->theight;
00038 piximg->width=intval(eusary->c.ary.dim[1]);
00039 piximg->height=intval(eusary->c.ary.dim[0]);
00040 piximg->wsize=piximg->width * piximg->height; }
00041
00042 static int img_correlation1(image,pattern,x,y)
00043 register pixel_image *image, *pattern;
00044 register int x, y;
00045 { register unsigned char *img=image->imgary, *pat=pattern->imgary;
00046 register int i, j;
00047 register int ww=pattern->width;
00048 register long cor, corsum=0;
00049 int tiw=image->twidth, piw=pattern->twidth;
00050 int wh=pattern->height;
00051
00052 img=imgvec(image, x, y);
00053 pat=imgvec(pattern, 0, 0);
00054 for (j=0; j<wh; j++) {
00055 for (i=0; i<ww; i++) {
00056 cor=img[i]-pat[i];
00057 corsum+= abs(cor);}
00058 img+=tiw; pat+=piw;
00059 }
00060 return(corsum);}
00061
00062 struct corinfo {
00063 long corval;
00064 long x,y;
00065 };
00066
00067 static int img_correlation(image,pattern,x0,y0,size,threshold,result)
00068 pixel_image *image, *pattern;
00069 register int size;
00070 register int threshold;
00071 int x0, y0;
00072 struct corinfo *result;
00073 { register unsigned char *img=image->imgary, *pat=pattern->imgary;
00074 register int i, j;
00075 register int x, y;
00076 register int tiw=image->twidth, piw=pattern->twidth;
00077 register int ww=pattern->width;
00078 register long cor, corsum;
00079 register int wh=pattern->height;
00080 int found=0;
00081
00082 for (y=y0; y<y0+size; y++) {
00083 for (x=x0; x<x0+size; x++) {
00084
00085 corsum=0;
00086 img=imgvec(image, x, y);
00087 pat=imgvec(pattern, 0, 0);
00088 for (j=0; j<wh; j++) {
00089 for (i=0; i<ww; i++) {
00090 cor=img[i]-pat[i];
00091 if (cor>0) corsum+=cor;
00092 else corsum-=cor;}
00093 if (corsum>threshold) goto nextwindow;
00094 img+=tiw; pat+=piw; }
00095
00096
00097 if (corsum<threshold) {
00098 if (debug) printf("cor=%ld (%d, %d)\n", corsum, x, y);
00099 found=1;
00100 threshold=corsum;
00101 result->corval=corsum;
00102 result->x=x; result->y=y;};
00103
00104 nextwindow: continue;
00105 } }
00106 return(found);}
00107
00108 static pointer IMAGE_CORRELATION1(ctx,n,argv)
00109 context *ctx;
00110 int n;
00111 pointer argv[];
00112 { pointer arg0, arg1;
00113 pixel_image img,pat;
00114 int x,y, cor;
00115 ckarg(4);
00116 set_pixparams(&img, argv[0]);
00117 set_pixparams(&pat, argv[1]);
00118 x=ckintval(argv[2]); y=ckintval(argv[3]);
00119 cor=img_correlation1(&img, &pat, x, y);
00120 return(makeint(cor));}
00121
00122
00123
00124
00125 static pointer IMAGE_CORRELATION(ctx,n,argv)
00126 context *ctx;
00127 int n;
00128 pointer argv[];
00129 { pointer arg0, arg1;
00130 pixel_image img,pat;
00131 int x,y, cor, size, threshold;
00132 struct { long corval, x, y;} result;
00133 ckarg(6);
00134 set_pixparams(&img, argv[0]);
00135 set_pixparams(&pat, argv[1]);
00136 x=ckintval(argv[2]); y=ckintval(argv[3]);
00137 size=ckintval(argv[4]); threshold=ckintval(argv[5]);
00138 cor=img_correlation(&img, &pat, x, y, size, threshold, &result);
00139 if (cor) {
00140 vpush(makeint(result.corval));
00141 vpush(makeint(result.x));
00142 vpush(makeint(result.y));
00143 return((pointer)stacknlist(ctx,3));}
00144 else return(NIL);}
00145
00146
00147 static pointer CIRCULAR_CORRELATION(ctx,n,argv)
00148
00149 context *ctx;
00150 int n;
00151 pointer argv[];
00152 { unsigned char *pat1, *pat2, pat2x[1024*4];
00153 int len, num_components, total_len, i, j, k, x, y;
00154 int c, cor, min_cor, min_pos, max_cor, avecor, total_cor;
00155 float fcor, flen;
00156 pointer fcorvec, r;
00157 numunion nu;
00158
00159 ckarg(3);
00160 num_components=ckintval(argv[2]);
00161 pat1=get_string(argv[0]);
00162 pat2=get_string(argv[1]);
00163 total_len=vecsize(argv[0]);
00164 if (total_len != vecsize(argv[1])) error(E_VECSIZE);
00165 if (total_len >=1024*3) error(E_ARRAYINDEX);
00166 memcpy(&pat2x[0], pat2, total_len);
00167 memcpy(&pat2x[total_len], pat2, total_len);
00168 len=total_len/num_components;
00169 flen=len;
00170 fcorvec=makevector(C_FLTVECTOR, len);
00171 vpush(fcorvec);
00172
00173 min_pos = -1; min_cor=0x3fffffff; max_cor=0; total_cor=0;
00174
00175 for (i=0; i<len; i++) {
00176 cor=0; x=i*num_components;
00177 for (j=0; j<len; j++) {
00178 c=0; y=j*num_components;
00179 for (k=0; k<num_components; k++) c += abs(pat2x[x+j+k]-pat1[j+k]);
00180 cor += c/num_components; }
00181 if (cor < min_cor) { min_cor=cor; min_pos=i; }
00182 else if (cor>max_cor) max_cor=cor;
00183 total_cor += cor;
00184 fcorvec->c.fvec.fv[i]=(float)cor/total_len;
00185 }
00186 vpush(makeint(min_pos));
00187 vpush(makeflt(min_cor/(flen*num_components)));
00188 vpush(makeflt(total_cor/(flen*num_components*flen)));
00189 vpush(makeflt(max_cor/(len*num_components)));
00190 vpush(fcorvec);
00191 r=stacknlist(ctx,5);
00192 vpop();
00193 return(r);}
00194
00195 pointer image_correlation(ctx,n,argv)
00196 context *ctx;
00197 int n;
00198 pointer argv[];
00199 { pointer mod=argv[0];
00200 defun(ctx,"IMAGE-CORRELATION1",mod,IMAGE_CORRELATION1,NULL);
00201 defun(ctx,"IMAGE-CORRELATION",mod,IMAGE_CORRELATION,NULL);
00202 defun(ctx,"CIRCULAR-CORRELATION",mod,CIRCULAR_CORRELATION,NULL);
00203 return(NIL);
00204 }