/* FEATURE MORPH * */ /* ==================================================================== */ /* includes for graphics */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "DrawSprocket.h" #include /* ==================================================================== */ /* includes for graphics */ #include #include #include /* ==================================================================== */ /* constants */ #define DISPLAY #define SCREEN_WIDTH 400 #define SCREEN_HEIGHT 400 #define LINEFEED printf("\n"); const int WIDTH = 200; const int HEIGHT = 200; const int BYTESIZE = WIDTH*HEIGHT*3; /* ==================================================================== */ /* STRUCTURES */ /* XY structure*/ typedef struct xy_struct { float x,y; } xy_td; /* FEATURE * line in image1: p1,p2; * line in image2: q1,q2 * weigths used in mapping: a,b,p * length of line in image2 */ typedef struct feature_struct { xy_td p1,p2,q1,q2; float a,b,p; float plength,qlength; } feature_td; /* FEATURE LIST*/ typedef struct featureList_struct { int num; feature_td *features; } featureList_td; /* ==================================================================== */ /* globals for graphics*/ DSpContextAttributes gTheContextAttributes; DSpContextReference gTheContext; /* ==================================================================== */ /* static function prototypes for graphics */ static CGrafPtr SetupScreen(void); static void ShutdownScreen(CGrafPtr theFrontBuffer); static AGLContext setupAGL(AGLDrawable win); static void cleanupAGL(AGLContext ctx); /* static void drawGL(); */ static void drawGL(AGLContext ctx, char *values, int numu, int numv); /* ==================================================================== */ /* INITIALIZE */ static void initialize(void) { InitGraf(&qd.thePort); InitFonts(); InitWindows(); InitMenus(); TEInit(); InitDialogs(nil); InitCursor(); HideCursor(); } /* ==================================================================== */ /* function prototypes for feature morph routines */ void fill_rect(char *buffer,int x, int y, int dx, int dy, int r, int g, int b); void init_features(featureList_td *features); void init_buffer(); void morph(featureList_td *features); /* ==================================================================== */ /* images */ char image1[BYTESIZE]; char image2[BYTESIZE]; /* ==================================================================== */ /* MAIN */ void main() { CGrafPtr theScreen; AGLContext ctx; featureList_td features; initialize(); init_features(&features); init_buffer(); morph(&features); #ifdef DISPLAY theScreen = SetupScreen(); /* Setup the OpenGL context */ ctx = setupAGL((AGLDrawable) theScreen); if(!ctx) return; do { drawGL(ctx,image1,WIDTH,HEIGHT); } while (!Button()); /* Cleanup the OpenGL context */ cleanupAGL(ctx); ShutdownScreen(theScreen); ShowCursor(); FlushEvents(everyEvent, 0); ExitToShell(); #endif } /* ==================================================================== */ /* INIT_FEATURES */ void init_features(featureList_td *featureList) { feature_td *featureArray; float v1,v2; int num; int a,b,p; int x1,y1,x2,y2; int i; printf("\n number of features = "); scanf("%d",&num); featureList->num = num; featureArray = (feature_td *)malloc(sizeof(feature_td)*num); featureList->features = featureArray; for (i=0; ifeatures[i].p1.x = x1; featureList->features[i].p1.y = y1; featureList->features[i].p2.x = x2; featureList->features[i].p2.y = y2; printf("\n input image2 feature line (x1,y1,x2,y2):" ); scanf("%d %d %d %d",&x1,&y1,&x2,&y2); featureList->features[i].q1.x = x1; featureList->features[i].q1.y = y1; featureList->features[i].q2.x = x2; featureList->features[i].q2.y = y2; printf("\n input weights (a,b,p):" ); scanf("%d %d %d",&a,&b,&p); LINEFEED featureList->features[i].a = a; featureList->features[i].b = b; featureList->features[i].p = p; v1 = featureList->features[i].p1.x-featureList->features[i].p2.x; v2 = featureList->features[i].p1.y-featureList->features[i].p2.y; featureList->features[i].plength = sqrt(v1*v1+v2*v2); v1 = featureList->features[i].q1.x-featureList->features[i].q2.x; v2 = featureList->features[i].q1.y-featureList->features[i].q2.y; featureList->features[i].qlength = sqrt(v1*v1+v2*v2); } return; } /* ==================================================================== */ /* INIT_BUFFER */ void init_buffer() { fill_rect(image1,0,0,WIDTH,HEIGHT,120,20,20); fill_rect(image1,50,50,10,100,0,0,0); fill_rect(image1,50,100,50,10,0,0,0); fill_rect(image1,50,150,100,10,0,0,0); } /* ==================================================================== */ /* FILL_RECT */ void fill_rect(char *buffer, int x, int y, int dx, int dy, int r, int g, int b) { int index; int i,j; for (i=y; i=0) && (i=0) && (j=0) && (indexnum; k++) { /* get info about kth feature line */ a = featureList->features[k].a; b = featureList->features[k].b; p = featureList->features[k].p; p1.x = featureList->features[k].p1.x; p1.y = featureList->features[k].p1.y; p2.x = featureList->features[k].p2.x; p2.y = featureList->features[k].p2.y; q1.x = featureList->features[k].q1.x; q1.y = featureList->features[k].q1.y; q2.x = featureList->features[k].q2.x; q2.y = featureList->features[k].q2.y; length = featureList->features[k].qlength; /* get local feature coordinate system in image1 */ vp.x = p2.x-p1.x; vp.y = p2.y-p1.y; wp.x = vp.y; wp.y = -vp.x; /* get feature vector in image2 */ vq.x = q2.x-q1.x; vq.y = q2.y-q1.y; /* get vector from first feature point to pixel (image2) */ v.x = j-q1.x; v.y = i-q1.y; /* get perpendicular distance from feature line to pixel (image2) */ s = (v.x*vq.x + v.y*vq.y)/(length*length); t = (v.x*vq.y-v.y*vq.x)/(length*length); /* use (s,t) and vp, wp to map to point in image1 space */ jj = (int)(p1.x + s*vp.x + t*wp.x); ii = (int)(p1.y + s*vp.y + t*wp.y); /* printf("\n %d,%d",ii,jj); */ t = length/(a+t); jdisp += (jj-j)*t; idisp += (ii-i)*t; weight += t; } jdisp /= weight; idisp /= weight; ii = (int)(i+idisp); jj = (int)(j+jdisp); indexD = (WIDTH*i+j)*3; if ( (ii<0) || (ii>=HEIGHT) || (jj<0) || (jj>=WIDTH) ) { image2[indexD] = background[0]; image2[indexD+1] = background[1]; image2[indexD+2] = background[2]; } else { indexS = (WIDTH*ii+jj)*3; image2[indexD] = image1[indexS]; image2[indexD+1] = image1[indexS+1]; image2[indexD+2] = image1[indexS+2]; } } } /* imageSave(image2,WIDTH,HEIGHT,"test.bmp"); */ } /* ============================================================================== */ /* DRAWGL */ static void drawGL(AGLContext ctx, char *values, int numu, int numv) { int i,j; float xl,xr,yb,yt; int pixel; /* Clear color buffer to yellow */ glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); /* Draw a smooth shaded polygon */ for (i=0; i