Example #1
0
        public IMaskHolder GetMasks(Point[] body, PointF headPoint, PointF leftPoint, PointF rightPoint, Size maxSize, double headDistanceThreshold, double[] distances, double[] lineDistances, Image <Bgr, byte> debugImg)
        {
            IMaskHolder maskHolder = ModelResolver.Resolve <IMaskHolder>();
            PointF      com        = leftPoint.MidPoint(rightPoint);
            Vector      forwardVec = new Vector(headPoint.X - com.X, headPoint.Y - com.Y);
            Vector      leftVec    = new Vector(forwardVec.Y, -forwardVec.X);
            Vector      rightVec   = new Vector(-forwardVec.Y, forwardVec.X);

            leftVec.Normalize();
            rightVec.Normalize();

            List <Point> leftPoints = new List <Point>(), rightPoints = new List <Point>();
            double       headValue = MathExtension.GetSide(leftPoint, rightPoint, headPoint);

            foreach (Point point in body)
            {
                //Find if value is on same side as nose
                double pointSide = MathExtension.GetSide(leftPoint, rightPoint, point);

                if ((headValue < 0 && pointSide > 0) || (headValue > 0 && pointSide < 0))
                {
                    continue;
                }

                //Make sure value is far enough from nose tip
                //if (point.Distance(headPoint) < headDistanceThreshold)
                //{
                //    continue;
                //}

                //Find if value is on left or right
                double d = MathExtension.GetSide(com, headPoint, point);

                if (d > 0)
                {
                    leftPoints.Add(point);
                }
                else
                {
                    rightPoints.Add(point);
                }
            }

            maskHolder.LeftPoints  = new List <Point[]>();
            maskHolder.RightPoints = new List <Point[]>();
            maskHolder.LeftPoints.Add(leftPoints.ToArray());
            maskHolder.RightPoints.Add(rightPoints.ToArray());

            if (leftPoints.Count == 0 || rightPoints.Count == 0)
            {
                return(null);
            }

            ImageViewer.Show(debugImg);
            //Order them by closest to headPoint
            Point[] orderedLeftPoints  = OrderPointsByBiggestGap(leftPoints, headPoint.ToPoint());
            Point[] orderedRightPoints = OrderPointsByBiggestGap(rightPoints, headPoint.ToPoint());
            debugImg.DrawPolyline(orderedRightPoints, false, new Bgr(Color.Red));
            debugImg.DrawPolyline(orderedLeftPoints, false, new Bgr(Color.Red));
            debugImg.Draw(new LineSegment2DF(com, headPoint), new Bgr(Color.Yellow), 2);
            ImageViewer.Show(debugImg);
            //We now have a list of the points that need to go left and points that need to go right
            for (int i = 1; i < distances.Length; i++)
            {
                double d1 = distances[i - 1];
                double d2 = distances[i];

                Point[] extendedLeftPoints1  = ExtendPointsOutwards(orderedLeftPoints, leftVec, d1, 0, 0, maxSize.Width, maxSize.Height).Where(x => x.Distance(headPoint) >= headDistanceThreshold).ToArray();
                Point[] extendedLeftPoints2  = ExtendPointsOutwards(orderedLeftPoints, leftVec, d2, 0, 0, maxSize.Width, maxSize.Height).Where(x => x.Distance(headPoint) >= headDistanceThreshold).ToArray();
                Point[] extendedRightPoints1 = ExtendPointsOutwards(orderedRightPoints, rightVec, d1, 0, 0, maxSize.Width, maxSize.Height).Where(x => x.Distance(headPoint) >= headDistanceThreshold).ToArray();
                Point[] extendedRightPoints2 = ExtendPointsOutwards(orderedRightPoints, rightVec, d2, 0, 0, maxSize.Width, maxSize.Height).Where(x => x.Distance(headPoint) >= headDistanceThreshold).ToArray();
                debugImg.DrawPolyline(extendedRightPoints1, false, new Bgr(Color.Yellow));
                debugImg.DrawPolyline(extendedRightPoints2, false, new Bgr(Color.Red));
                debugImg.DrawPolyline(extendedLeftPoints1, false, new Bgr(Color.Yellow));
                debugImg.DrawPolyline(extendedLeftPoints2, false, new Bgr(Color.Red));
                ImageViewer.Show(debugImg);
                //Generate curved portions
                double  startAngle = Math.Atan2(leftVec.Y, leftVec.X);
                Point[] ePoints    = GetCircularSegmentPoints(startAngle, Math.PI / 2, d1, 180, headPoint.ToPoint()).Reverse().ToArray();
                extendedLeftPoints1 = extendedLeftPoints1.Concat(ePoints.Reverse()).ToArray();

                ePoints             = GetCircularSegmentPoints(startAngle, Math.PI / 2, d2, 180, headPoint.ToPoint()).Reverse().ToArray();
                extendedLeftPoints2 = extendedLeftPoints2.Concat(ePoints.Reverse()).ToArray();

                startAngle = Math.Atan2(rightVec.Y, rightVec.X);

                ePoints = GetCircularSegmentPoints(startAngle, -Math.PI / 2, d1, 180, headPoint.ToPoint()).Reverse().ToArray();
                extendedRightPoints1 = extendedRightPoints1.Concat(ePoints.Reverse()).ToArray();

                ePoints = GetCircularSegmentPoints(startAngle, -Math.PI / 2, d2, 180, headPoint.ToPoint()).Reverse().ToArray();
                extendedRightPoints2 = extendedRightPoints2.Concat(ePoints.Reverse()).ToArray();

                //Reverse the second set of points
                Point[] leftMask  = extendedLeftPoints1.Concat(extendedLeftPoints2.Reverse()).ToArray();
                Point[] rightMask = extendedRightPoints1.Concat(extendedRightPoints2.Reverse()).ToArray();

                double lower = d1 < d2 ? d1 : d2;
                double upper = d1 < d2 ? d2 : d1;
                maskHolder.AddMask(leftMask, rightMask, lower, upper);
            }

            //Generate lines
            for (int i = 0; i < lineDistances.Length; i++)
            {
                double dist = lineDistances[i];

                Point[] extendedLeftPoints1  = ExtendPointsOutwards(orderedLeftPoints, leftVec, dist, 0, 0, maxSize.Width, maxSize.Height);
                Point[] extendedRightPoints1 = ExtendPointsOutwards(orderedRightPoints, rightVec, dist, 0, 0, maxSize.Width, maxSize.Height);
                maskHolder.LeftPoints.Add(extendedLeftPoints1);
                maskHolder.RightPoints.Add(extendedRightPoints1);

                //Generate curved portions
                double  startAngle = Math.Atan2(leftVec.Y, leftVec.X);
                Point[] ePoints    = GetCircularSegmentPoints(startAngle, Math.PI / 2, dist, 180, headPoint.ToPoint()).Reverse().ToArray();
                //maskHolder.LeftPoints.Add(ePoints);
                extendedLeftPoints1 = extendedLeftPoints1.Concat(ePoints.Reverse()).ToArray();

                startAngle = Math.Atan2(rightVec.Y, rightVec.X);

                ePoints = GetCircularSegmentPoints(startAngle, -Math.PI / 2, dist, 180, headPoint.ToPoint()).Reverse().ToArray();
                //maskHolder.RightPoints.Add(ePoints);
                extendedRightPoints1 = extendedRightPoints1.Concat(ePoints.Reverse()).ToArray();

                maskHolder.AddLine(extendedLeftPoints1, extendedRightPoints1, dist);
            }

            return(maskHolder);
        }