Ejemplo n.º 1
0
        /// <summary>
        /// Detector
        /// </summary>
        /// <param name="inputTexture">Input Unity texture</param>
        /// <param name="texParams">Texture parameters (flipped, rotated etc.)</param>
        /// <param name="detect">Flag signalling whether we need detection on this frame</param>
        public virtual void ProcessTexture(T texture, Unity.TextureConversionParams texParams, bool detect = true)
        {
            // convert Unity texture to OpenCv::Mat
            ImportTexture(texture, texParams);

            // detect
            if (detect)
            {
                double invF = 1.0 / appliedFactor;
                DataStabilizer.ThresholdFactor = invF;

                // convert to grayscale and normalize
                Mat gray = new Mat();
                Cv2.CvtColor(processingImage, gray, ColorConversionCodes.BGR2GRAY);

                // fix shadows
                Cv2.EqualizeHist(gray, gray);

                /*Mat normalized = new Mat();
                 * CLAHE clahe = CLAHE.Create();
                 * clahe.TilesGridSize = new Size(8, 8);
                 * clahe.Apply(gray, normalized);
                 * gray = normalized;*/

                // detect matching regions (faces bounding)
                Rect[] rawFaces = cascadeFaces.DetectMultiScale(gray, 1.2, 6);
                if (Faces.Count != rawFaces.Length)
                {
                    Faces.Clear();
                }

                // now per each detected face draw a marker and detect eyes inside the face rect
                int facesCount = 0;
                for (int i = 0; i < rawFaces.Length; ++i)
                {
                    Rect faceRect       = rawFaces[i];
                    Rect faceRectScaled = faceRect * invF;
                    using (Mat grayFace = new Mat(gray, faceRect))
                    {
                        // another trick: confirm the face with eye detector, will cut some false positives
                        if (cutFalsePositivesWithEyesSearch && null != cascadeEyes)
                        {
                            Rect[] eyes = cascadeEyes.DetectMultiScale(grayFace);
                            if (eyes.Length == 0 || eyes.Length > 2)
                            {
                                continue;
                            }
                        }

                        // get face object
                        DetectedFace face = null;
                        if (Faces.Count < i + 1)
                        {
                            face = new DetectedFace(DataStabilizer, faceRectScaled);
                            Faces.Add(face);
                        }
                        else
                        {
                            face = Faces[i];
                            face.SetRegion(faceRectScaled);
                        }

                        // shape
                        facesCount++;
                        if (null != shapeFaces)
                        {
                            Point[] marks = shapeFaces.DetectLandmarks(gray, faceRect);

                            // we have 68-point predictor
                            if (marks.Length == 68)
                            {
                                // transform landmarks to the original image space
                                List <Point> converted = new List <Point>();
                                foreach (Point pt in marks)
                                {
                                    converted.Add(pt * invF);
                                }

                                // save and parse landmarks
                                face.SetLandmarks(converted.ToArray());
                            }
                        }
                    }
                }

                // log
                //UnityEngine.Debug.Log(String.Format("Found {0} faces", Faces.Count));
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Detector
        /// </summary>
        /// <param name="inputTexture">Input Unity texture</param>
        /// <param name="texParams">Texture parameters (flipped, rotated etc.)</param>
        /// <param name="detect">Flag signalling whether we need detection on this frame</param>
        public virtual Point[] ProcessTexture(T texture, Unity.TextureConversionParams texParams)
        {
            // convert Unity texture to OpenCv::Mat
            ImportTexture(texture, texParams);

            DataStabilizer.ThresholdFactor = 1;

            // convert to grayscale and normalize
            Mat gray = new Mat();

            Cv2.CvtColor(processingImage, gray, ColorConversionCodes.BGR2GRAY);
            Cv2.Blur(gray, gray, new Size(10, 10));

            // fix shadows
            // Cv2.EqualizeHist(gray, gray);

            // detect matching regions (faces bounding)
            Rect[] rawFaces = cascadeFaces.DetectMultiScale(gray, 1.2, 6);
            if (Faces.Count != rawFaces.Length)
            {
                Faces.Clear();
            }

            // now per each detected face draw a marker and detect eyes inside the face rect
            int facesCount = 0;

            Point[] maxFace     = lastFace;
            double  maxFaceSize = 0;

            for (int i = 0; i < rawFaces.Length; ++i)
            {
                Rect faceRect = rawFaces[i];
                using (Mat grayFace = new Mat(gray, faceRect))
                {
                    // another trick: confirm the face with eye detector, will cut some false positives
                    if (cutFalsePositivesWithEyesSearch && null != cascadeEyes)
                    {
                        Rect[] eyes = cascadeEyes.DetectMultiScale(grayFace);
                        if (eyes.Length == 0 || eyes.Length > 2)
                        {
                            continue;
                        }
                    }

                    // get face object
                    Demo.DetectedFace face = null;
                    if (Faces.Count < i + 1)
                    {
                        face = new Demo.DetectedFace(DataStabilizer, faceRect);
                        Faces.Add(face);
                    }
                    else
                    {
                        face = Faces[i];
                        face.SetRegion(faceRect);
                    }

                    // shape
                    facesCount++;
                    if (null != shapeFaces)
                    {
                        Point[] marks = shapeFaces.DetectLandmarks(gray, faceRect);

                        // we have 68-point predictor
                        if (marks.Length == 68)
                        {
                            double size = Point.DistancePow2(marks[0], marks[16]);
                            if (size > maxFaceSize)
                            {
                                maxFaceSize = size;
                                maxFace     = marks;
                            }
                        }
                    }
                }
            }

            if (maxFaceSize != 0)
            {
                lastFace = maxFace;
            }

            return(maxFace);
        }