📄 faceextract.cc
字号:
const char *help = "\progname: faceExtract.cc\n\code2html: This program reads an image and an annotation file and extracts faces.\n\version: Torch3 vision2.0, 2003-2005\n\(c) Yann Rodriguez (rodrig@idiap.ch) and Sebastien Marcel (marcel@idiap.ch)\n";#include "Image.h"#include "ImageGray.h"#include "ImageRgb.h"#include "ImageDiskXFile.h"#include "xtprobeImageDiskXFile.h"#include "FaceModel.h"#include "FrontalFace15x20.h"#include "FrontalFace19x19.h"#include "NonFrontalFace19x19.h"#include "FrontalFace64x80.h"#include "FrontalFace64x40.h"#include "FrontalFace64x56.h"#include "ipFaceExtract.h"#include "Random.h"#include "CmdLine.h"#include "DiskXFile.h"using namespace Torch;int main(int argc, char *argv[]){ char *imagefilename; char *posfilename; int facemodel_id; int postype; bool oneface; int pan; int shift; int scale; int rotate; int n_selected; real angle_offset; int width_out; int height_out; bool savepgm; char *bin_filename; bool verbose; bool draw; bool norm; CmdLine cmd; cmd.setBOption("write log", false); cmd.info(help); cmd.addText("\nArguments:"); cmd.addSCmdArg("imagefile", &imagefilename, "image file"); cmd.addSCmdArg("posfile", &posfilename, "pos file"); cmd.addText("\nOptions:"); cmd.addICmdOption("-facemodel", &facemodel_id, 2, "facemodel (1=15x20, 2=19x19, 3=64x80, 4=64x40, 5=64x56)"); cmd.addICmdOption("-postype", &postype, 2, "posfile format (1=eyes center, 2=banca format, 3=eyes corners, 4=eye corners + nose tip + chin, 5=left eye corners + right eye center + nose tip + chin, 6=left eye center + nose tip + chin, 68=AAM's markup 68 pts)"); cmd.addBCmdOption("-oneface", &oneface, false, "only one face in the posfile (no header)"); cmd.addICmdOption("-pan", &pan, 0, "pan angle for non-frontal faces"); cmd.addRCmdOption("-angleoffset", &angle_offset, 0.0, "angle offset"); cmd.addICmdOption("-shift", &shift, 0, "number of shifts in pixels"); cmd.addICmdOption("-scale", &scale, 0, "number of scale levels"); cmd.addICmdOption("-rotate", &rotate, 0, "number of rotations"); cmd.addICmdOption("-select", &n_selected, 1, "number of patterns selected"); cmd.addICmdOption("-width", &width_out, -1, "width"); cmd.addICmdOption("-height", &height_out, -1, "height"); cmd.addBCmdOption("-savepgm", &savepgm, false, "save the cropped images in pgm"); cmd.addSCmdOption("-savebin", &bin_filename, "", "bin filename (Torch3 binary format)"); cmd.addBCmdOption("-verbose", &verbose, false, "print some information (mainly for debug)"); cmd.addBCmdOption("-draw", &draw, false, "draw"); cmd.addBCmdOption("-norm", &norm, false, "norm output values to [0,1]"); cmd.read(argc, argv); Allocator *allocator = new Allocator; Random::seed(); if(width_out == -1 || height_out == -1) { if(height_out != width_out) error("incorrect values for width or height."); } /*----------- 1] the .pos file -----------*/ DiskXFile pos_file(posfilename, "r"); int n_faces = 0; if(oneface) { n_faces = 1; if(verbose) message("1 face in the posfile (one face)"); } else { pos_file.scanf("%d", &n_faces); if(verbose) message("%d faces in the posfile", n_faces); if(n_faces <=0 ) error("Incorrect value for n_faces. Exit."); } /*----------- 2] load the image -----------*/ Image *image; ImageDiskXFile *image_disk; image_disk = new(allocator) xtprobeImageDiskXFile(imagefilename, "r"); image = new(allocator) ImageGray(); // convert in gray if needed image->loadImageXFile(image_disk); allocator->free(image_disk); /*----------- 3] the FaceModel -----------*/ FaceModel *face_model = NULL; switch(facemodel_id) { case 1: if(verbose) message("using 15x20 face model."); if(pan == 0) face_model = new(allocator) FrontalFace15x20(postype); else error("No 15x20 non-frontal model available."); break; case 2: if(verbose) message("using 19x19 face model."); if(pan == 0) face_model = new(allocator) FrontalFace19x19(postype); else face_model = new(allocator) NonFrontalFace19x19(pan, postype); break; case 3: if(verbose) message("using 64x80 face model."); if(pan == 0) face_model = new(allocator) FrontalFace64x80(postype); else error("No 64x80 non-frontal model available."); break; case 4: if(verbose) message("using 64x40 face model."); if(pan == 0) face_model = new(allocator) FrontalFace64x40(postype); else error("No 64x40 non-frontal model available."); break; case 5: if(verbose) message("using 64x56 face model."); if(pan == 0) face_model = new(allocator) FrontalFace64x56(postype); else error("No 64x56 non-frontal model available."); break; default: error("Invalid face model. Exit."); } face_model->setBOption("verbose", verbose); if(postype == 1) { if(verbose) message("reading eye centers pos format."); } else if(postype == 2) { if(verbose) message("reading Banca pos format."); if(n_faces != 1) error("This postype is not defined for multiple face images."); } else if(postype == 3) { if(verbose) message("reading eye corners pos format."); } else if(postype == 4) { if(verbose) message("reading eye corners + nose tip + chin pos format (non frontal 22.5 degree)."); } else if(postype == 5) { if(verbose) message("reading left eye corners + right eye center + nose tip + chin pos format (non frontal 45/67.5 degree)."); } else if(postype == 6) { if(verbose) message("reading left eye center + nose tip + chin pos format (non frontal 90 degree)."); } else if(postype == 68) { if(verbose) message("reading Tim Cootes Markup point format."); } else error("Invalid format for pos files. Exit."); if(width_out == -1 || height_out == -1) { width_out = (int) face_model->model_width; height_out = (int) face_model->model_height; } if(verbose) print("Output size: %dx%d\n", width_out, height_out); /*----------- 4] the FaceExtractPIM's -----------*/ ipFaceExtract **face_extract = (ipFaceExtract **)allocator->alloc(n_faces*sizeof(ipFaceExtract *)); /*----------- 5] loop on all faces -----------*/ ImageRgb *colorimage = NULL; if(draw) { colorimage = new(allocator) ImageRgb(); colorimage->copyFrom(image); } for(int i=0 ; i<n_faces; i++) { if(verbose) message("Face %d:", i+1); face_model->loadXFile(&pos_file); if(draw) face_model->drawLDM(colorimage); face_extract[i] = new(allocator) ipFaceExtract(image->width, image->height, width_out, height_out, image->coding, face_model, angle_offset, shift, scale, rotate, n_selected); face_extract[i]->setBOption("verbose", verbose); // extract the subimages face_extract[i]->process(image); } if(draw) colorimage->save("output.ppm"); /*----------- 5] gestion de: bindata_filename, savepgm .. -----------*/ // save the cropped images in pgm. if(savepgm) { char filename[100]; ImageGray *image_out = new ImageGray(); for(int i=0; i<n_faces; i++) { for(int j=0; j<n_selected; j++) { image_out->copyFrom(width_out, height_out, face_extract[i]->seq_out->frames[j], face_extract[i]->coding); sprintf(filename, "crop_%d_%d.pgm", i, j); image_out->save(filename); } } delete image_out; } // save the cropped images in a file (binary format). if(strcmp(bin_filename, "")) { // each ipFaceExtract has the same #n_output# and #output_size# // and remember that: face_extract[0]->n_output == n_selected ... int output_size = face_extract[0]->seq_out->frame_size; int n_output = face_extract[0]->seq_out->n_frames * n_faces; DiskXFile bin_file = DiskXFile(bin_filename, "w"); bin_file.write(&n_output, sizeof(int), 1); bin_file.write(&output_size, sizeof(int), 1); for(int i=0; i<n_faces; i++) for(int j=0; j<face_extract[0]->seq_out->n_frames; j++) { real *tmp_ = face_extract[i]->seq_out->frames[j]; for(int k=0; k<output_size; k++) if(norm) { real pix = tmp_[k]/255.0; bin_file.write(&pix, sizeof(real), 1); } else bin_file.write(&tmp_[k], sizeof(real), 1); } } delete allocator; return(0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -