Esempio n. 1
0
    private void sort(ref MatOfPoint2f fourPoints)
    {
        // the argument needs to contain 4 points precisely
        // sort the bounding box to (topleft, topright, bottomright, bottomleft
        double[]     p1, p2, p3, p4;
        List <Point> points = new List <Point>();

        p1 = new double[2] {
            fourPoints.get(0, 0)[0], fourPoints.get(0, 0)[1]
        };
        p2 = new double[2] {
            fourPoints.get(1, 0)[0], fourPoints.get(1, 0)[1]
        };
        p3 = new double[2] {
            fourPoints.get(2, 0)[0], fourPoints.get(2, 0)[1]
        };
        p4 = new double[2] {
            fourPoints.get(3, 0)[0], fourPoints.get(3, 0)[1]
        };
        print("p1: " + (char)p1[0] + "," + (char)p1[1]);
        print("p2: " + (char)p2[0] + "," + (char)p2[1]);
        print("p3: " + (char)p3[0] + "," + (char)p3[1]);
        print("p4: " + (char)p4[0] + "," + (char)p4[1]);

        if (p1[0] < p2[0] && p1[0] < p3[0] || p1[0] < p4[0] && p1[0] < p3[0] || p1[0] < p2[0] && p1[0] < p4[0])
        {
            if (p1[1] < p2[1] && p1[1] < p3[1] || p1[1] < p4[1] && p1[1] < p3[1] || p1[1] < p2[1] && p1[1] < p4[1])
            {
                points.Add(new Point(p1[0], p1[1]));
                if (p2[1] < p3[1] && p2[1] < p4[1])
                {
                    points.Add(new Point(p2[0], p2[1]));
                    if (p3[0] < p4[0])
                    {
                        points.Add(new Point(p4[0], p4[1]));
                        points.Add(new Point(p3[0], p3[1]));
                    }
                    else
                    {
                        points.Add(new Point(p3[0], p3[1]));
                        points.Add(new Point(p4[0], p4[1]));
                    }
                }
                else if (p3[1] < p2[1] && p3[1] < p4[1])
                {
                    points.Add(new Point(p3[0], p3[1]));
                    if (p2[0] < p4[0])
                    {
                        points.Add(new Point(p4[0], p4[1]));
                        points.Add(new Point(p2[0], p2[1]));
                    }
                    else
                    {
                        points.Add(new Point(p2[0], p2[1]));
                        points.Add(new Point(p4[0], p4[1]));
                    }
                }
                else if (p4[1] < p2[1] && p4[1] < p3[1])
                {
                    points.Add(new Point(p4[0], p4[1]));
                    if (p2[0] < p3[0])
                    {
                        points.Add(new Point(p3[0], p3[1]));
                        points.Add(new Point(p2[0], p2[1]));
                    }
                    else
                    {
                        points.Add(new Point(p2[0], p2[1]));
                        points.Add(new Point(p3[0], p3[1]));
                    }
                }
            }
            else if (p2[0] < p3[0] && p2[0] < p4[0])
            {
                points.Add(new Point(p2[0], p2[1]));
                if (p3[1] < p4[1])
                {
                    points.Add(new Point(p3[0], p3[1]));
                    points.Add(new Point(p4[0], p4[1]));
                }
                else
                {
                    points.Add(new Point(p4[0], p4[1]));
                    points.Add(new Point(p3[0], p3[1]));
                }
                points.Add(new Point(p1[0], p1[1]));
            }
            else if (p3[0] < p2[0] && p3[0] < p4[0])
            {
                points.Add(new Point(p3[0], p3[1]));
                if (p2[1] < p4[1])
                {
                    points.Add(new Point(p2[0], p2[1]));
                    points.Add(new Point(p4[0], p4[1]));
                }
                else
                {
                    points.Add(new Point(p4[0], p4[1]));
                    points.Add(new Point(p2[0], p2[1]));
                }
                points.Add(new Point(p1[0], p1[1]));
            }
            else if (p4[0] < p3[0] && p4[0] < p2[0])
            {
                points.Add(new Point(p4[0], p4[1]));
                if (p3[1] < p2[1])
                {
                    points.Add(new Point(p3[0], p3[1]));
                    points.Add(new Point(p2[0], p2[1]));
                }
                else
                {
                    points.Add(new Point(p2[0], p2[1]));
                    points.Add(new Point(p3[0], p3[1]));
                }
                points.Add(new Point(p1[0], p1[1]));
            }
        }
        else if (p2[0] < p1[0] && p2[0] < p3[0] || p2[0] < p4[0] && p2[0] < p3[0] || p2[0] < p1[0] && p2[0] < p4[0])
        {
            if (p2[1] < p1[1] && p2[1] < p3[1] || p2[1] < p4[1] && p2[1] < p3[1] || p2[1] < p1[1] && p2[1] < p4[1])
            {
                points.Add(new Point(p2[0], p2[1]));
                if (p1[1] < p3[1] && p1[1] < p4[1])
                {
                    points.Add(new Point(p1[0], p1[1]));
                    if (p3[0] < p4[0])
                    {
                        points.Add(new Point(p4[0], p4[1]));
                        points.Add(new Point(p3[0], p3[1]));
                    }
                    else
                    {
                        points.Add(new Point(p3[0], p3[1]));
                        points.Add(new Point(p4[0], p4[1]));
                    }
                }
                else if (p3[1] < p1[1] && p3[1] < p4[1])
                {
                    points.Add(new Point(p3[0], p3[1]));
                    if (p1[0] < p4[0])
                    {
                        points.Add(new Point(p4[0], p4[1]));
                        points.Add(new Point(p1[0], p1[1]));
                    }
                    else
                    {
                        points.Add(new Point(p1[0], p1[1]));
                        points.Add(new Point(p4[0], p4[1]));
                    }
                }
                else if (p4[1] < p1[1] && p4[1] < p3[1])
                {
                    points.Add(new Point(p4[0], p4[1]));
                    if (p1[0] < p3[0])
                    {
                        points.Add(new Point(p3[0], p3[1]));
                        points.Add(new Point(p1[0], p1[1]));
                    }
                    else
                    {
                        points.Add(new Point(p1[0], p1[1]));
                        points.Add(new Point(p3[0], p3[1]));
                    }
                }
            }
            else if (p1[0] < p3[0] && p1[0] < p4[0])
            {
                points.Add(new Point(p1[0], p1[1]));
                if (p3[1] < p4[1])
                {
                    points.Add(new Point(p3[0], p3[1]));
                    points.Add(new Point(p4[0], p4[1]));
                }
                else
                {
                    points.Add(new Point(p4[0], p4[1]));
                    points.Add(new Point(p3[0], p3[1]));
                }
                points.Add(new Point(p2[0], p2[1]));
            }
            else if (p3[0] < p1[0] && p3[0] < p4[0])
            {
                points.Add(new Point(p3[0], p3[1]));
                if (p1[1] < p4[1])
                {
                    points.Add(new Point(p1[0], p1[1]));
                    points.Add(new Point(p4[0], p4[1]));
                }
                else
                {
                    points.Add(new Point(p4[0], p4[1]));
                    points.Add(new Point(p1[0], p1[1]));
                }
                points.Add(new Point(p2[0], p2[1]));
            }
            else if (p4[0] < p3[0] && p4[0] < p1[0])
            {
                points.Add(new Point(p4[0], p4[1]));
                if (p3[1] < p1[1])
                {
                    points.Add(new Point(p3[0], p3[1]));
                    points.Add(new Point(p1[0], p1[1]));
                }
                else
                {
                    points.Add(new Point(p1[0], p1[1]));
                    points.Add(new Point(p3[0], p3[1]));
                }
                points.Add(new Point(p2[0], p2[1]));
            }
        }
        else if (p3[0] < p2[0] && p3[0] < p1[0] || p3[0] < p4[0] && p3[0] < p1[0] || p3[0] < p2[0] && p3[0] < p4[0])
        {
            if (p3[1] < p2[1] && p3[1] < p1[1] || p3[1] < p4[1] && p3[1] < p1[1] || p3[1] < p2[1] && p3[1] < p4[1])
            {
                points.Add(new Point(p3[0], p3[1]));
                if (p2[1] < p1[1] && p2[1] < p4[1])
                {
                    points.Add(new Point(p2[0], p2[1]));
                    if (p1[0] < p4[0])
                    {
                        points.Add(new Point(p4[0], p4[1]));
                        points.Add(new Point(p1[0], p1[1]));
                    }
                    else
                    {
                        points.Add(new Point(p1[0], p1[1]));
                        points.Add(new Point(p4[0], p4[1]));
                    }
                }
                else if (p1[1] < p2[1] && p1[1] < p4[1])
                {
                    points.Add(new Point(p1[0], p1[1]));
                    if (p2[0] < p4[0])
                    {
                        points.Add(new Point(p4[0], p4[1]));
                        points.Add(new Point(p2[0], p2[1]));
                    }
                    else
                    {
                        points.Add(new Point(p2[0], p2[1]));
                        points.Add(new Point(p4[0], p4[1]));
                    }
                }
                else if (p4[1] < p2[1] && p4[1] < p1[1])
                {
                    points.Add(new Point(p4[0], p4[1]));
                    if (p2[0] < p1[0])
                    {
                        points.Add(new Point(p1[0], p1[1]));
                        points.Add(new Point(p2[0], p2[1]));
                    }
                    else
                    {
                        points.Add(new Point(p2[0], p2[1]));
                        points.Add(new Point(p1[0], p1[1]));
                    }
                }
            }
            else if (p2[0] < p1[0] && p2[0] < p4[0])
            {
                points.Add(new Point(p2[0], p2[1]));
                if (p1[1] < p4[1])
                {
                    points.Add(new Point(p1[0], p1[1]));
                    points.Add(new Point(p4[0], p4[1]));
                }
                else
                {
                    points.Add(new Point(p4[0], p4[1]));
                    points.Add(new Point(p1[0], p1[1]));
                }
                points.Add(new Point(p3[0], p3[1]));
            }
            else if (p1[0] < p2[0] && p1[0] < p4[0])
            {
                points.Add(new Point(p1[0], p1[1]));
                if (p2[1] < p4[1])
                {
                    points.Add(new Point(p2[0], p2[1]));
                    points.Add(new Point(p4[0], p4[1]));
                }
                else
                {
                    points.Add(new Point(p4[0], p4[1]));
                    points.Add(new Point(p2[0], p2[1]));
                }
                points.Add(new Point(p3[0], p3[1]));
            }
            else if (p4[0] < p1[0] && p4[0] < p2[0])
            {
                points.Add(new Point(p4[0], p4[1]));
                if (p1[1] < p2[1])
                {
                    points.Add(new Point(p1[0], p1[1]));
                    points.Add(new Point(p2[0], p2[1]));
                }
                else
                {
                    points.Add(new Point(p2[0], p2[1]));
                    points.Add(new Point(p1[0], p1[1]));
                }
                points.Add(new Point(p3[0], p3[1]));
            }
        }
        else if (p4[0] < p2[0] && p4[0] < p3[0] || p4[0] < p1[0] && p4[0] < p3[0] || p4[0] < p2[0] && p4[0] < p1[0])
        {
            if (p4[1] < p2[1] && p4[1] < p3[1] || p4[1] < p1[1] && p4[1] < p3[1] || p4[1] < p2[1] && p4[1] < p1[1])
            {
                points.Add(new Point(p4[0], p4[1]));
                if (p2[1] < p3[1] && p2[1] < p1[1])
                {
                    points.Add(new Point(p2[0], p2[1]));
                    if (p3[0] < p1[0])
                    {
                        points.Add(new Point(p1[0], p1[1]));
                        points.Add(new Point(p3[0], p3[1]));
                    }
                    else
                    {
                        points.Add(new Point(p3[0], p3[1]));
                        points.Add(new Point(p1[0], p1[1]));
                    }
                }
                else if (p3[1] < p2[1] && p3[1] < p1[1])
                {
                    points.Add(new Point(p3[0], p3[1]));
                    if (p2[0] < p1[0])
                    {
                        points.Add(new Point(p1[0], p1[1]));
                        points.Add(new Point(p2[0], p2[1]));
                    }
                    else
                    {
                        points.Add(new Point(p2[0], p2[1]));
                        points.Add(new Point(p1[0], p1[1]));
                    }
                }
                else if (p1[1] < p2[1] && p1[1] < p3[1])
                {
                    points.Add(new Point(p1[0], p1[1]));
                    if (p2[0] < p3[0])
                    {
                        points.Add(new Point(p3[0], p3[1]));
                        points.Add(new Point(p2[0], p2[1]));
                    }
                    else
                    {
                        points.Add(new Point(p2[0], p2[1]));
                        points.Add(new Point(p3[0], p3[1]));
                    }
                }
            }
            else if (p2[0] < p3[0] && p2[0] < p1[0])
            {
                points.Add(new Point(p2[0], p2[1]));
                if (p3[1] < p1[1])
                {
                    points.Add(new Point(p3[0], p3[1]));
                    points.Add(new Point(p1[0], p1[1]));
                }
                else
                {
                    points.Add(new Point(p1[0], p1[1]));
                    points.Add(new Point(p3[0], p3[1]));
                }
                points.Add(new Point(p4[0], p4[1]));
            }
            else if (p3[0] < p2[0] && p3[0] < p1[0])
            {
                points.Add(new Point(p3[0], p3[1]));
                if (p2[1] < p1[1])
                {
                    points.Add(new Point(p2[0], p2[1]));
                    points.Add(new Point(p1[0], p1[1]));
                }
                else
                {
                    points.Add(new Point(p1[0], p1[1]));
                    points.Add(new Point(p2[0], p2[1]));
                }
                points.Add(new Point(p4[0], p4[1]));
            }
            else if (p1[0] < p3[0] && p1[0] < p2[0])
            {
                points.Add(new Point(p1[0], p1[1]));
                if (p3[1] < p2[1])
                {
                    points.Add(new Point(p3[0], p3[1]));
                    points.Add(new Point(p2[0], p2[1]));
                }
                else
                {
                    points.Add(new Point(p2[0], p2[1]));
                    points.Add(new Point(p3[0], p3[1]));
                }
                points.Add(new Point(p4[0], p4[1]));
            }
        }
        // MatOfPoint2f pts2 = new MatOfPoint2f();
        fourPoints = new MatOfPoint2f();
        fourPoints.release();
        fourPoints.fromList(points);
    }
