Exemple #1
0
        public static Point FindMouseNoseTip(IEnumerable <Point> points, IEnumerable <Point> contourPoints)
        {
            List <Point> headPoints       = points.ToList();
            List <Point> allContourPoints = contourPoints.ToList();

            StraightLine vectorPointsLine = new StraightLine(headPoints[1], headPoints[3]);
            PointF       closestPointToNose;
            double       distance        = vectorPointsLine.FindDistanceToSegment(headPoints[2], out closestPointToNose);
            Point        closestIntPoint = new Point((int)closestPointToNose.X, (int)closestPointToNose.Y);
            StraightLine direction       = new StraightLine(closestIntPoint, headPoints[2]);

            float targetExtensionDistance = 3;
            Point targetLinePoint1        = new Point((int)(vectorPointsLine.StartPoint.X + (direction.NormalizedVector * distance * targetExtensionDistance).X), (int)(vectorPointsLine.StartPoint.Y + (direction.NormalizedVector * distance * targetExtensionDistance).Y));
            Point targetLinePoint2        = new Point((int)(vectorPointsLine.EndPoint.X + (direction.NormalizedVector * distance * targetExtensionDistance).X), (int)(vectorPointsLine.EndPoint.Y + (direction.NormalizedVector * distance * targetExtensionDistance).Y));

            StraightLine targetLine = new StraightLine(targetLinePoint1, targetLinePoint2);

            int   numberOfTargets = 5;
            float offset          = targetLine.GetMagnitude() / numberOfTargets;

            float finalDist = 10000;
            Point nosePoint = new Point();

            for (float currentTargetLength = 0; currentTargetLength <= targetLine.GetMagnitude(); currentTargetLength += offset)
            {
                Point currentTargetPoint = targetLine.DistanceFromStart(currentTargetLength);

                foreach (Point point in allContourPoints)
                {
                    float dist = currentTargetPoint.Distance(point);

                    if (dist < finalDist)
                    {
                        finalDist = dist;
                        nosePoint = point;
                    }
                }
            }

            return(nosePoint);
        }
Exemple #2
0
        public List <PointF> FindKeyPoints(Point[] points, float offset = 0, bool removeDuplicates = true)
        {
            //Stopwatch sw = new Stopwatch();
            //sw.Start();
            //Point[] allPoints = points.ToArray();
            List <PointF> result        = new List <PointF>();
            List <PointF> visitedPoints = new List <PointF>();
            PointF        currentPoint  = points[0];

            if (removeDuplicates)
            {
                visitedPoints.Add(currentPoint);
            }

            double distanceCounter = 0;

            if (offset == 0)
            {
                result.Add(currentPoint);
            }
            else
            {
                distanceCounter += offset;
            }

            int pointCounter = 1;

            while (true)
            {
                Point targetPoint = points[pointCounter];

                double dist = currentPoint.Distance(targetPoint);

                if (distanceCounter + dist >= Settings.GapDistance)
                {
                    StraightLine line     = new StraightLine(currentPoint, targetPoint);
                    double       addOn    = Settings.GapDistance - distanceCounter;
                    PointF       keyPoint = line.DistanceFromStart(addOn);
                    result.Add(keyPoint);
                    currentPoint    = keyPoint;
                    distanceCounter = 0;
                }
                else
                {
                    distanceCounter += dist;
                    currentPoint     = points[pointCounter];
                    pointCounter++;

                    if (pointCounter == points.Length)
                    {
                        break;
                    }

                    if (removeDuplicates)
                    {
                        if (visitedPoints.Contains(points[pointCounter]))
                        {
                            break;
                        }
                        else
                        {
                            visitedPoints.Add(points[pointCounter]);
                        }
                    }
                }
            }

            //sw.Stop();
            //Console.WriteLine("FindKeyPoints: " + sw.ElapsedMilliseconds);
            return(result);
        }
