void FacePredict::FaceSynthesis(AAM_Shape &shape, CvMat* texture, IplImage* newImage) { double thisfacewidth = shape.GetWidth(); shape.Scale(stdwidth / thisfacewidth); shape.Translate(-shape.MinX(), -shape.MinY()); AAM_PAW paw; CvMat* points = cvCreateMat (1, __shape.nPoints(), CV_32FC2); CvMemStorage* storage = cvCreateMemStorage(0); paw.Train(shape, points, storage, __paw.GetTri(), false); //the actual shape __AAMRefShape.Translate(-__AAMRefShape.MinX(), -__AAMRefShape.MinY()); //refShape, central point is at (0,0);translate the min to (0,0) double minV, maxV; cvMinMaxLoc(texture, &minV, &maxV); cvConvertScale(texture, texture, 1/(maxV-minV)*255, -minV*255/(maxV-minV)); cvZero(newImage); int x1, x2, y1, y2, idx1 = 0, idx2 = 0; int tri_idx, v1, v2, v3; int minx, miny, maxx, maxy; minx = shape.MinX(); miny = shape.MinY(); maxx = shape.MaxX(); maxy = shape.MaxY(); for(int y = miny; y < maxy; y++) { y1 = y-miny; for(int x = minx; x < maxx; x++) { x1 = x-minx; idx1 = paw.Rect(y1, x1); if(idx1 >= 0) { tri_idx = paw.PixTri(idx1); v1 = paw.Tri(tri_idx, 0); v2 = paw.Tri(tri_idx, 1); v3 = paw.Tri(tri_idx, 2); x2 = paw.Alpha(idx1)*__AAMRefShape[v1].x + paw.Belta(idx1)*__AAMRefShape[v2].x + paw.Gamma(idx1)*__AAMRefShape[v3].x; y2 = paw.Alpha(idx1)*__AAMRefShape[v1].y + paw.Belta(idx1)*__AAMRefShape[v2].y + paw.Gamma(idx1)*__AAMRefShape[v3].y; idx2 = __paw.Rect(y2, x2); if(idx2 < 0) continue; CV_IMAGE_ELEM(newImage, byte, y, 3*x) = cvmGet(texture, 0, 3*idx2); CV_IMAGE_ELEM(newImage, byte, y, 3*x+1) = cvmGet(texture, 0, 3*idx2+1); CV_IMAGE_ELEM(newImage, byte, y, 3*x+2) = cvmGet(texture, 0, 3*idx2+2); } } } cvReleaseMat(&points); cvReleaseMemStorage(&storage); }
//=========================================================================== void AAM_Basic::Draw(IplImage* image, const AAM_Shape& Shape, int type) { if(type == 0) AAM_Common::DrawPoints(image, Shape); else if(type == 1) AAM_Common::DrawTriangles(image, Shape, __cam.__paw.__tri); else if(type == 2) { double minV, maxV; cvMinMaxLoc(__t_m, &minV, &maxV); cvConvertScale(__t_m, __t_m, 255/(maxV-minV), -minV*255/(maxV-minV)); AAM_PAW paw; paw.Train(Shape, __cam.__Points, __cam.__Storage, __cam.__paw.GetTri(), false); AAM_Common::DrawAppearance(image, Shape, __t_m, paw, __cam.__paw); } else fprintf(stderr, "ERROR(%s, %d): Unsupported drawing type\n", __FILE__, __LINE__); }
//============================================================================ void AAM_IC::Draw(IplImage* image, const AAM_Shape& Shape, int type) { if(type == 0) AAM_Common::DrawPoints(image, Shape); else if(type == 1) AAM_Common::DrawTriangles(image, Shape, __paw.__tri); else if(type == 2) { cvGEMM(__error_t, __texture.GetBases(), 1, NULL, 1, __lamda, CV_GEMM_B_T); __texture.CalcTexture(__lamda, __warp_t); AAM_PAW paw; double minV, maxV; cvMinMaxLoc(__warp_t, &minV, &maxV); cvConvertScale(__warp_t, __warp_t, 255/(maxV-minV), -minV*255/(maxV-minV)); paw.Train(Shape, __Points, __Storage, __paw.GetTri(), false); AAM_Common::DrawAppearance(image, Shape, __warp_t, paw, __paw); } else fprintf(stderr, "ERROR(%s, %d): Unsupported drawing type\n", __FILE__, __LINE__); }
//============================================================================ void AAM_CAM::DrawAppearance(IplImage* image, const AAM_Shape& Shape, CvMat* Texture) { AAM_PAW paw; int x1, x2, y1, y2, idx1 = 0, idx2 = 0; int tri_idx, v1, v2, v3; int minx, miny, maxx, maxy; paw.Train(Shape, __Points, __Storage, __paw.GetTri(), false); AAM_Shape refShape = __paw.__referenceshape; double minV, maxV; cvMinMaxLoc(Texture, &minV, &maxV); cvConvertScale(Texture, Texture, 1/(maxV-minV)*255, -minV*255/(maxV-minV)); minx = Shape.MinX(); miny = Shape.MinY(); maxx = Shape.MaxX(); maxy = Shape.MaxY(); for(int y = miny; y < maxy; y++) { y1 = y-miny; for(int x = minx; x < maxx; x++) { x1 = x-minx; idx1 = paw.Rect(y1, x1); if(idx1 >= 0) { tri_idx = paw.PixTri(idx1); v1 = paw.Tri(tri_idx, 0); v2 = paw.Tri(tri_idx, 1); v3 = paw.Tri(tri_idx, 2); x2 = paw.Alpha(idx1)*refShape[v1].x + paw.Belta(idx1)*refShape[v2].x + paw.Gamma(idx1)*refShape[v3].x; y2 = paw.Alpha(idx1)*refShape[v1].y + paw.Belta(idx1)*refShape[v2].y + paw.Gamma(idx1)*refShape[v3].y; idx2 = __paw.Rect(y2, x2); if(idx2 < 0) continue; CV_IMAGE_ELEM(image, byte, y, 3*x) = cvmGet(Texture, 0, 3*idx2); CV_IMAGE_ELEM(image, byte, y, 3*x+1) = cvmGet(Texture, 0, 3*idx2+1); CV_IMAGE_ELEM(image, byte, y, 3*x+2) = cvmGet(Texture, 0, 3*idx2+2); } } } }
//============================================================================ void AAM_Basic::DrawAppearance(IplImage* image) { AAM_Shape Shape; Shape.Mat2Point(__current_s); AAM_PAW paw; paw.Train(Shape, __cam.__Points, __cam.__Storage, __cam.__paw.GetTri(), false); int x1, x2, y1, y2, idx1, idx2; int tri_idx, v1, v2, v3; int xby3, idxby3; int minx, miny, maxx, maxy; AAM_Shape refShape; refShape.Mat2Point(__cam.__MeanS); refShape.Translate(-refShape.MinX(), -refShape.MinY()); double minV, maxV; cvMinMaxLoc(__t_m, &minV, &maxV); cvConvertScale(__t_m, __t_m, 255/(maxV-minV), -minV*255/(maxV-minV)); byte* pimg; double* fastt = __t_m->data.db; minx = Shape.MinX(); miny = Shape.MinY(); maxx = Shape.MaxX(); maxy = Shape.MaxY(); if( minx < 0 ) minx = 0; else if(minx >= image->width) minx = image->width - 1; if( miny < 0 ) miny = 0; else if(miny >= image->height) miny = image->height - 1; if( maxx < 0 ) maxx = 0; else if(maxx >= image->width) maxx = image->height - 1; if( maxy < 0 ) maxy = 0; else if(maxy >= image->height) maxy = image->height - 1; for(int y = miny; y < maxy; y++) { y1 = y-miny; pimg = (byte*)(image->imageData + image->widthStep*y); for(int x = minx; x < maxx; x++) { x1 = x-minx; idx1 = paw.__rect[y1][x1]; if(idx1 >= 0) { tri_idx = paw.PixTri(idx1); v1 = paw.Tri(tri_idx, 0); v2 = paw.Tri(tri_idx, 1); v3 = paw.Tri(tri_idx, 2); x2 = paw.__alpha[idx1]*refShape[v1].x + paw.__belta[idx1]*refShape[v2].x + paw.__gamma[idx1]*refShape[v3].x; y2 = paw.__alpha[idx1]*refShape[v1].y + paw.__belta[idx1]*refShape[v2].y + paw.__gamma[idx1]*refShape[v3].y; xby3 = 3*x; idx2 = __cam.__paw.__rect[y2][x2]; idxby3 = 3*idx2; pimg[xby3] = fastt[idxby3]; pimg[xby3+1] = fastt[idxby3+1]; pimg[xby3+2] = fastt[idxby3+2]; } } } }