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