Exemple #3
0
        public static AutomatedRodentTracker.Services.RBSK.RBSK GetStandardMouseRules()
        {
            RBSKRules mouseRules = new RBSKRules();

            //Always make sure the number of parameters is correct first
            mouseRules.AddRule(new RBSKRule((x, s, b) =>
            {
                if (x.Length != s.NumberOfPoints)
                {
                    return(false);
                }

                return(true);
            }));

            //Rules regarding the points layout
            mouseRules.AddRule(new RBSKRule((x, s, b) =>
            {
                PointF nosePoint      = x[2];
                PointF[] vectorPoints = { x[1], x[3] };
                PointF[] rearPoints   = { x[0], x[4] };

                double gapDistance = s.GapDistance;

                //Calculate target areas
                double gapDistanceSquared = gapDistance * gapDistance;
                double targetHeadArea     = 0.433f * gapDistanceSquared;
                //float targetArea = gapDistanceSquared + targetHeadArea;

                //Check total area
                //float area = MathExtension.PolygonArea(x);
                //if (area < targetArea / 1.5)
                //{
                //    return false;
                //}

                //check head area
                float headArea = MathExtension.PolygonArea(new[] { vectorPoints[0], nosePoint, vectorPoints[1] });
                if (headArea < targetHeadArea / 2)
                {
                    return(false);
                }

                //Check which side the points lie on
                PointSideVector result = MathExtension.FindSide(vectorPoints[0], vectorPoints[1], nosePoint);

                if (result == PointSideVector.On)
                {
                    return(false);
                }

                PointSideVector rearResult1 = MathExtension.FindSide(vectorPoints[0], vectorPoints[1], rearPoints[0]);
                PointSideVector rearResult2 = MathExtension.FindSide(vectorPoints[0], vectorPoints[1], rearPoints[1]);

                //If the points are on the line then continue
                if (rearResult1 == PointSideVector.On || rearResult2 == PointSideVector.On)
                {
                    return(false);
                }

                //Make sure the rear points are on the opposite side to the nose point
                if (!(rearResult1 == rearResult2 && rearResult1 != result))
                {
                    return(false);
                }

                //Check rear points are correctly aligned with the center line
                PointF vectorMidPoint = new PointF((vectorPoints[0].X + vectorPoints[1].X) / 2, (vectorPoints[0].Y + vectorPoints[1].Y) / 2);

                rearResult1 = MathExtension.FindSide(nosePoint, vectorMidPoint, rearPoints[0]);
                rearResult2 = MathExtension.FindSide(nosePoint, vectorMidPoint, rearPoints[1]);

                if (rearResult1 == rearResult2)
                {
                    return(false);
                }

                StraightLine centerLine   = new StraightLine(nosePoint, vectorMidPoint);
                PointF targetRearMidPoint = centerLine.DistanceFromEndFloat(-s.GapDistance);
                centerLine = new StraightLine(nosePoint, targetRearMidPoint);

                double rearDist1 = centerLine.FindDistanceToSegment(rearPoints[0]);

                if (rearDist1 < s.GapDistance / 3)
                {
                    return(false);
                }

                rearDist1 = centerLine.FindDistanceToSegment(rearPoints[1]);

                if (rearDist1 < s.GapDistance / 3)
                {
                    return(false);
                }

                //The points are correctly aligned, make sure it's covering black pixels
                int blackCounter  = 0;
                int whiteCounter  = 0;
                StraightLine line = new StraightLine(vectorPoints[0], vectorPoints[1]);
                double distance   = line.GetMagnitude();
                float increment   = (float)distance / 10.0f;

                for (int j = 1; j < 9; j++)
                {
                    Point pointToCheck = line.DistanceFromStart(j * increment);
                    if (b[pointToCheck].Intensity <= 120)
                    {
                        blackCounter++;
                    }
                    else
                    {
                        whiteCounter++;
                    }
                }

                if (whiteCounter > blackCounter)
                {
                    return(false);
                }

                //Don't want the distance to be too great between the vector points
                //double distance = vectorPoints[0].Distance(vectorPoints[1]);
                //double distance = Math.Sqrt((vectorPoints[1].X - vectorPoints[0].X) + (vectorPoints[1].Y - vectorPoints[0].Y));
                if (distance > 1.4f * gapDistance)
                {
                    return(false);
                }

                //Rear distance must fall between a certain range
                double rearDistance = rearPoints[0].Distance(rearPoints[1]);
                if (rearDistance > 2.5f * gapDistance)
                {
                    return(false);
                }

                if (rearDistance < 1.2 * gapDistance)
                {
                    return(false);
                }

                return(true);
            }));

            RBSKRules advancedRules = new RBSKRules();

            advancedRules.AddRule(new RBSKRule((x, s, b) =>
            {
                Point intNosePoint    = x[2].ToPoint();
                Point intVectorPoint1 = x[1].ToPoint();
                Point intVectorPoint2 = x[3].ToPoint();

                Image <Gray, Byte> mask = new Image <Gray, byte>(b.Cols, b.Rows, new Gray(0));
                mask.FillConvexPoly(new[] { intNosePoint, intVectorPoint1, intVectorPoint2 }, new Gray(255), LineType.FourConnected);

                double avgIntensity = b.GetAverage(mask).Intensity;

                if (avgIntensity > 10)
                {
                    return(false);
                }

                return(true);
            }));

            //Create probability funcation
            RBSKProbability rbskProbability = new RBSKProbability((p, s) =>
            {
                PointF[] points = p;

                if (points.Length != 5)
                {
                    return(0);
                }

                //float gapDistanceSquared = s.GapDistance*s.GapDistance;

                StraightLine line = new StraightLine(points[1], points[3]);

                //Need to normalize the line
                double targetNoseDistance = 0.866d * s.GapDistance;
                double actualNoseDistance = line.FindDistanceToSegment(points[2]);
                double noseProbability;

                if (targetNoseDistance > actualNoseDistance)
                {
                    noseProbability = actualNoseDistance / targetNoseDistance;
                }
                else
                {
                    noseProbability = targetNoseDistance / actualNoseDistance;
                }

                //float targetHeadArea = 0.433f * gapDistanceSquared;
                //float targetHeadArea = (float)MathExtension.PolygonArea(new[]
                //{
                //    new Point(0, 0),
                //    new Point((int)s.GapDistance, 0),
                //    new Point((int)(s.GapDistance/2), (int)(s.GapDistance*0.866f)),
                //});
                //float actualHeadArea = MathExtension.PolygonArea(new[]
                //{
                //    points[1], points[2], points[3]
                //});
                //float areaProbability;

                //if (targetHeadArea > actualHeadArea)
                //{
                //    areaProbability = actualHeadArea / targetHeadArea;
                //}
                //else
                //{
                //    areaProbability = targetHeadArea / actualHeadArea;
                //}

                return(noseProbability);// * areaProbability;
            });

            return(new AutomatedRodentTracker.Services.RBSK.RBSK(mouseRules, advancedRules, new RBSKSettings(5), rbskProbability));
        }