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 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 /*  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 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       /* compute correlation for a particular window */
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       /* correlation factor for a window is obtained in corsum */
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       /* try a next window */
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 /* (IMAGE-CORRELATION image pattern x y size threshold) */
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 /* Actually, this is a linear correlation. */
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   }


euslisp
Author(s): Toshihiro Matsui
autogenerated on Thu Jun 6 2019 18:05:53