//=========================================================================== 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_TDM::Train(const file_lists& pts_files, const file_lists& img_files, const AAM_PAW& m_warp, double texture_percentage /* = 0.975 */, bool registration /* = true */) { int nPoints = m_warp.nPoints(); int nPixels = m_warp.nPix()*3; int nSamples = pts_files.size(); CvMat *AllTextures = cvCreateMat(nSamples, nPixels, CV_64FC1); CvMat * matshape = cvCreateMat(1, nPoints*2, CV_64FC1); for(int i = 0; i < nSamples; i++) { IplImage* image = cvLoadImage(img_files[i].c_str(), -1); AAM_Shape trueshape; if(!trueshape.ReadAnnotations(pts_files[i])) trueshape.ScaleXY(image->width, image->height); trueshape.Point2Mat(matshape); AAM_Common::CheckShape(matshape, image->width, image->height); CvMat t; cvGetRow(AllTextures, &t, i); m_warp.CalcWarpTexture(matshape, image, &t); cvReleaseImage(&image); } cvReleaseMat(&matshape); // align texture so as to minimize the lighting variation AAM_TDM::AlignTextures(AllTextures); //now do pca DoPCA(AllTextures, texture_percentage); if(registration) SaveSeriesTemplate(AllTextures, m_warp); cvReleaseMat(&AllTextures); }
//============================================================================ 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]; } } } }
//============================================================================ void AAM_TDM::SaveSeriesTemplate(const CvMat* AllTextures, const AAM_PAW& m_warp) { LOGD("Saving the face template image...\n"); AAM_Common::MkDir("registration"); AAM_Common::MkDir("Modes"); AAM_Common::MkDir("Tri"); char filename[100]; int i; for(i = 0; i < AllTextures->rows; i++) { CvMat oneTexture; cvGetRow(AllTextures, &oneTexture, i); sprintf(filename, "registration/%d.jpg", i); m_warp.SaveWarpTextureToImage(filename, &oneTexture); } for(int nmodes = 0; nmodes < nModes(); nmodes++) { CvMat oneVar; cvGetRow(__TextureEigenVectors, &oneVar, nmodes); sprintf(filename, "Modes/A%03d.jpg", nmodes+1); m_warp.SaveWarpTextureToImage(filename, &oneVar); } IplImage* templateimg = cvCreateImage (cvSize(m_warp.Width(), m_warp.Height()), IPL_DEPTH_8U, 3); IplImage* convexImage = cvCreateImage (cvSize(m_warp.Width(), m_warp.Height()), IPL_DEPTH_8U, 3); IplImage* TriImage = cvCreateImage (cvSize(m_warp.Width(), m_warp.Height()), IPL_DEPTH_8U, 3); m_warp.SaveWarpTextureToImage("Modes/Template.jpg", __MeanTexture); m_warp.TextureToImage(templateimg, __MeanTexture); cvSetZero(convexImage); for(i = 0; i < m_warp.nTri(); i++) { CvPoint p, q; int ind1, ind2; cvCopy(templateimg, TriImage); ind1 = m_warp.Tri(i, 0); ind2 = m_warp.Tri(i, 1); p = cvPointFrom32f(m_warp.Vertex(ind1)); q = cvPointFrom32f(m_warp.Vertex(ind2)); cvLine(TriImage, p, q, CV_RGB(255, 255, 255)); cvLine(convexImage, p, q, CV_RGB(255, 255, 255)); ind1 = m_warp.Tri(i, 1); ind2 = m_warp.Tri(i, 2); p = cvPointFrom32f(m_warp.Vertex(ind1)); q = cvPointFrom32f(m_warp.Vertex(ind2)); cvLine(TriImage, p, q, CV_RGB(255, 255, 255)); cvLine(convexImage, p, q, CV_RGB(255, 255, 255)); ind1 = m_warp.Tri(i, 2); ind2 = m_warp.Tri(i, 0); p = cvPointFrom32f(m_warp.Vertex(ind1)); q = cvPointFrom32f(m_warp.Vertex(ind2)); cvLine(TriImage, p, q, CV_RGB(255, 255, 255)); cvLine(convexImage, p, q, CV_RGB(255, 255, 255)); sprintf(filename, "Tri/%03i.jpg", i+1); cvSaveImage(filename, TriImage); } cvSaveImage("Tri/convex.jpg", convexImage); cvReleaseImage(&templateimg); cvReleaseImage(&convexImage); cvReleaseImage(&TriImage); }
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); }