Esempio n. 2
0
        /// <summary>
        /// Refines the matches with homography.
        /// </summary>
        /// <returns><c>true</c>, if matches with homography was refined, <c>false</c> otherwise.</returns>
        /// <param name="queryKeypoints">Query keypoints.</param>
        /// <param name="trainKeypoints">Train keypoints.</param>
        /// <param name="reprojectionThreshold">Reprojection threshold.</param>
        /// <param name="matches">Matches.</param>
        /// <param name="homography">Homography.</param>
        static bool refineMatchesWithHomography
        (
            MatOfKeyPoint queryKeypoints,
            MatOfKeyPoint trainKeypoints,
            float reprojectionThreshold,
            MatOfDMatch matches,
            Mat homography
        )
        {
//              Debug.Log ("matches " + matches.ToString ());

            int minNumberMatchesAllowed = 8;

            List <KeyPoint> queryKeypointsList = queryKeypoints.toList();
            List <KeyPoint> trainKeypointsList = trainKeypoints.toList();
            List <DMatch>   matchesList        = matches.toList();

            if (matchesList.Count < minNumberMatchesAllowed)
            {
                return(false);
            }

            // Prepare data for cv::findHomography
            List <Point> srcPointsList = new List <Point> (matchesList.Count);
            List <Point> dstPointsList = new List <Point> (matchesList.Count);

            for (int i = 0; i < matchesList.Count; i++)
            {
                srcPointsList.Add(trainKeypointsList [matchesList [i].trainIdx].pt);
                dstPointsList.Add(queryKeypointsList [matchesList [i].queryIdx].pt);
            }

            // Find homography matrix and get inliers mask
            using (MatOfPoint2f srcPoints = new MatOfPoint2f())
                using (MatOfPoint2f dstPoints = new MatOfPoint2f())
                    using (MatOfByte inliersMask = new MatOfByte(new byte[srcPointsList.Count])) {
                        srcPoints.fromList(srcPointsList);
                        dstPoints.fromList(dstPointsList);

//              Debug.Log ("srcPoints " + srcPoints.ToString ());
//              Debug.Log ("dstPoints " + dstPoints.ToString ());


                        Calib3d.findHomography(srcPoints,
                                               dstPoints,
                                               Calib3d.FM_LMEDS,
                                               reprojectionThreshold,
                                               inliersMask, 2000, 0.9).copyTo(homography);

                        if (homography.rows() != 3 || homography.cols() != 3)
                        {
                            return(false);
                        }

                        //Debug.Log ("homography " + homography.ToString ());

                        //Debug.Log ("inliersMask " + inliersMask.dump ());

                        List <byte> inliersMaskList = inliersMask.toList();

                        List <DMatch> inliers = new List <DMatch> ();
                        for (int i = 0; i < inliersMaskList.Count; i++)
                        {
                            if (inliersMaskList [i] == 1)
                            {
                                inliers.Add(matchesList [i]);
                            }
                        }

                        matches.fromList(inliers);
                        //Debug.Log ("matches " + matches.ToString ());
                    }

            return(matchesList.Count > minNumberMatchesAllowed);
        }
