void drawface(Face *f, int i) { char *tstr; Rectangle r; Point p; if(f == nil) return; if(i<first || i>=last) return; r = facerect(i-first); draw(screen, r, bgrnd, nil, ZP); draw(screen, r, f->bit, f->mask, ZP); r.min.y += Facesize; center(mediumfont, r.min, f->str[Suser], display->black); r.min.y += mediumfont->height; tstr = facetime(f, &f->recent); center(mediumfont, r.min, tstr, display->black); if(f->unknown){ r.min.y -= mediumfont->height + tinyfont->height + 2; for(p.x=-1; p.x<=1; p.x++) for(p.y=-1; p.y<=1; p.y++) center(tinyfont, addpt(r.min, p), f->str[Sdomain], display->white); center(tinyfont, r.min, f->str[Sdomain], display->black); } }
void addface(Face *f) /* always adds at 0 */ { Face **ofaces; Rectangle r0, r1, r; int y, nx, ny; if(f == nil) return; if(first != 0){ first = 0; eresized(0); } findbit(f); nx = nacross; ny = (nfaces+(nx-1)) / nx; lockdisplay(display); for(y=ny; y>=0; y--){ /* move them along */ r0 = facerect(y*nx+0); r1 = facerect(y*nx+1); r = r1; r.max.x = r.min.x + (nx - 1)*(Facesize+Facesep); draw(screen, r, screen, nil, r0.min); /* copy one down from row above */ if(y != 0){ r = facerect((y-1)*nx+nx-1); draw(screen, r0, screen, nil, r.min); } } ofaces = faces; faces = emalloc((nfaces+1)*sizeof(Face*)); memmove(faces+1, ofaces, nfaces*(sizeof(Face*))); free(ofaces); nfaces++; setlast(); drawarrows(); faces[0] = f; drawface(f, 0); flushimage(display, 1); unlockdisplay(display); }
void delface(int j) { Rectangle r0, r1, r; int nx, ny, x, y; if(j < first) first--; else if(j < last){ nx = nacross; ny = (nfaces+(nx-1)) / nx; x = (j-first)%nx; for(y=(j-first)/nx; y<ny; y++){ if(x != nx-1){ /* move them along */ r0 = facerect(y*nx+x); r1 = facerect(y*nx+x+1); r = r0; r.max.x = r.min.x + (nx - x - 1)*(Facesize+Facesep); draw(screen, r, screen, nil, r1.min); } if(y != ny-1){ /* copy one up from row below */ r = facerect((y+1)*nx); draw(screen, facerect(y*nx+nx-1), screen, nil, r.min); } x = 0; } if(last < nfaces) /* first off-screen becomes visible */ drawface(faces[last], last-1); else{ /* clear final spot */ r = facerect(last-first-1); draw(screen, r, bgrnd, nil, r.min); } } freeface(faces[j]); memmove(faces+j, faces+j+1, (nfaces-(j+1))*sizeof(Face*)); nfaces--; setlast(); drawarrows(); }
void DetectEyesAndMouth( // use OpenCV detectors to find the eyes and mouth DetPar& detpar, // io: eye and mouth fields updated, other fields untouched const Image& img) // in: ROI around face (already rotated if necessary) { Rect facerect(cvRound(detpar.x - detpar.width/2), cvRound(detpar.y - detpar.height/2), cvRound(detpar.width), cvRound(detpar.height)); // possibly get the eyes detpar.lex = detpar.ley = INVALID; // mark eyes as unavailable detpar.rex = detpar.rey = INVALID; vec_Rect leyes, reyes; int ileft_best = -1, iright_best = -1; // indices into leyes and reyes if (!leye_det_g.empty()) // do we need the eyes? (depends on model estart field) { DetectAllEyes(leyes, reyes, img, detpar.eyaw, facerect); SelectEyes(ileft_best, iright_best, detpar.eyaw, leyes, reyes, EyeInnerRect(detpar.eyaw, facerect)); if (ileft_best >= 0) RectToImgFrame(detpar.lex, detpar.ley, leyes[ileft_best]); if (iright_best >= 0) RectToImgFrame(detpar.rex, detpar.rey, reyes[iright_best]); } // possibly get the mouth detpar.mouthx = detpar.mouthy = INVALID; // mark mouth as unavailable if (!mouth_det_g.empty()) // do we need the mouth? (depends on model estart field) { vec_Rect mouths; DetectAllMouths(mouths, img, detpar.eyaw, facerect, ileft_best, iright_best, leyes, reyes); if (!mouths.empty()) { int imouth_best = -1; SelectMouth(imouth_best, ileft_best, iright_best, leyes, reyes, mouths, MouthInnerRect(facerect, detpar.eyaw, ileft_best, iright_best, leyes, reyes)); if (imouth_best >= 0) { TweakMouthPosition(mouths, leyes, reyes, ileft_best, iright_best, imouth_best, detpar); RectToImgFrame(detpar.mouthx, detpar.mouthy, mouths[imouth_best]); } } } }