// Pick only the more stable/rigid points under changes of expression void extract_rigid_points(Mat_<double>& source_points, Mat_<double>& destination_points) { if(source_points.rows == 68) { Mat_<double> tmp_source = source_points.clone(); source_points = Mat_<double>(); // Push back the rigid points (some face outline, eyes, and nose) source_points.push_back(tmp_source.row(1)); source_points.push_back(tmp_source.row(2)); source_points.push_back(tmp_source.row(3)); source_points.push_back(tmp_source.row(4)); source_points.push_back(tmp_source.row(12)); source_points.push_back(tmp_source.row(13)); source_points.push_back(tmp_source.row(14)); source_points.push_back(tmp_source.row(15)); source_points.push_back(tmp_source.row(27)); source_points.push_back(tmp_source.row(28)); source_points.push_back(tmp_source.row(29)); source_points.push_back(tmp_source.row(31)); source_points.push_back(tmp_source.row(32)); source_points.push_back(tmp_source.row(33)); source_points.push_back(tmp_source.row(34)); source_points.push_back(tmp_source.row(35)); source_points.push_back(tmp_source.row(36)); source_points.push_back(tmp_source.row(39)); source_points.push_back(tmp_source.row(40)); source_points.push_back(tmp_source.row(41)); source_points.push_back(tmp_source.row(42)); source_points.push_back(tmp_source.row(45)); source_points.push_back(tmp_source.row(46)); source_points.push_back(tmp_source.row(47)); Mat_<double> tmp_dest = destination_points.clone(); destination_points = Mat_<double>(); // Push back the rigid points destination_points.push_back(tmp_dest.row(1)); destination_points.push_back(tmp_dest.row(2)); destination_points.push_back(tmp_dest.row(3)); destination_points.push_back(tmp_dest.row(4)); destination_points.push_back(tmp_dest.row(12)); destination_points.push_back(tmp_dest.row(13)); destination_points.push_back(tmp_dest.row(14)); destination_points.push_back(tmp_dest.row(15)); destination_points.push_back(tmp_dest.row(27)); destination_points.push_back(tmp_dest.row(28)); destination_points.push_back(tmp_dest.row(29)); destination_points.push_back(tmp_dest.row(31)); destination_points.push_back(tmp_dest.row(32)); destination_points.push_back(tmp_dest.row(33)); destination_points.push_back(tmp_dest.row(34)); destination_points.push_back(tmp_dest.row(35)); destination_points.push_back(tmp_dest.row(36)); destination_points.push_back(tmp_dest.row(39)); destination_points.push_back(tmp_dest.row(40)); destination_points.push_back(tmp_dest.row(41)); destination_points.push_back(tmp_dest.row(42)); destination_points.push_back(tmp_dest.row(45)); destination_points.push_back(tmp_dest.row(46)); destination_points.push_back(tmp_dest.row(47)); } }
void collectData(int subjId, CascadeClassifier &classifier, ShapePredictor &predictor, Mat_<float> &labels, Mat_<float> &multihog, Mat_<float> &landmarks) { int H[] = { -15, -10, -5, 0, 5, 10, 15 }; int V[] = { -10, 0, 10 }; string path = to_string(subjId) + "/"; if (subjId < 10) path = "columbia/000" + path; else path = "columbia/00" + path; ifstream fin(path + "annotation.txt"); for (int imgId = 0; imgId < 105; imgId++) { int p, v, h; fin >> p >> v >> h; if (abs(p) > 15) continue; string imgpath = path + to_string(imgId) + ".jpg"; Mat_<uchar> img = imread(imgpath, 0); BBox bbox = getTestBBox(img, classifier); if (EmptyBox(bbox)) continue; int l = 0; // EYE, MOUTH, NOF if (abs(h) <= 5 && v == 0) l = 0; else if (abs(h) <= 5 && v == -10) l = 1; else l = 2; if (l == 2) { RNG rng(getTickCount()); double num = rng.uniform(0.0, 1.0); if (num > 0.5) continue; } // 上中下 /*if (v < 0) l = 0; else if (v == 0) l = 1; else l = 2;*/ // 9分类 /*if (h < -5) l += 0; else if (h > 5) l += 2; else l += 1; if (v < 0) l += 0; else if (v > 0) l += 2 * 3; else l += 1 * 3;*/ Mat_<float> lab = l*Mat_<float>::ones(1, 1); labels.push_back(lab); Mat_<double> shape = predictor(img, bbox); Geom G; initGeom(shape, G); Pose P; calcPose(G, P); Mat_<uchar> lEye, rEye; regularize(img, bbox, P, shape, lEye, rEye); vector<float> lRlt; vector<float> rRlt; calcMultiHog(lEye, lRlt); calcMultiHog(rEye, rRlt); vector<float> _hog2nd_vec; for (int k = 0; k < lRlt.size(); k++) _hog2nd_vec.push_back(lRlt[k]); for (int k = 0; k < rRlt.size(); k++) _hog2nd_vec.push_back(rRlt[k]); Mat_<float> _hog2nd_row = Mat_<float>(_hog2nd_vec).reshape(1, 1); multihog.push_back(_hog2nd_row); vector<float> _ldmks; for (int i = 28; i < 48; i++) { _ldmks.push_back((shape(i, 0) - bbox.cx) / bbox.w); _ldmks.push_back((shape(i, 1) - bbox.cy) / bbox.h); } float mouthx = (shape(51, 0) + shape(62, 0) + shape(66, 0) + shape(57, 0)) / 4; float mouthy = (shape(51, 1) + shape(62, 1) + shape(66, 1) + shape(57, 1)) / 4; _ldmks.push_back((mouthx - bbox.cx) / bbox.w); _ldmks.push_back((mouthy - bbox.cy) / bbox.h); float maxVal = *std::max_element(_ldmks.begin(), _ldmks.end()); for (int i = 0; i < _ldmks.size(); i++) _ldmks[i] *= 1.0 / maxVal; // scale to [-1, 1] Mat_<float> ldmks = Mat_<float>(_ldmks).reshape(1, 1); landmarks.push_back(ldmks); } fin.close(); }