Esempio n. 3
0
        /// <summary>
        /// Processes points by filter.
        /// </summary>
        /// <param name="img">Image mat.</param>
        /// <param name="srcPoints">Input points.</param>
        /// <param name="dstPoints">Output points.</param>
        /// <param name="drawDebugPoints">if true, draws debug points.</param>
        /// <returns>Output points.</returns>
        public override List <Vector2> Process(Mat img, List <Vector2> srcPoints, List <Vector2> dstPoints = null, bool drawDebugPoints = false)
        {
            if (srcPoints != null && srcPoints.Count != numberOfElements)
            {
                throw new ArgumentException("The number of elements is different.");
            }

            if (srcPoints == null)
            {
                return(dstPoints == null ? srcPoints : dstPoints);
            }

            if (!flag)
            {
                if (img.channels() == 4)
                {
                    Imgproc.cvtColor(img, prevgray, Imgproc.COLOR_RGBA2GRAY);
                }
                else if (img.channels() == 3)
                {
                    Imgproc.cvtColor(img, prevgray, Imgproc.COLOR_RGB2GRAY);
                }
                else
                {
                    if (prevgray.total() == 0)
                    {
                        prevgray = img.clone();
                    }
                    else
                    {
                        img.copyTo(prevgray);
                    }
                }

                for (int i = 0; i < numberOfElements; i++)
                {
                    prevTrackPts[i] = new Point(srcPoints [i].x, srcPoints [i].y);
                }

                flag = true;
            }

            if (srcPoints != null)
            {
                if (dstPoints == null)
                {
                    dstPoints = new List <Vector2> ();
                }
                if (dstPoints != null && dstPoints.Count != numberOfElements)
                {
                    dstPoints.Clear();
                    for (int i = 0; i < numberOfElements; i++)
                    {
                        dstPoints.Add(new Vector2());
                    }
                }

                if (img.channels() == 4)
                {
                    Imgproc.cvtColor(img, gray, Imgproc.COLOR_RGBA2GRAY);
                }
                else if (img.channels() == 3)
                {
                    Imgproc.cvtColor(img, gray, Imgproc.COLOR_RGB2GRAY);
                }
                else
                {
                    if (gray.total() == 0)
                    {
                        gray = img.clone();
                    }
                    else
                    {
                        img.copyTo(gray);
                    }
                }

                if (prevgray.total() > 0)
                {
                    mOP2fPrevTrackPts.fromList(prevTrackPts);
                    mOP2fNextTrackPts.fromList(nextTrackPts);
                    Video.calcOpticalFlowPyrLK(prevgray, gray, mOP2fPrevTrackPts, mOP2fNextTrackPts, status, err);
                    prevTrackPts = mOP2fPrevTrackPts.toList();
                    nextTrackPts = mOP2fNextTrackPts.toList();

                    // clac diffDlib
                    prevTrackPtsMat.fromList(prevTrackPts);
                    OpenCVForUnity.Rect rect = Imgproc.boundingRect(prevTrackPtsMat);
                    double diffDlib          = this.diffDlib * rect.area() / 40000.0 * diffCheckSensitivity;

                    // if the face is moving so fast, use dlib to detect the face
                    double diff = calDistanceDiff(prevTrackPts, nextTrackPts);
                    if (drawDebugPoints)
                    {
                        Debug.Log("variance:" + diff);
                    }
                    if (diff > diffDlib)
                    {
                        for (int i = 0; i < numberOfElements; i++)
                        {
                            nextTrackPts [i].x = srcPoints [i].x;
                            nextTrackPts [i].y = srcPoints [i].y;

                            dstPoints [i] = srcPoints [i];
                        }

                        if (drawDebugPoints)
                        {
                            Debug.Log("DLIB");
                            for (int i = 0; i < numberOfElements; i++)
                            {
                                Imgproc.circle(img, new Point(srcPoints [i].x, srcPoints [i].y), 2, new Scalar(255, 0, 0, 255), -1);
                            }
                        }
                    }
                    else
                    {
                        // In this case, use Optical Flow
                        for (int i = 0; i < numberOfElements; i++)
                        {
                            dstPoints [i] = new Vector2((float)nextTrackPts [i].x, (float)nextTrackPts [i].y);
                        }

                        if (drawDebugPoints)
                        {
                            Debug.Log("Optical Flow");
                            for (int i = 0; i < numberOfElements; i++)
                            {
                                Imgproc.circle(img, nextTrackPts [i], 2, new Scalar(0, 0, 255, 255), -1);
                            }
                        }
                    }
                }
                Swap(ref prevTrackPts, ref nextTrackPts);
                Swap(ref prevgray, ref gray);
            }
            return(dstPoints);
        }