예제 #1
0
    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);
    }