public List<Point[]> detect (Mat im, float scaleFactor, int minNeighbours, OpenCVForUnity.Size minSize) { //convert image to greyscale Mat gray = null; if (im.channels () == 1) { gray = im; } else { gray = new Mat (); Imgproc.cvtColor (im, gray, Imgproc.COLOR_RGBA2GRAY); } using (Mat equalizeHistMat = new Mat ()) using (MatOfRect faces = new MatOfRect ()) { Imgproc.equalizeHist (gray, equalizeHistMat); detector.detectMultiScale (equalizeHistMat, faces, scaleFactor, minNeighbours, 0 | Objdetect.CASCADE_FIND_BIGGEST_OBJECT | Objdetect.CASCADE_SCALE_IMAGE, minSize, new Size ()); if (faces.rows () < 1) { return new List<Point[]> (); } return convertMatOfRectToPoints (faces); } }
public Point[] calc_peaks (Mat im, Point[] points, OpenCVForUnity.Size ssize) { int n = points.Length; // Debug.Log ("n == int(patches.size()) " + patches.Count); using (Mat pt = (new MatOfPoint2f (points)).reshape (1, 2 * n)) using (Mat S = calc_simil (pt)) using (Mat Si = inv_simil (S)) { Point[] pts = apply_simil (Si, points); for (int i = 0; i < n; i++) { OpenCVForUnity.Size wsize = new OpenCVForUnity.Size (ssize.width + patches [i].patch_size ().width, ssize.height + patches [i].patch_size ().height); using (Mat A = new Mat (2, 3, CvType.CV_32F)) { A.put (0, 0, S.get (0, 0) [0]); A.put (0, 1, S.get (0, 1) [0]); A.put (1, 0, S.get (1, 0) [0]); A.put (1, 1, S.get (1, 1) [0]); A.put (0, 2, pt.get (2 * i, 0) [0] - (A.get (0, 0) [0] * (wsize.width - 1) / 2 + A.get (0, 1) [0] * (wsize.height - 1) / 2)); A.put (1, 2, pt.get (2 * i + 1, 0) [0] - (A.get (1, 0) [0] * (wsize.width - 1) / 2 + A.get (1, 1) [0] * (wsize.height - 1) / 2)); using (Mat I = new Mat ()) { Imgproc.warpAffine (im, I, A, wsize, Imgproc.INTER_LINEAR + Imgproc.WARP_INVERSE_MAP); using (Mat R = patches [i].calc_response (I, false)) { Core.MinMaxLocResult minMaxLocResult = Core.minMaxLoc (R); pts [i].x = pts [i].x + minMaxLocResult.maxLoc.x - 0.5 * ssize.width; pts [i].y = pts [i].y + minMaxLocResult.maxLoc.y - 0.5 * ssize.height; } } } } return apply_simil (S, pts); } }
public TrackedObject (OpenCVForUnity.Rect rect) { lastPositions = new PositionsVector (); numDetectedFrames = 1; numFramesNotDetected = 0; lastPositions.Add (rect); _id = getNextId (); id = _id; }
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; }