image_correlation.c
Go to the documentation of this file.
00001 /****************************************************************/
00002 /* image_correlation.c
00003 /* rectangular window match: image-correlation pattern window ...
00004 /* linear match: circular-correlation pattern target num_components
00005 /* gcc -c -Di386 -DLinux -w -DGCC  -fpic  -I../c -O image_correlation.c;
00006    ld -shared -o image_correlation.so image_correlation.o
00007 /* cc -c -O -Dsun4 -Bstatic -I../../c cor.c
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 /*  printf("imgp=%x\n", imgp); */
00029   piximg->imgary=
00030         (elmtypeof(imgp)==ELM_FOREIGN)?
00031                 ((unsigned char *)imgp->c.ivec.iv[0]) :
00032                 (imgp->c.str.chars);
00033 /*  printf("imgary=%x\n", piximg->imgary); */
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       /* compute correlation for a particular window */
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       /* correlation factor for a window is obtained in corsum */
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       /* try a next window */
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 /* (IMAGE-CORRELATION image pattern x y size threshold) */
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 /* Actually, this is a linear correlation. */
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   }


euslisp
Author(s): Toshihiro Matsui
autogenerated on Thu Sep 3 2015 10:36:19