private Point[] fit(Mat image, Point[] init, OpenCVForUnity.Size ssize, bool robust, int itol, double ftol) { int n = smodel.npts(); // assert((int(init.size())==n) && (pmodel.n_patches()==n)); // Debug.Log ("init.size())==n " + init.Length + " " + n); // Debug.Log ("pmodel.n_patches()==n " + pmodel.n_patches () + " " + n); smodel.calc_params(init, new Mat(), 3.0f); Point[] pts = smodel.calc_shape(); //find facial features in image around current estimates Point[] peaks = pmodel.calc_peaks(image, pts, ssize); //optimise if (!robust) { smodel.calc_params(peaks, new Mat(), 3.0f); //compute shape model parameters pts = smodel.calc_shape(); //update shape } else { using (Mat weight = new Mat(n, 1, CvType.CV_32F)) using (Mat weight_sort = new Mat(n, 1, CvType.CV_32F)) { Point[] pts_old = pts; for (int iter = 0; iter < itol; iter++) { //compute robust weight for (int i = 0; i < n; i++) { using (MatOfPoint tmpMat = new MatOfPoint(new Point(pts [i].x - peaks [i].x, pts [i].y - peaks [i].y))) { weight.put(i, 0, new float[] { (float)Core.norm(tmpMat) }); } } Core.sort(weight, weight_sort, Core.SORT_EVERY_COLUMN | Core.SORT_ASCENDING); double var = 1.4826 * (float)weight_sort.get(n / 2, 0) [0]; if (var < 0.1) { var = 0.1; } Core.pow(weight, 2, weight); Core.multiply(weight, new Scalar(-0.5 / (var * var)), weight); Core.exp(weight, weight); //compute shape model parameters smodel.calc_params(peaks, weight, 3.0f); //update shape pts = smodel.calc_shape(); //check for convergence float v = 0; for (int i = 0; i < n; i++) { using (MatOfPoint tmpMat = new MatOfPoint(new Point(pts [i].x - pts_old [i].x, pts [i].y - pts_old [i].y))) { v += (float)Core.norm(tmpMat); } } if (v < ftol) { break; } else { pts_old = pts; } } } } return(pts); }