Beispiel #1
0
static void
create_eyes(ModeInfo * mi, Eyes * e, Eyes * eyes, int num_eyes)
{
	EyeScrInfo *ep = &eye_info[MI_SCREEN(mi)];
	Display    *display = MI_DISPLAY(mi);
	Window      window = MI_WINDOW(mi);
	int         win_width = MI_WIDTH(mi);
	int         win_height = MI_HEIGHT(mi);
	unsigned long black_pixel = MI_BLACK_PIXEL(mi);
	unsigned long white_pixel = MI_WHITE_PIXEL(mi);
	Bool        iconic = MI_IS_ICONIC(mi);
	Pixmap      pix = e->pixmap;	/* preserve pixmap handle */
	int         w = e->width;	/* remember last w/h */
	int         h = e->height;
	int         npixels = MI_NPIXELS(mi);	/* num colors in colormap */
	int         cycs = MI_CYCLES(mi);	/* affects eye lifetime */
	int         maxw = win_width / 2;	/* widest eyes can be */
	int         color, lid_color;
	int         i;

	(void) memset((char *) e, 0, sizeof (Eyes));	/* wipe everything */
	e->pixmap = pix;	/* remember Pixmap handle */

	/* sanity check the cycles value */
	if (cycs < 1)
		cycs = 1;
	if (cycs > MAX_CYCLES)
		cycs = MAX_CYCLES;
	e->time_to_die = (unsigned long) LIFE_MIN + NRAND(LIFE_RANGE);
	e->time_to_die *= (unsigned long) cycs;		/* multiply life by cycles */
	e->time_to_die += ep->time;

	e->pupil_pixel = black_pixel;	/* pupil is always black */

	if (MI_NPIXELS(mi) <= 2) {
		/* TODO: stipple the eyelid? */
		e->eyelid_pixel = black_pixel;
		e->eyeball_pixel = white_pixel;
	} else {
		lid_color = NRAND(npixels);
		e->eyelid_pixel = MI_PIXEL(mi, lid_color);

		while ((color = NRAND(npixels + 5)) == lid_color) {
			/* empty */
		}
		if (color >= npixels) {
			/* give white a little better chance */
			e->eyeball_pixel = white_pixel;
		} else {
			e->eyeball_pixel = MI_PIXEL(mi, color);
		}
	}

	if (iconic) {
		/* only one pair of eyes, fills entire window */
		e->width = win_width;
		e->height = win_height;
	} else {
		if (maxw - MIN_EYE_SIZE > MIN_EYE_SIZE)
			e->width = NRAND(maxw - MIN_EYE_SIZE) + MIN_EYE_SIZE;
		else
			e->width = NRAND(MIN_EYE_SIZE) + MIN_EYE_SIZE;
		e->x = (win_width - e->width > 0) ? NRAND(win_width - e->width) : 0;
		e->height = NRAND(e->width * 3 / 4) + (e->width / 4);
		e->y = (win_height - e->height > 0) ? NRAND(win_height - e->height) : 0;

		/* check for overlap with other eyes */
		for (i = 0; i < num_eyes; i++) {
			if (&eyes[i] == e) {	/* that's me */
				continue;
			}
			if (eyes_overlap(e, &eyes[i])) {
				/* collision, force retry on next cycle */
				e->time_to_die = 0;
				break;
			}
		}
	}

	/* If the Pixmap is smaller than the new size, make it bigger */
	if ((e->width > w) || (e->height > h)) {
		if (e->pixmap != None) {
			XFreePixmap(display, e->pixmap);
		}
		if ((e->pixmap = XCreatePixmap(display, window,
					  e->width, e->height, MI_DEPTH(mi))) == None) {
			e->width = e->height = 0;
			return;
		}
	}
	/* Set the transformation matrix for this set of eyes
	 * If iconic, make the eyes image one pixel shorter and
	 * skinnier, they seem to fit in the icon box better that way.
	 */
	SetTransform(&e->transform, 0, (iconic) ? e->width - 1 : e->width,
		     (iconic) ? e->height - 1 : e->height, 0,
		     W_MIN_X, W_MAX_X, W_MIN_Y, W_MAX_Y);

	/* clear the offscreen pixmap to background color */
	XSetForeground(display, ep->eyeGC, black_pixel);
	XFillRectangle(display, (Drawable) e->pixmap, ep->eyeGC, 0, 0, e->width, e->height);

	/* make the full eye images in the offscreen Pixmap */
	make_eye(mi, e->pixmap, e, 0, True);
	make_eye(mi, e->pixmap, e, 1, True);
}
Beispiel #2
0
static void
paint_eyes(ModeInfo * mi, Eyes * e, Fly * f, Eyes * eyes, int num_eyes)
{
	EyeScrInfo *ep = &eye_info[MI_SCREEN(mi)];
	Display    *display = MI_DISPLAY(mi);
	Window      window = MI_WINDOW(mi);
	GC          gc = ep->eyeGC;
	Bool        iconic = MI_IS_ICONIC(mi);
	int         focusx = (f->x + (f->width / 2)) - e->x;
	int         focusy = (f->y + (f->height / 2)) - e->y;
	Pixmap      pix = e->pixmap;
	TPoint      point;
	int         i;

	if (pix == None) {
		e->time_to_die = 0;	/* "should not happen" */
	}
	if (ep->time >= e->time_to_die) {
		/* Sorry Bud, your time is up */
		if (e->painted) {
			/* only unpaint it if previously painted */
			XSetForeground(display, gc, MI_BLACK_PIXEL(mi));
			XFillRectangle(display, window, gc, e->x, e->y, e->width, e->height);
		}
		/* randomly place the eyes elsewhere */
		create_eyes(mi, e, eyes, num_eyes);
		pix = e->pixmap;	/* pixmap may have changed */
	}
	/* If the bouncer would intersect this pair of eyes, force the
	 * eyes to move.  This simplifies the code, because we do not
	 * have to deal with drawing the bouncer on top of the eyes.
	 * When trying to do so, there was too much annoying flashing
	 * and ghost images from the undraw.  I decided to observe the
	 * KISS principle and keep it simple.  I think the effect is
	 * better also.
	 * We must draw the flyer on the eyes when iconic, but that is
	 * easy because the eyes repaint the whole box each time.
	 */
	if ((!iconic) && (fly_touches_eye(f, e))) {
		e->time_to_die = 0;
	}
	if (e->time_to_die == 0) {
		return;		/* collides with something */
	}
	/* set the point to look at and compute the pupil position  */
	point.x = Tx(focusx, focusy, &e->transform);
	point.y = Ty(focusx, focusy, &e->transform);
	computePupil(0, point, &(e->pupil[0]));
	computePupil(1, point, &(e->pupil[1]));

	if (e->painted) {
		/* if still looking at the same point, do nothing further */
		if (TPointEqual(e->pupil[0], e->last_pupil[0]) &&
		    TPointEqual(e->pupil[1], e->last_pupil[1])) {
			return;
		}
	}
	for (i = 0; i < 2; i++) {
		/* update the eye, calculates the changed rectangle */
		make_eye(mi, pix, e, i, False);

		/* Only blit the change if the full image has been painted */
		if (e->painted) {
			/* copy the changed rectangle out to the screen */
			XCopyArea(display, pix, window, gc,
				  e->bbox.x, e->bbox.y,
				  (int) e->bbox.width, (int) e->bbox.height,
				  e->x + e->bbox.x, e->y + e->bbox.y);
		}
		/* remember where we're looking, for the next time around */
		e->last_pupil[i] = e->pupil[i];
	}

	/* always do full paint when iconic, eliminates need to track fly */
	if (iconic || (!e->painted)) {
		XCopyArea(display, pix, window, gc, 0, 0,
			  e->width, e->height, e->x, e->y);
	}
	/* when iconic, pretend to never paint, causes full paint each time */
	if (!iconic) {
		e->painted++;	/* note that a paint has been done */
	}
}
Beispiel #3
0
void filter(const float *img, const int rows, const int cols, int * x_pos,int *y_pos,int *width)
// Algorithm inspired by:
// Robust real-time pupil tracking in highly off-axis images
// Lech Świrski Andreas Bulling Neil A. Dodgson
// Computer Laboratory, University of Cambridge, United Kingdom
// Eye Tracking Research & Applications 2012
{
    point_t img_size = {rows,cols};
    int min_h = 16;
    int max_h = 80;
    int h, i, j;
    float best_response = -10000;
    point_t best_pos ={0,0};
    int best_h = 0;
    int h_step = 4;
    int step = 5;

    for (h = min_h; h < max_h; h+=h_step)
        {
            eye_t eye = make_eye(h);
            // printf("inner factor%f outer.factor %f center %i \n",eye.inner.f,eye.outer.f,(int)eye.w_half );
            for (i=0; i<rows-eye.w; i +=step)
            {
                for (j=0; j<cols-eye.w; j+=step)
                {
                    // printf("|%2.0f",img[i * cols + j]);
                    point_t offset = {i,j};
                    float response =  eye.outer.f*area(img,img_size,eye.outer.s,eye.outer.e,offset)
                                     +eye.inner.f*area(img,img_size,eye.inner.s,eye.inner.e,offset);
                    // printf("| %5.2f ",response);
                    if(response > best_response){
                        // printf("!");
                        best_response = response;
                        best_pos = (point_t){i,j};
                        // printf("%i %i", (int)best_pos.r,(int)best_pos.c);
                        best_h = eye.h;
                    }
                }
                // printf("\n");
            }
        }



    // now we refine the search at pixel resolution This hole part can be commented out if needed
    point_t window_lower = {MAX(0,best_pos.r-step+1),MAX(0,best_pos.c-step+1)};
    point_t window_upper = {MIN(img_size.r,best_pos.r+step),MIN(img_size.c,best_pos.c+step)};
    for (h = best_h-h_step+1; h < best_h+h_step; h+=1)
        {
            eye_t eye = make_eye(h);
            // printf("inner factor%f outer.factor %f center %i \n",eye.inner.f,eye.outer.f,(int)eye.w_half );
            for (i=window_lower.r; i<MIN(window_upper.r,img_size.r-eye.w); i +=1)
            {
                for (j=window_lower.c; j<MIN(window_upper.c,img_size.c-eye.w); j +=1)
                {

                    // printf("|%2.0f",img[i * cols + j]);
                    point_t offset = {i,j};
                    float response =  eye.outer.f*area(img,img_size,eye.outer.s,eye.outer.e,offset)
                                     +eye.inner.f*area(img,img_size,eye.inner.s,eye.inner.e,offset);
                    // printf("| %5.2f ",response);
                    if(response > best_response){
                        // printf("!");
                        best_response = response;
                        best_pos = (point_t){i,j};
                        // printf("%i %i", (int)best_pos.r,(int)best_pos.c);
                        best_h = eye.h;
                    }
                }
                // printf("\n");
            }
        }


    // point_t start = {0,0};
    // point_t end = {1,1};
    // printf("FULL IMG SUM %1.0f\n",img[(img_size.r-1) * img_size.c + (img_size.c-1)] );
    // printf("AREA:%f\n",area(img,img_size,start,end,(point_t){0,0}));
    *x_pos = (int)best_pos.r;
    *y_pos = (int)best_pos.c;
    *width = best_h*3;
    }