#include #include #include #include #include #include #include "image.h" #include "lib.h" // rotate // // rotate IM into RIM by angle theta. // uses (cx,cy) as centre of rotation (may be off of image) void rotate(float *IM, float *RIM, int xsize, int ysize, int cx, int cy, float theta) { float COS = cos(theta); float SIN = sin(theta); int X,Y; // build RIM for (int y=0;y=xsize) || (Y>=ysize)) { RIM[x+y*xsize]=0; } else { RIM[x+y*xsize]=IM[X+Y*xsize]; } } } } // translate // // translates image im1 into im2 using (tx,ty) as translation vector void translate(float *im1, float *im2, int xsize, int ysize, int tx, int ty) { for (int y=0;y=ysize)) { for (int x=0;x=xsize)) { im2[y*xsize+x]=0; continue; } im2[y*xsize+x]=im1[(y+ty)*xsize+(x+tx)]; } } } // align // // finds the optimal alignment parameters (theta, tx, ty) between two images // (im1, im2). Values of theta in [-theta_range,theta_range] are checked over // theta_steps intervals. Values of tx between [-tx_range,tx_range] are // checked. same for ty. // this routine just attempts to minimize the SSD between image pixels for a // given region starting at (x,y) of size (xrange, yrange) after the first // image has been rotated and translated. void align(float *im1, float *im2, int xsize, int ysize, int x, int y, int xrange, int yrange, float theta_range, int theta_steps, int tx_range, int ty_range, float &theta, int &tx, int &ty) { float *Rimage = new float[xsize*ysize]; float *B1 = Rimage; float *B2 = copy_image(im2,xsize,ysize); smooth_image(B2,xsize,ysize,0.5); float BestTheta; int BestTX; int BestTY; unsigned int BestScore=0xFFFFFFFF; // attempt to align image by rotating, blurring, translating for (float THETA = -theta_range; THETA<=theta_range; THETA=THETA+(2*theta_range/theta_steps)) { // rotate im1 into Rimage rotate(im1, Rimage, xsize, ysize, xsize/2, ysize/2, THETA); // blur B1 (Rimage) and B2 smooth_image(B1,xsize,ysize,0.5); // now we minimize the sum of squared differences between a // translated copy of B1 and B2 // we only inspect the bounded region specified by x,y,xrange,yrange int whichx, whichy; unsigned int cost=0xFFFFFFFF; for (int TY=-ty_range;TY<=ty_range;TY++) for (int TX=-tx_range;TX<=tx_range;TX++) { unsigned int thesum=0; for (int Y=y;Ythresh) { nxmap[i]=xmap[i]; nymap[i]=ymap[i]; } } } // mask_under_thresh // // masks off sections of image im where disparity (xmap,ymap) is below thresh void mask_under_thresh(float *im, int *xmap, int *ymap, int xsize, int ysize, int thresh) { for (int i=0;ithresh) im[i]=0; } } // save_disp // // converts a disparity file to a pair of pgms and saves them void save_disp(char *filename, int *dx, int *dy, int x, int y) { float *pgmx=make_image(x,y); float *pgmy=make_image(x,y); for (int i=0;i=sizex) || (y<0) || (y>=sizey)) return 0; // if ((mask[y*sizex+x]==col)) return 0; if ((dx[y*sizex+x]==0) && (dy[y*sizex+x]==0)) return 0; int count=1; mask[y*sizex+x]=col; dx[y*sizex+x]=0; dy[y*sizex+x]=0; for (int i=-thresh;i<=thresh;i++) for (int j=-thresh;j<=thresh;j++) count+=build_group(dx,dy,mask,sizex,sizey,x+j,y+i,thresh,col); return count; } // compute_xy_histogram // // counts up the number of pixels in each row & column void compute_xy_histogram(int *mask, int *xhist, int *yhist, int xsize, int ysize) { for (int y=0;y=0;x--) if (xhist[x]) { xmax=x; break; } // move x bounds inward until Pxcount pixels remain for (int count=xcount;;) { xhist[xmin]--; if (xhist[xmin]==0) xmin++; count--; if (count<=Pxcount) break; xhist[xmax]--; if (xhist[xmax]==0) xmax--; count--; if (count<=Pxcount) break; } // xmin,xmax are now the 100P% bounds on the blob for (int y=0;y=0;y--) if (yhist[y]) { ymax=y; break; } // move y bounds inward until Pycount pixels remain for (int count=ycount;;) { yhist[ymin]--; if (yhist[ymin]==0) ymin++; count--; if (count<=Pycount) break; yhist[ymax]--; if (yhist[ymax]==0) ymax--; count--; if (count<=Pycount) break; } // ymin,ymax are now the 100P% bounds on the blob x1=xmin; x2=xmax; y1=ymin; y2=ymax; cx=xcentre; cy=ycentre; }