Beispiel #1
0
        // Draws the Delaunay triangulation into an image using the triangle indexes
        private void DrawDelaunay(ref Mat img, ref VectorOfPointF points, VectorOfVectorOfInt triangleIndexes, MCvScalar delaunayColor)
        {
            Size      size = img.Size;
            Rectangle rect = new Rectangle(0, 0, size.Width, size.Height);

            for (int i = 0; i < triangleIndexes.Size; i++)
            {
                VectorOfPoint tri = new VectorOfPoint();
                PointF        pp0 = points[triangleIndexes[i][0]];
                PointF        pp1 = points[triangleIndexes[i][1]];
                PointF        pp2 = points[triangleIndexes[i][2]];
                Point[]       p0  = { new Point((int)pp0.X, (int)pp0.Y) };
                Point[]       p1  = { new Point((int)pp1.X, (int)pp1.Y) };
                Point[]       p2  = { new Point((int)pp2.X, (int)pp2.Y) };
                tri.Push(p0);
                tri.Push(p1);
                tri.Push(p2);

                if (rect.Contains(tri[0]) && rect.Contains(tri[1]) && rect.Contains(tri[2]))
                {
                    CvInvoke.Line(img, tri[0], tri[1], delaunayColor, 2, Emgu.CV.CvEnum.LineType.AntiAlias, 0);
                    CvInvoke.Line(img, tri[1], tri[2], delaunayColor, 2, Emgu.CV.CvEnum.LineType.AntiAlias, 0);
                    CvInvoke.Line(img, tri[2], tri[0], delaunayColor, 2, Emgu.CV.CvEnum.LineType.AntiAlias, 0);
                }
            }
        }
Beispiel #2
0
        static MapMoveInfo GoToOrtogonalTop(byte[,,] data, Point playerCord)
        {
            VectorOfPoint vectorOfPoint = new VectorOfPoint();

            vectorOfPoint.Push(playerCord.YieldToArray());

            for (int i = playerCord.Y; i >= 0; i--)
            {
                var convStep = CalculateConvolutionStep(data, i, playerCord.X, 3);
                if (convStep != IntersectionType.Nothing)
                {
                    vectorOfPoint.Push(new Point(playerCord.X, i).YieldToArray());
                    return(new MapMoveInfo()
                    {
                        Vector = vectorOfPoint, Angle = 90, IntersectionType = convStep
                    });
                }
            }

            vectorOfPoint.Push(new Point(playerCord.X, 1).YieldToArray());
            return(new MapMoveInfo()
            {
                Angle = 90, IntersectionType = IntersectionType.Nothing, Vector = vectorOfPoint
            });
        }
Beispiel #3
0
        /// <summary>
        /// Filter points based on neighbor distance
        /// </summary>
        /// <param name="points">Point vector</param>
        /// <param name="maxNeighborDistance">Max distance from nearest neighbor</param>
        /// <returns>Filtered point vector</returns>
        private VectorOfPoint CompactOnNeighborhoodMedian(VectorOfPoint points, double maxNeighborDistance)
        {
            VectorOfPoint medianPoints = new VectorOfPoint();

            if (points.Size == 0)
            {
                return(medianPoints);
            }
            if (maxNeighborDistance <= 0)
            {
                return(medianPoints);
            }

            Point reference = points[0];
            Point median    = points[0];

            for (int i = 0; i < points.Size; i++)
            {
                if (findPointsDistance(reference, points[i]) > maxNeighborDistance)
                {
                    medianPoints.Push(new Point[] { median });
                    reference = points[i];
                    median    = points[i];
                }
                else
                {
                    median = new Point((points[i].X + median.X) / 2, (points[i].Y + median.Y) / 2);
                }
            }

            medianPoints.Push(new Point[] { median });
            return(medianPoints);
        }
Beispiel #4
0
        protected TMoveInfo PointToMoveInfo <TMoveInfo>(Point point) where TMoveInfo : MoveInfoBase, new()
        {
            VectorOfPoint vectorOfPoint = new VectorOfPoint();

            vectorOfPoint.Push(reader.PlayerCord.YieldToArray());
            vectorOfPoint.Push(point.YieldToArray());
            var angleLeft     = reader.PlayerCord.AngleBetweenCenterAndPoint(point);
            var anglegradLeft = 180 * angleLeft / Math.PI;

            return(new TMoveInfo()
            {
                Angle = anglegradLeft, Vector = vectorOfPoint
            });
        }
Beispiel #5
0
        private static List <PointF> GetMiniBox(List <Point> contours, out float minEdgeSize)
        {
            VectorOfPoint vop = new VectorOfPoint();

            vop.Push(contours.ToArray <Point>());
            return(GetMiniBox(vop, out minEdgeSize));
        }
Beispiel #6
0
    VectorOfPoint FinalizeTips(VectorOfPoint leftTips, VectorOfPoint rightTips)
    {
        VectorOfPoint finalTips = new VectorOfPoint();

        for (int i = 0; i < leftTips.Size; i++)
        {
            int    j2           = -1;
            double smallestDist = 10000;    //high default value
            Point  a            = leftTips[i];
            for (int j = 0; j < rightTips.Size; j++)
            {
                Point  b    = rightTips[j];
                double dist = CalculateDistance(a, b);
                if (dist < smallestDist)
                {
                    smallestDist = dist;
                    j2           = j;
                }
            }
            Console.WriteLine("leftTip num" + leftTips.Size);
            Console.WriteLine("rightTip num" + rightTips.Size);

            Console.WriteLine("dist" + smallestDist);
            finalTips.Push(new Point[] { a });
            if (smallestDist < 25)
            {
                //get rid of duplicate tip from rightTips
                VectorOfPoint tmp = new VectorOfPoint();
                for (int j = 0; j < rightTips.Size; j++)
                {
                    if (j != j2)
                    {
                        tmp.Push(new Point[] { rightTips[j] });
                    }
                }
                rightTips = tmp;
            }
        }
        //then add the rest of right tips (hopefully just one left)
        for (int i = 0; i < rightTips.Size; i++)
        {
            Point c = rightTips[i];
            finalTips.Push(new Point[] { c });
        }
        return(finalTips);
    }
Beispiel #7
0
        /// <summary>
        /// Find point with closest X value
        /// </summary>
        /// <param name="points">Points vector</param>
        /// <param name="pivot">Reference point</param>
        /// <returns></returns>
        private VectorOfPoint findClosestOnX(VectorOfPoint points, Point pivot)
        {
            VectorOfPoint result = new VectorOfPoint();

            if (points.Size == 0)
            {
                return(result);
            }

            double distanceX1 = Double.MaxValue;
            double distance1  = Double.MaxValue;
            double distanceX2 = Double.MaxValue;
            double distance2  = Double.MaxValue;
            int    indexFound = 0;

            for (int i = 0; i < points.Size; i++)
            {
                double distanceX = findPointsDistanceOnX(pivot, points[i]);
                double distance  = findPointsDistance(pivot, points[i]);

                if (distanceX < distanceX1 && distanceX != 0 && distance <= distance1)
                {
                    distanceX1 = distanceX;
                    distance1  = distance;
                    indexFound = i;
                }
            }
            result.Push(new Point[] { points[indexFound] });

            for (int i = 0; i < points.Size; i++)
            {
                double distanceX = findPointsDistanceOnX(pivot, points[i]);
                double distance  = findPointsDistance(pivot, points[i]);

                if (distanceX < distanceX2 && distanceX != 0 && distance <= distance2 && distanceX != distanceX1)
                {
                    distanceX2 = distanceX;
                    distance2  = distance;
                    indexFound = i;
                }
            }
            result.Push(new Point[] { points[indexFound] });

            return(result);
        }
Beispiel #8
0
        private static VectorOfPoint sortVector(VectorOfPoint vector)
        {
            var output = new VectorOfPoint();
            var left   = vector.ToArray().OrderBy(x => x.X).Take(2).ToArray();
            var top    = vector.ToArray().OrderBy(x => x.Y).Take(2).ToArray();

            var leftTop     = left.Intersect(top).ToArray();
            var leftBottom  = left.Except(top).ToArray();
            var rightTop    = top.Except(left).ToArray();
            var rightBottom = vector.ToArray().Except(left.Concat(top)).ToArray();

            output.Push(leftTop);
            output.Push(rightBottom);
            output.Push(leftBottom);
            output.Push(rightTop);

            return(output);
        }
Beispiel #9
0
        private VectorOfVectorOfPoint GetVVP(Point[] points)
        {
            VectorOfVectorOfPoint vvp = new VectorOfVectorOfPoint();
            VectorOfPoint         vp  = new VectorOfPoint();

            vp.Push(points);
            vvp.Push(vp);
            return(vvp);
        }
Beispiel #10
0
        //**********************************************************************************************************************************************************************************************
        //**********************************************************************************************************************************************************************************************
        //**********************************************************************************************************************************************************************************************

        #region Contour, Vector, Array utilities

        /// <summary>
        /// Return a contour that is translated.
        /// </summary>
        /// <param name="contourIn">Contour that should be translated</param>
        /// <param name="offset_x">X translation</param>
        /// <param name="offset_y">Y translation</param>
        /// <returns>Translated contour</returns>
        public static VectorOfPoint TranslateContour(VectorOfPoint contourIn, int offset_x, int offset_y)
        {
            VectorOfPoint ret_contour = new VectorOfPoint();

            for (int i = 0; i < contourIn.Size; i++)
            {
                ret_contour.Push(new Point((int)(contourIn[i].X + offset_x + 0.5), (int)(contourIn[i].Y + offset_y + 0.5)));
            }
            return(ret_contour);
        }
Beispiel #11
0
        static IEnumerable <VectorOfPoint> Vectorize(List <Point> points)
        {
            List <VectorOfPoint> vectorOfPoints = new List <VectorOfPoint>();
            VectorOfPoint        vpoints        = new VectorOfPoint();

            for (int i = 1; i < points.Count; i++)
            {
                if (points[i].Y > 0 && points[i - 1].Y == 0)
                {
                    vpoints.Push(points[i].YieldToArray());
                }
                if (points[i].Y == 0 && points[i - 1].Y > 0)
                {
                    vpoints.Push(points[i].YieldToArray());
                    vectorOfPoints.Add(vpoints);
                    vpoints = new VectorOfPoint();
                }
            }
            return(vectorOfPoints);
        }
Beispiel #12
0
        private VectorOfVectorOfPoint mergeContours(VectorOfVectorOfPoint _contours)
        {
            var dist = cfg.widthOfCameraView / cfg.ValvesCount /* / 2.5*/;
            List <VectorOfPoint> list = new List <VectorOfPoint>();

            List <VectorOfPoint> contours = new List <VectorOfPoint>();

            for (int i = 0; i < _contours.Size; i++)
            {
                contours.Add(_contours[i]);
            }

            List <Moments> moments = new List <Moments>();

            for (int i = 0; i < _contours.Size; i++)
            {
                moments.Add(CvInvoke.Moments(_contours[i], false));
            }


            for (int i = 0; i < contours.Count; i++)
            {
                if (contours[i] != null && moments[i].M00 != 0)
                {
                    VectorOfPoint n = contours[i];

                    //for (int j = 0; j < contours.Count; j++)
                    for (int j = i; j < contours.Count; j++)
                    {
                        if (i != j && contours[j] != null && moments[j].M00 != 0)
                        {
                            if (find_if_close(moments[i], moments[j], dist, cfg.widthOfCameraView))
                            {
                                n.Push(contours[j]);

                                contours[j] = null;
                            }
                        }
                    }

                    list.Add(n);
                }
            }


            VectorOfVectorOfPoint res = new VectorOfVectorOfPoint(list.ToArray());

            if (res.Size > 1)
            {
                ;
            }
            return(res);
        }
Beispiel #13
0
        //**********************************************************************************************************************************************************************************************

        /// <summary>
        /// Find corners, extract the edges and classify the piece
        /// </summary>
        private void process()
        {
            Bitmap bwImg = PieceImgBw.Bmp;
            Bitmap colorImg = PieceImgColor.Bmp;

            corners.Clear();
            PluginGroupFindPieceCorners pluginFindPieceCorners = PluginFactory.GetEnabledPluginsOfGroupType<PluginGroupFindPieceCorners>().FirstOrDefault();
            corners.Push(pluginFindPieceCorners?.FindCorners(PieceID, bwImg, colorImg).ToArray());

            bwImg.Dispose();
            colorImg.Dispose();

            extract_edges();
            classify();
        }
Beispiel #14
0
        static MapMoveInfo GoToOrtogonalBottom(byte[,,] data, Point playerCord)   //t
        {
            VectorOfPoint vectorOfPoint = new VectorOfPoint();

            vectorOfPoint.Push(playerCord.YieldToArray());

            for (int i = playerCord.Y; i < data.GetLength(0); i++)
            {
                var convStep = CalculateConvolutionStep(data, i, playerCord.X, 3);
                if (convStep != IntersectionType.Nothing)
                {
                    vectorOfPoint.Push(new Point(playerCord.X, i).YieldToArray());
                    return(new MapMoveInfo()
                    {
                        Vector = vectorOfPoint, Angle = 270, IntersectionType = convStep
                    });
                }
            }
            vectorOfPoint.Push(new Point(playerCord.X, data.GetLength(0) - 1).YieldToArray());
            return(new MapMoveInfo()
            {
                Angle = 270, IntersectionType = IntersectionType.Nothing, Vector = vectorOfPoint
            });
        }
Beispiel #15
0
        private void EmguCV_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            if (this.m_cvImage == null)
            {
                return;
            }

            switch (m_CurrentMode)
            {
            case ENUM_EmguCVControlEx_Mode.RectangleROI:
                int w = (int)(e.X - this.startX);
                int h = (int)(e.Y - this.startY);
                this.graphics.DrawRectangle(new Pen(new SolidBrush(Color.Red)), this.startX, this.startY, w, h);
                this.startDraw = false;
                this.DislpayObj(new Rectangle((int)startX, (int)startY, w, h));
                break;

            case ENUM_EmguCVControlEx_Mode.IrregularROI:
                this.startDraw = false;
                Point p = new Point(e.X, e.Y);
                this.curvePoints.Add(p);
                Pen redPen = new Pen(Color.Red, 1);
                graphics.DrawClosedCurve(redPen, curvePoints.ToArray());

                Mat roi = new Mat(m_cvImage.Size, DepthType.Cv8U, 3);
                Mat dst = new Mat();
                VectorOfVectorOfPoint contour = new VectorOfVectorOfPoint();
                VectorOfPoint         pts     = new VectorOfPoint();
                pts.Push(curvePoints.ToArray());
                contour.Push(pts);
                CvInvoke.DrawContours(roi, contour, 0, new MCvScalar(255, 255, 255), -1);
                m_cvImage.CopyTo(dst, roi);
                graphics.DrawImage(dst.ToImage <Bgr, Byte>().ToBitmap(), 0, 0, dst.Width, dst.Height);
                break;

            case ENUM_EmguCVControlEx_Mode.ImageMove:
                if (m_bCanMove)
                {
                    ImagePart.X += (int)(e.X - startX);
                    ImagePart.Y += (int)(e.Y - startY);
                    m_bCanMove   = false;
                }
                break;

            default:
                break;
            }
        }
        public VectorOfPoint GetTrainContour()
        {
            if (_trainContour.Size == 0)
            {
                VectorOfPointF corners = new VectorOfPointF();
                corners.Push(new PointF[] { new PointF(0.0f, 0.0f) });
                corners.Push(new PointF[] { new PointF(_referenceTrainImage.Cols, 0.0f) });
                corners.Push(new PointF[] { new PointF(_referenceTrainImage.Cols, _referenceTrainImage.Rows) });
                corners.Push(new PointF[] { new PointF(0.0f, _referenceTrainImage.Rows) });

                VectorOfPointF transformedCorners = new VectorOfPointF();
                CvInvoke.PerspectiveTransform(corners, transformedCorners, _homography);

                for (int i = 0; i < transformedCorners.Size; ++i)
                {
                    _trainContour.Push(new Point[] { new Point((int)transformedCorners[i].X, (int)transformedCorners[i].Y) });
                }
            }
            return(_trainContour);
        }
Beispiel #17
0
        //**********************************************************************************************************************************************************************************************

        /// <summary>
        /// This function takes in a vector of points, and transforms it so that it starts at the origin, and ends on the y-axis
        /// </summary>
        /// <param name="contour">Contour to normalize</param>
        /// <returns>normalized contour</returns>
        private VectorOfPoint normalize(VectorOfPoint contour)
        {
            if (contour.Size == 0)
            {
                return(contour);
            }

            VectorOfPoint ret_contour = new VectorOfPoint();
            PointF        a           = new PointF(contour.ToArray().First().X, contour.ToArray().First().Y);
            PointF        b           = new PointF(contour.ToArray().Last().X, contour.ToArray().Last().Y);

            //Calculating angle from vertical
            b.X = b.X - a.X;
            b.Y = b.Y - a.Y;

            double theta = Math.Acos(b.Y / (Utils.DistanceToOrigin(b)));

            if (b.X < 0)
            {
                theta = -theta;
            }

            //Theta is the angle every point needs rotated. and -a is the translation
            for (int i = 0; i < contour.Size; i++)
            {
                //Apply translation
                PointF temp_point = new PointF(contour[i].X - a.X, contour[i].Y - a.Y);

                //Apply roatation
                double new_x = Math.Cos(theta) * temp_point.X - Math.Sin(theta) * temp_point.Y;
                double new_y = Math.Sin(theta) * temp_point.X + Math.Cos(theta) * temp_point.Y;
                ret_contour.Push(new Point((int)new_x, (int)new_y));
            }

            return(ret_contour);
        }
Beispiel #18
0
        /// <summary>
        /// Count number of fingers on skinMask and draw debug information
        /// </summary>
        /// <param name="skinMask">Skin mask to count fingers on</param>
        /// <returns>Mat with detection debug information</returns>
        public Mat FindFingersCount(Mat skinMask)
        {
            Mat contoursImage = Mat.Ones(skinMask.Height, skinMask.Width, DepthType.Cv8U, 3);

            if (skinMask.IsEmpty || skinMask.NumberOfChannels != 1)
            {
                return(contoursImage);
            }

            VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();
            Mat hierarchy = new Mat();

            CvInvoke.FindContours(skinMask, contours, hierarchy, RetrType.External, ChainApproxMethod.ChainApproxNone);

            if (contours.Size <= 0)
            {
                return(contoursImage);
            }

            int    biggestContourIndex = -1;
            double biggestArea         = 0;

            for (int i = 0; i < contours.Size; i++)
            {
                double area = CvInvoke.ContourArea(contours[i], false);
                if (area > biggestArea)
                {
                    biggestArea         = area;
                    biggestContourIndex = i;
                }
            }
            if (biggestContourIndex < 0)
            {
                return(contoursImage);
            }

            VectorOfPoint hullPoints = new VectorOfPoint();
            VectorOfInt   hullInts   = new VectorOfInt();


            CvInvoke.ConvexHull(contours[biggestContourIndex], hullPoints, true);
            CvInvoke.ConvexHull(contours[biggestContourIndex], hullInts, false);

            Mat defects = new Mat();

            if (hullInts.Size > 3)
            {
                CvInvoke.ConvexityDefects(contours[biggestContourIndex], hullInts, defects);
            }
            else
            {
                return(contoursImage);
            }

            Rectangle boundingRectangle = CvInvoke.BoundingRectangle(hullPoints);

            Point         centerBoundingRectangle = new Point((boundingRectangle.X + boundingRectangle.Right) / 2, (boundingRectangle.Y + boundingRectangle.Bottom) / 2);
            VectorOfPoint startPoints             = new VectorOfPoint();
            VectorOfPoint farPoints = new VectorOfPoint();

            int[,,] defectsData = (int[, , ])defects.GetData();
            for (int i = 0; i < defectsData.Length / 4; i++)
            {
                Point startPoint = contours[biggestContourIndex][defectsData[i, 0, 0]];
                if (!startPoints.ToArray().ToList().Any(p => Math.Abs(p.X - startPoint.X) < 30 && Math.Abs(p.Y - startPoint.Y) < 30))
                {
                    VectorOfPoint startPointVector = new VectorOfPoint(new Point[] { startPoint });
                    startPoints.Push(startPointVector);
                }
                Point farPoint = contours[biggestContourIndex][defectsData[i, 0, 2]];
                if (findPointsDistance(farPoint, centerBoundingRectangle) < boundingRectangle.Height * BOUNDING_RECT_FINGER_SIZE_SCALING)
                {
                    VectorOfPoint farPointVector = new VectorOfPoint(new Point[] { farPoint });
                    farPoints.Push(farPointVector);
                }
            }


            VectorOfPoint filteredStartPoints = CompactOnNeighborhoodMedian(startPoints, boundingRectangle.Height * BOUNDING_RECT_NEIGHBOR_DISTANCE_SCALING);
            VectorOfPoint filteredFarPoints   = CompactOnNeighborhoodMedian(farPoints, boundingRectangle.Height * BOUNDING_RECT_NEIGHBOR_DISTANCE_SCALING);

            VectorOfPoint filteredFingerPoints = new VectorOfPoint();

            if (filteredFarPoints.Size > 1)
            {
                VectorOfPoint fingerPoints = new VectorOfPoint();

                for (int i = 0; i < filteredStartPoints.Size; i++)
                {
                    VectorOfPoint closestPoints = findClosestOnX(filteredFarPoints, filteredStartPoints[i]);

                    if (isFinger(closestPoints[0], filteredStartPoints[i], closestPoints[1], LIMIT_ANGLE_INF, LIMIT_ANGLE_SUP, centerBoundingRectangle, boundingRectangle.Height * BOUNDING_RECT_FINGER_SIZE_SCALING))
                    {
                        fingerPoints.Push(new Point[] { filteredStartPoints[i] });
                    }
                }
                if (fingerPoints.Size > 0)
                {
                    while (fingerPoints.Size > 5)
                    {
                        //Remove extra fingers
                        //Convert to list and remove last item
                        List <Point> points = new List <Point>(fingerPoints.ToArray());
                        points.Remove(points.Last());
                        fingerPoints = new VectorOfPoint(points.ToArray());
                    }
                    for (int i = 0; i < fingerPoints.Size - 1; i++)
                    {
                    }
                    filteredFingerPoints       = fingerPoints;
                    this.NumberOfFingersRaised = filteredFingerPoints.Size;
                }
            }

            Bgr colorRed    = new Bgr(Color.Red);
            Bgr colorGreen  = new Bgr(Color.Green);
            Bgr colorBlue   = new Bgr(Color.Blue);
            Bgr colorYellow = new Bgr(Color.Yellow);
            Bgr colorPurple = new Bgr(Color.Purple);
            Bgr colorWhite  = new Bgr(Color.White);

            //Debug, draw defects
            defectsData = (int[, , ])defects.GetData();
            for (int i = 0; i < defectsData.Length / 4; i++)
            {
                Point start = contours[biggestContourIndex][defectsData[i, 0, 0]];
                Point far   = contours[biggestContourIndex][defectsData[i, 0, 2]];
                Point end   = contours[biggestContourIndex][defectsData[i, 0, 1]];

                CvInvoke.Polylines(contoursImage, new Point[] { start, far, end }, true, colorPurple.MCvScalar, DRAW_THICKNESS / 2);
                CvInvoke.Circle(contoursImage, start, 5, colorWhite.MCvScalar);
                CvInvoke.Circle(contoursImage, far, 5, colorRed.MCvScalar, 10);
                CvInvoke.Circle(contoursImage, end, 5, colorBlue.MCvScalar);
            }

            //Draw information about what was detected (Contours, key points, fingers / how many fingers)
            CvInvoke.DrawContours(contoursImage, contours, 0, colorGreen.MCvScalar, DRAW_THICKNESS, LineType.AntiAlias);
            CvInvoke.Polylines(contoursImage, hullPoints, true, colorBlue.MCvScalar, DRAW_THICKNESS);
            CvInvoke.Rectangle(contoursImage, boundingRectangle, colorRed.MCvScalar, DRAW_THICKNESS);
            CvInvoke.Circle(contoursImage, centerBoundingRectangle, 5, colorYellow.MCvScalar, DRAW_THICKNESS);
            drawVectorPoints(contoursImage, filteredStartPoints, colorRed.MCvScalar, true, 3);
            drawVectorPoints(contoursImage, filteredFarPoints, colorWhite.MCvScalar, true, 3);
            drawVectorPoints(contoursImage, filteredFingerPoints, colorYellow.MCvScalar, false, 3);
            CvInvoke.PutText(contoursImage, filteredFingerPoints.Size.ToString(), centerBoundingRectangle, FontFace.HersheyComplex, 2, colorYellow.MCvScalar);


            return(contoursImage);
        }
Beispiel #19
0
        // Partial Match Algorithm using color feature
        // I used the framework for the partial matching algorithm using turning angle
        // but using the differences of the color on the edge
        public static Match partialColorMatch(List <Phi> DNAseq1, List <Phi> DNAseq2)
        {
            bool  flag = true; // ToDo: Compare the control points in contours between two parts
            Match segment;     // create an empty match segment

            segment.t11 = 0;
            segment.t12 = 0;
            segment.t21 = 0;
            segment.t22 = 0;

            List <Phi> seq1, seq2; // two empty List of edge maps
            int        best = 0, max_match;
            int        offset = 0, length = 0;

            if (DNAseq1.Count > DNAseq2.Count) // if the contour in first part has more control points than the second part
            {
                seq1 = replicateDNA(DNAseq1);  //replicate the larger DNA

                seq2 = DNAseq2.ToList();       //reverse the smaller one
                seq2.Reverse();
            }
            else
            {
                flag = false;
                seq1 = replicateDNA(DNAseq2); // if the first one has less control point, attach all the control points of the second part
                seq2 = DNAseq1.ToList();      //reverse the smaller one
                seq2.Reverse();
            }
            List <int> zc        = new List <int>();
            List <int> starts    = new List <int>();
            int        iteration = 0;

            for (int shift = 0; shift < seq1.Count - seq2.Count; shift += Constants.STEP)
            {
                List <int> diff = new List <int>();
                bool       flag1 = false;
                int        start = 0, end = 0;
                // TODO: change the differences into color difference (done)
                List <int> zeroCounts = new List <int>();
                int        zeroCount  = 0;
                List <int> starts2    = new List <int>();
                // TODO: need to add a tolerance level for some random non 0 differences
                int tolerCount = 0; // tolerance count for random non 0s.
                for (int i = 0; i < seq2.Count; ++i)
                {
                    int difference = Metrics.colorDifference(seq1[i + shift].color, seq2[i].color);
                    // if difference==0, flag
                    // if difference!=0, unflag
                    if (difference <= 0)
                    {
                        // if it is in unflag state, mark the point as starting point
                        if (!flag1)
                        {
                            flag1 = true;
                            start = i;
                            //starts.Add(start);
                            starts2.Add(start);
                        }
                        // count the number of zero difference points in this section
                        zeroCount++;
                        tolerCount = 0;
                    }
                    else
                    {
                        if (tolerCount <= Constants.COLOR_TOLERANCE)
                        {
                            if (flag1)
                            {
                                zeroCount++;
                                tolerCount++;
                            }
                        }
                        else
                        {
                            if (flag1)
                            {
                                zeroCounts.Add(zeroCount); // add to a upper level storage
                                zeroCount  = 0;            // reset the counter
                                flag1      = false;        // unflag
                                tolerCount = 0;
                            }
                        }
                    }


                    diff.Add(difference);
                }
                if (iteration == 33)
                {
                    Console.WriteLine("33");
                }
                if (zeroCounts.Count == 0)
                {
                    starts.Add(-1);
                }
                else
                {
                    starts.Add(starts2[zeroCounts.IndexOf(zeroCounts.Max())]);
                }
                if (zeroCounts.Count == 0)
                {
                    zc.Add(0);
                }
                else
                {
                    zc.Add(zeroCounts.Max());
                }

                // TTODO: implement a histogram algorithm for color match
                //max_match = colorHistogram(diff, seq2, ref start, ref end, Util.DELTA_THETA);
                max_match = 0;

                iteration++;
            }

            Console.WriteLine("Max:" + zc.Max());
            if (zc.Max() == 0)
            {
                goto a;
            }
            int t_shift = 0;
            int s_start = 0;

            for (int i = 0; i < zc.Count; i++)
            {
                if (zc[i] == zc.Max())
                {
                    t_shift = Constants.STEP * i;
                    s_start = starts[i];
                }
            }
            int startPos1 = t_shift + s_start;
            int endPos1   = startPos1 + zc.Max();
            int startPos2 = s_start;
            int endPos2   = startPos2 + zc.Max();

            length = zc.Max();
            // check if the algorithm get the correct position of the matching color
            Console.WriteLine("Flag:" + flag);
            Console.WriteLine("Shiftreq:" + startPos1);
            Console.WriteLine("Count:" + DNAseq1.Count);

            Console.WriteLine("P1_start_x" + seq1[startPos1].x);
            Console.WriteLine("P1_start_y" + seq1[startPos1].y);
            Console.WriteLine("P1_end_x" + seq1[endPos1].x);
            Console.WriteLine("P1_end_y" + seq1[endPos1].y);

            Console.WriteLine("P2_start_x" + seq2[startPos2].x);
            Console.WriteLine("P2_start_y" + seq2[startPos2].y);
            Console.WriteLine("P2_end_x" + seq2[endPos2].x);
            Console.WriteLine("P2_end_y" + seq2[endPos2].y);

            // correct for all the code above

            // regression analysis for the relationship between seq and DNA
            // flag=true for 3*3 frag5 and frag6
            if (flag)
            {
                for (int j = 0; j < DNAseq1.Count; j++)
                {
                    if ((seq1[startPos1].x == DNAseq1[j].x) && (seq1[startPos1].y == DNAseq1[j].y))
                    {
                        segment.t11 = j;

                        segment.t12 = j + zc.Max();
                        if (segment.t12 >= DNAseq1.Count)
                        {
                            segment.t12 -= DNAseq1.Count;
                        }
                    }
                }


                for (int j = 0; j < DNAseq2.Count; j++)
                {
                    if ((seq2[startPos2].x == DNAseq2[j].x) && (seq2[startPos2].y == DNAseq2[j].y))
                    {
                        segment.t21 = j;

                        segment.t22 = j - zc.Max();
                        if (segment.t22 < 0)
                        {
                            segment.t22 += DNAseq2.Count;
                        }
                    }
                }
            }
            else
            {
                for (int j = 0; j < DNAseq2.Count; j++)
                {
                    if ((seq1[startPos1].x == DNAseq2[j].x) && (seq1[startPos1].y == DNAseq2[j].y))
                    {
                        segment.t21 = j;

                        segment.t22 = j + zc.Max();
                        if (segment.t22 >= DNAseq2.Count)
                        {
                            segment.t22 -= DNAseq2.Count;
                        }
                    }
                }

                for (int j = 0; j < DNAseq1.Count; j++)
                {
                    if ((seq2[startPos2].x == DNAseq1[j].x) && (seq2[startPos2].y == DNAseq1[j].y))
                    {
                        segment.t11 = j;

                        segment.t12 = j - zc.Max();
                        if (segment.t12 < 0)
                        {
                            segment.t12 += DNAseq1.Count;
                        }
                    }
                }
            }



            // fine code below


            a : segment.x11 = (int)DNAseq1[segment.t11].x;
            segment.y11     = (int)DNAseq1[segment.t11].y;
            segment.x12     = (int)DNAseq1[segment.t12].x;
            segment.y12     = (int)DNAseq1[segment.t12].y;

            segment.x21 = (int)DNAseq2[segment.t21].x;
            segment.y21 = (int)DNAseq2[segment.t21].y;
            segment.x22 = (int)DNAseq2[segment.t22].x;
            segment.y22 = (int)DNAseq2[segment.t22].y;

            // correct at this point

            /*if (best == 0)
             *  segment.confidence = 0;
             * else
             *  segment.confidence = Math.Sqrt((double)(length * length) / best); */
            segment.confidence = length;
            Console.WriteLine(segment.ToString());
            // all the code above is the matching segment without considering edge feature
            // we need to consider edge feature at this point
            // and cull out the matching edge that does not match

            // consider the most simple case: straight line without rotating
            // then to edges with turning angles but still without rotating
            // then to general case

            // Step 1: extract the portion of DNA that forms the matching edge (done)
            List <Phi> edge1 = new List <Phi>(); // valid edge in image 1
            List <Phi> edge2 = new List <Phi>(); // valid edge in image 2

            for (int i = Math.Min(segment.t11, segment.t12); i < Math.Max(segment.t11, segment.t12); i++)
            {
                edge1.Add(DNAseq1[i]);
            }
            for (int i = Math.Min(segment.t21, segment.t22); i < Math.Max(segment.t21, segment.t22); i++)
            {
                edge2.Add(DNAseq2[i]);
            }
            if (edge1.Count == 0 || edge2.Count == 0)
            {
                goto r; // if there is no matching edge, it is not nessesary for culling
            }

            // Step 2: Analyze the edge feature

            // convert edge into contour
            VectorOfPoint c1;
            VectorOfPoint c2;
            List <Point>  pedge1;
            List <Point>  pedge2;


            c1 = new VectorOfPoint();
            List <Point> ps = new List <Point>();

            foreach (Phi p in edge1)
            {
                ps.Add(new Point((int)p.x, (int)p.y));
            }
            c1.Push(ps.ToArray());

            CvInvoke.ApproxPolyDP(c1, c1, 2.0, false);

            pedge1 = c1.ToArray().ToList();



            c2 = new VectorOfPoint();
            List <Point> ps2 = new List <Point>();

            foreach (Phi p in edge2)
            {
                ps2.Add(new Point((int)p.x, (int)p.y));
            }
            c2.Push(ps2.ToArray());

            CvInvoke.ApproxPolyDP(c2, c2, 2.0, false);

            pedge2 = c2.ToArray().ToList();



            // Step 3: Cull the edge
            // calculate the turning angle for each edge

            // if the cumulative turning angle change is greater than 90, restart

            // use a brute force longest straight line approach first, this solves a lot of cases
            int maxDistance = -99999;
            int pos1 = 0, pos2 = 0;

            for (int i = 0; i < pedge1.Count - 1; i++)
            {
                if (pedge1[i + 1].X == pedge1[i].X)
                {
                    if (Math.Abs(pedge1[i + 1].Y - pedge1[i].Y) > maxDistance)
                    {
                        maxDistance = Math.Abs(pedge1[i + 1].Y - pedge1[i].Y);
                        pos1        = i;
                    }
                }
                else if (pedge1[i + 1].Y == pedge1[i].Y)
                {
                    if (Math.Abs(pedge1[i + 1].X - pedge1[i].X) > maxDistance)
                    {
                        maxDistance = Math.Abs(pedge1[i + 1].X - pedge1[i].X);
                        pos1        = i;
                    }
                }
            }
            maxDistance = -99999;
            for (int i = 0; i < pedge2.Count - 1; i++)
            {
                if (pedge2[i + 1].X == pedge2[i].X)
                {
                    if (Math.Abs(pedge2[i + 1].Y - pedge2[i].Y) > maxDistance)
                    {
                        maxDistance = Math.Abs(pedge2[i + 1].Y - pedge2[i].Y);
                        pos2        = i;
                    }
                }
                else if (pedge2[i + 1].Y == pedge2[i].Y)
                {
                    if (Math.Abs(pedge2[i + 1].X - pedge2[i].X) > maxDistance)
                    {
                        maxDistance = Math.Abs(pedge2[i + 1].X - pedge2[i].X);
                        pos2        = i;
                    }
                }
            }

            // now the new matching edge is calculated, send the result to output

            for (int j = 0; j < DNAseq1.Count; j++)
            {
                if ((pedge1[pos1].X == DNAseq1[j].x) && (pedge1[pos1].Y == DNAseq1[j].y))
                {
                    segment.t11 = j;
                }
            }

            for (int j = 0; j < DNAseq2.Count; j++)
            {
                if ((pedge2[pos2].X == DNAseq2[j].x) && (pedge2[pos2].Y == DNAseq2[j].y))
                {
                    segment.t21 = j;
                }
            }
            for (int j = 0; j < DNAseq1.Count; j++)
            {
                if ((pedge1[pos1 + 1].X == DNAseq1[j].x) && (pedge1[pos1 + 1].Y == DNAseq1[j].y))
                {
                    segment.t12 = j;
                }
            }
            for (int j = 0; j < DNAseq2.Count; j++)
            {
                if ((pedge2[pos2 + 1].X == DNAseq2[j].x) && (pedge2[pos2 + 1].Y == DNAseq2[j].y))
                {
                    segment.t22 = j;
                }
            }
            segment.x11 = (int)DNAseq1[segment.t11].x;
            segment.y11 = (int)DNAseq1[segment.t11].y;
            segment.x12 = (int)DNAseq1[segment.t12].x;
            segment.y12 = (int)DNAseq1[segment.t12].y;

            segment.x21 = (int)DNAseq2[segment.t21].x;
            segment.y21 = (int)DNAseq2[segment.t21].y;
            segment.x22 = (int)DNAseq2[segment.t22].x;
            segment.y22 = (int)DNAseq2[segment.t22].y;



            r : return(segment);
        }
Beispiel #20
0
        // Partial Match Algorithm using color feature
        // I used the framework for the partial matching algorithm using turning angle
        // but using the differences of the color on the edge
        public static Match partialColorMatch(List<Phi> DNAseq1, List<Phi> DNAseq2)
        {
            bool flag = true; // ToDo: Compare the control points in contours between two parts
            Match segment; // create an empty match segment
            segment.t11 = 0;
            segment.t12 = 0;
            segment.t21 = 0;
            segment.t22 = 0;

            List<Phi> seq1, seq2; // two empty List of edge maps
            int best = 0, max_match;
            int offset = 0, length = 0;
            if (DNAseq1.Count > DNAseq2.Count) // if the contour in first part has more control points than the second part
            {
                seq1 = replicateDNA(DNAseq1);//replicate the larger DNA

                seq2 = DNAseq2.ToList();//reverse the smaller one
                seq2.Reverse();
            }
            else
            {
                flag = false;
                seq1 = replicateDNA(DNAseq2); // if the first one has less control point, attach all the control points of the second part
                seq2 = DNAseq1.ToList();//reverse the smaller one
                seq2.Reverse();
            }
            List<int> zc = new List<int>();
            List<int> starts = new List<int>();
            int iteration = 0;
            for (int shift = 0; shift < seq1.Count - seq2.Count; shift += Constants.STEP)
            {

                List<int> diff = new List<int>();
                bool flag1 = false;
                int start = 0, end = 0;
                // TODO: change the differences into color difference (done)
                List<int> zeroCounts = new List<int>();
                int zeroCount = 0;
                List<int> starts2 = new List<int>();
                // TODO: need to add a tolerance level for some random non 0 differences
                int tolerCount = 0; // tolerance count for random non 0s.
                for (int i = 0; i < seq2.Count; ++i)
                {
                    int difference = Metrics.colorDifference(seq1[i + shift].color, seq2[i].color);
                    // if difference==0, flag
                    // if difference!=0, unflag
                    if (difference <= 0)
                    {
                        // if it is in unflag state, mark the point as starting point
                        if (!flag1)
                        {
                            flag1 = true;
                            start = i;
                            //starts.Add(start);
                            starts2.Add(start);
                        }
                        // count the number of zero difference points in this section
                        zeroCount++;
                        tolerCount = 0;
                    }
                    else
                    {
                        if (tolerCount <= Constants.COLOR_TOLERANCE)
                        {
                            if (flag1)
                            {
                                zeroCount++;
                                tolerCount++;
                            }
                        }
                        else
                        {
                            if (flag1)
                            {
                                zeroCounts.Add(zeroCount); // add to a upper level storage
                                zeroCount = 0; // reset the counter
                                flag1 = false; // unflag
                                tolerCount = 0;
                            }
                        }
                    }

                    diff.Add(difference);
                }
                if (iteration == 33)
                {
                    Console.WriteLine("33");
                }
                if (zeroCounts.Count == 0)
                {
                    starts.Add(-1);
                }
                else
                {
                    starts.Add(starts2[zeroCounts.IndexOf(zeroCounts.Max())]);
                }
                if (zeroCounts.Count == 0)
                {
                    zc.Add(0);
                }
                else
                {
                    zc.Add(zeroCounts.Max());
                }

                // TTODO: implement a histogram algorithm for color match
                //max_match = colorHistogram(diff, seq2, ref start, ref end, Util.DELTA_THETA);
                max_match = 0;

                iteration++;
            }

            Console.WriteLine("Max:" + zc.Max());
            if (zc.Max() == 0)
            {
                goto a;
            }
            int t_shift = 0;
            int s_start = 0;
            for (int i = 0; i < zc.Count; i++)
            {
                if (zc[i] == zc.Max())
                {
                    t_shift = Constants.STEP * i;
                    s_start = starts[i];
                }
            }
            int startPos1 = t_shift + s_start;
            int endPos1 = startPos1 + zc.Max();
            int startPos2 = s_start;
            int endPos2 = startPos2 + zc.Max();
            length = zc.Max();
            // check if the algorithm get the correct position of the matching color
            Console.WriteLine("Flag:" + flag);
            Console.WriteLine("Shiftreq:" + startPos1);
            Console.WriteLine("Count:" + DNAseq1.Count);

            Console.WriteLine("P1_start_x" + seq1[startPos1].x);
            Console.WriteLine("P1_start_y" + seq1[startPos1].y);
            Console.WriteLine("P1_end_x" + seq1[endPos1].x);
            Console.WriteLine("P1_end_y" + seq1[endPos1].y);

            Console.WriteLine("P2_start_x" + seq2[startPos2].x);
            Console.WriteLine("P2_start_y" + seq2[startPos2].y);
            Console.WriteLine("P2_end_x" + seq2[endPos2].x);
            Console.WriteLine("P2_end_y" + seq2[endPos2].y);

            // correct for all the code above

            // regression analysis for the relationship between seq and DNA
            // flag=true for 3*3 frag5 and frag6
            if (flag)
            {

                for (int j = 0; j < DNAseq1.Count; j++)
                {
                    if ((seq1[startPos1].x == DNAseq1[j].x) && (seq1[startPos1].y == DNAseq1[j].y))
                    {
                        segment.t11 = j;

                        segment.t12 = j + zc.Max();
                        if (segment.t12 >= DNAseq1.Count)
                        {
                            segment.t12 -= DNAseq1.Count;
                        }

                    }
                }

                for (int j = 0; j < DNAseq2.Count; j++)
                {
                    if ((seq2[startPos2].x == DNAseq2[j].x) && (seq2[startPos2].y == DNAseq2[j].y))
                    {
                        segment.t21 = j;

                        segment.t22 = j - zc.Max();
                        if (segment.t22 < 0)
                        {
                            segment.t22 += DNAseq2.Count;
                        }

                    }
                }

            }
            else
            {
                for (int j = 0; j < DNAseq2.Count; j++)
                {
                    if ((seq1[startPos1].x == DNAseq2[j].x) && (seq1[startPos1].y == DNAseq2[j].y))
                    {
                        segment.t21 = j;

                        segment.t22 = j + zc.Max();
                        if (segment.t22 >= DNAseq2.Count)
                        {
                            segment.t22 -= DNAseq2.Count;
                        }

                    }
                }

                for (int j = 0; j < DNAseq1.Count; j++)
                {
                    if ((seq2[startPos2].x == DNAseq1[j].x) && (seq2[startPos2].y == DNAseq1[j].y))
                    {
                        segment.t11 = j;

                        segment.t12 = j - zc.Max();
                        if (segment.t12 < 0)
                        {
                            segment.t12 += DNAseq1.Count;
                        }

                    }
                }

            }

            // fine code below

            a: segment.x11 = (int)DNAseq1[segment.t11].x;
            segment.y11 = (int)DNAseq1[segment.t11].y;
            segment.x12 = (int)DNAseq1[segment.t12].x;
            segment.y12 = (int)DNAseq1[segment.t12].y;

            segment.x21 = (int)DNAseq2[segment.t21].x;
            segment.y21 = (int)DNAseq2[segment.t21].y;
            segment.x22 = (int)DNAseq2[segment.t22].x;
            segment.y22 = (int)DNAseq2[segment.t22].y;

            // correct at this point
            /*if (best == 0)
                segment.confidence = 0;
            else
                segment.confidence = Math.Sqrt((double)(length * length) / best); */
            segment.confidence = length;
            Console.WriteLine(segment.ToString());
            // all the code above is the matching segment without considering edge feature
            // we need to consider edge feature at this point
            // and cull out the matching edge that does not match

            // consider the most simple case: straight line without rotating
            // then to edges with turning angles but still without rotating
            // then to general case

            // Step 1: extract the portion of DNA that forms the matching edge (done)
            List<Phi> edge1 = new List<Phi>(); // valid edge in image 1
            List<Phi> edge2 = new List<Phi>(); // valid edge in image 2
            for (int i = Math.Min(segment.t11, segment.t12); i < Math.Max(segment.t11, segment.t12); i++)
            {
                edge1.Add(DNAseq1[i]);
            }
            for (int i = Math.Min(segment.t21, segment.t22); i < Math.Max(segment.t21, segment.t22); i++)
            {
                edge2.Add(DNAseq2[i]);
            }
            if (edge1.Count == 0 || edge2.Count == 0)
            {
                goto r; // if there is no matching edge, it is not nessesary for culling
            }

            // Step 2: Analyze the edge feature

            // convert edge into contour
            VectorOfPoint c1;
            VectorOfPoint c2;
            List<Point> pedge1;
            List<Point> pedge2;

            c1 = new VectorOfPoint();
            List<Point> ps=new List<Point>();
            foreach(Phi p in edge1)
            {
                ps.Add(new Point((int)p.x, (int)p.y));
            }
            c1.Push(ps.ToArray());

            CvInvoke.ApproxPolyDP(c1, c1, 2.0, false);

            pedge1 = c1.ToArray().ToList();

            c2 = new VectorOfPoint();
            List<Point> ps2 = new List<Point>();
            foreach (Phi p in edge2)
            {
                ps2.Add(new Point((int)p.x, (int)p.y));
            }
            c2.Push(ps2.ToArray());

            CvInvoke.ApproxPolyDP(c2, c2, 2.0, false);

            pedge2 = c2.ToArray().ToList();

            // Step 3: Cull the edge
            // calculate the turning angle for each edge

            // if the cumulative turning angle change is greater than 90, restart

            // use a brute force longest straight line approach first, this solves a lot of cases
            int maxDistance = -99999;
            int pos1 = 0, pos2 = 0;
            for (int i = 0; i < pedge1.Count - 1; i++)
            {
                if (pedge1[i + 1].X == pedge1[i].X)
                {
                    if (Math.Abs(pedge1[i + 1].Y - pedge1[i].Y) > maxDistance)
                    {
                        maxDistance = Math.Abs(pedge1[i + 1].Y - pedge1[i].Y);
                        pos1 = i;
                    }
                }
                else if (pedge1[i + 1].Y == pedge1[i].Y)
                {
                    if (Math.Abs(pedge1[i + 1].X - pedge1[i].X) > maxDistance)
                    {
                        maxDistance = Math.Abs(pedge1[i + 1].X - pedge1[i].X);
                        pos1 = i;
                    }
                }
            }
            maxDistance = -99999;
            for (int i = 0; i < pedge2.Count - 1; i++)
            {
                if (pedge2[i + 1].X == pedge2[i].X)
                {
                    if (Math.Abs(pedge2[i + 1].Y - pedge2[i].Y) > maxDistance)
                    {
                        maxDistance = Math.Abs(pedge2[i + 1].Y - pedge2[i].Y);
                        pos2 = i;
                    }
                }
                else if (pedge2[i + 1].Y == pedge2[i].Y)
                {
                    if (Math.Abs(pedge2[i + 1].X - pedge2[i].X) > maxDistance)
                    {
                        maxDistance = Math.Abs(pedge2[i + 1].X - pedge2[i].X);
                        pos2 = i;
                    }
                }
            }

            // now the new matching edge is calculated, send the result to output

            for (int j = 0; j < DNAseq1.Count; j++)
            {
                if ((pedge1[pos1].X == DNAseq1[j].x) && (pedge1[pos1].Y == DNAseq1[j].y))
                {
                    segment.t11 = j;

                }
            }

            for (int j = 0; j < DNAseq2.Count; j++)
            {
                if ((pedge2[pos2].X == DNAseq2[j].x) && (pedge2[pos2].Y == DNAseq2[j].y))
                {
                    segment.t21 = j;

                }
            }
            for (int j = 0; j < DNAseq1.Count; j++)
            {
                if ((pedge1[pos1 + 1].X == DNAseq1[j].x) && (pedge1[pos1 + 1].Y == DNAseq1[j].y))
                {
                    segment.t12 = j;

                }
            }
            for (int j = 0; j < DNAseq2.Count; j++)
            {
                if ((pedge2[pos2 + 1].X == DNAseq2[j].x) && (pedge2[pos2 + 1].Y == DNAseq2[j].y))
                {
                    segment.t22 = j;

                }
            }
            segment.x11 = (int)DNAseq1[segment.t11].x;
            segment.y11 = (int)DNAseq1[segment.t11].y;
            segment.x12 = (int)DNAseq1[segment.t12].x;
            segment.y12 = (int)DNAseq1[segment.t12].y;

            segment.x21 = (int)DNAseq2[segment.t21].x;
            segment.y21 = (int)DNAseq2[segment.t21].y;
            segment.x22 = (int)DNAseq2[segment.t22].x;
            segment.y22 = (int)DNAseq2[segment.t22].y;

            r: return segment;
        }
Beispiel #21
0
        private void MorphTriangle(ref Mat img1, ref Mat img2, ref Mat imgM, ref VectorOfPointF t1, ref VectorOfPointF t2, ref VectorOfPointF tM, float alpha)
        {
            // Find bounding rectangle for each triangle
            Rectangle r1 = CvInvoke.BoundingRectangle(t1);
            Rectangle r2 = CvInvoke.BoundingRectangle(t2);
            Rectangle rM = CvInvoke.BoundingRectangle(tM);

            // Offset points by left top corner of the respective rectangles
            VectorOfPointF t1RectFlt = new VectorOfPointF();
            VectorOfPointF t2RectFlt = new VectorOfPointF();
            VectorOfPointF tMRectFlt = new VectorOfPointF();

            // for fillConvexPoly we need ints
            VectorOfPoint tMrectInt = new VectorOfPoint();

            for (int i = 0; i < 3; i++)
            {
                PointF[] pfArrM = { new PointF(tM[i].X - rM.X, tM[i].Y - rM.Y) };
                tMRectFlt.Push(pfArrM);

                Point[] pArrInt = { new Point((int)(tM[i].X - rM.X), (int)(tM[i].Y - rM.Y)) };
                tMrectInt.Push(pArrInt);

                PointF[] pfArr1 = { new PointF(t1[i].X - r1.X, t1[i].Y - r1.Y) };
                t1RectFlt.Push(pfArr1);

                PointF[] pfArr2 = { new PointF(t2[i].X - r2.X, t2[i].Y - r2.Y) };
                t2RectFlt.Push(pfArr2);
            }

            // Create white triangle mask
            Mat mask = Mat.Zeros(rM.Height, rM.Width, Emgu.CV.CvEnum.DepthType.Cv32F, 3);

            CvInvoke.FillConvexPoly(mask, tMrectInt, new MCvScalar(1.0, 1.0, 1.0), Emgu.CV.CvEnum.LineType.AntiAlias, 0); // different

            // Apply warpImage to small rectangular patches
            Mat img1Rect = new Mat(img1, r1);
            Mat img2Rect = new Mat(img2, r2);


            Mat warpImage1 = Mat.Zeros(rM.Height, rM.Width, Emgu.CV.CvEnum.DepthType.Cv32F, 3);
            Mat warpImage2 = Mat.Zeros(rM.Height, rM.Width, Emgu.CV.CvEnum.DepthType.Cv32F, 3);


            ApplyAffineTransform(ref warpImage1, ref img1Rect, ref t1RectFlt, ref tMRectFlt);
            ApplyAffineTransform(ref warpImage2, ref img2Rect, ref t2RectFlt, ref tMRectFlt);


            // Alpha blend rectangular patches into new image
            Mat imgRect = new Mat();
            Image <Bgr, Byte> imgRect_I = (1.0f - alpha) * warpImage1.ToImage <Bgr, Byte>() + alpha * warpImage2.ToImage <Bgr, Byte>();

            imgRect = imgRect_I.Mat;

            // Delete all outside of triangle
            imgRect.ConvertTo(imgRect, Emgu.CV.CvEnum.DepthType.Cv32F);
            mask.ConvertTo(mask, Emgu.CV.CvEnum.DepthType.Cv32F);
            CvInvoke.Multiply(imgRect, mask, imgRect);

            // Delete all inside the target triangle
            Mat tmp = new Mat(imgM, rM);
            Image <Bgr, Byte> tmpI = tmp.ToImage <Bgr, Byte>();
            Mat mask_cp            = new Mat();

            mask.CopyTo(mask_cp);

            Image <Bgr, Byte> tmp_maskI = mask.ToImage <Bgr, Byte>();

            mask_cp.SetTo(new MCvScalar(1.0f, 1.0f, 1.0f));

            CvInvoke.Subtract(mask_cp, mask, mask);
            CvInvoke.Multiply(tmp, mask, tmp);
            count++;

            // Add morphed triangle to target image
            CvInvoke.Add(tmp, imgRect, tmp); // img(rM) = tmp;
            Mat x = new Mat(imgM, rM);

            tmp.CopyTo(x);
        }
Beispiel #22
0
        VectorOfVectorOfPoint FindBlobs(Mat binary, int index)
        {
            VectorOfVectorOfPoint blobs = new VectorOfVectorOfPoint();

            // Fill the label_image with the blobs
            // 0  - background
            // 1  - unlabelled foreground
            // 2+ - labelled foreground

            Mat label_image = new Mat();
            binary.ConvertTo(label_image, DepthType.Cv8U);

            int label_count = 2; // starts at 2 because 0,1 are used already

            for (int y = 0; y < label_image.Rows; y++)
            {

                for (int x = 0; x < label_image.Cols; x++)
                {
                    var val = label_image.GetData(y, x)[0];

                    if (val != 255)
                    {
                        continue;
                    }
 
                    System.Drawing.Rectangle rect;
                    CvInvoke.FloodFill(label_image, new Mat(), new System.Drawing.Point(x, y), new MCvScalar(label_count), out rect, new MCvScalar(0), new MCvScalar(0), Connectivity.FourConnected, FloodFillType.Default);
                    //cv::floodFill(label_image, cv::Point(x,y), label_count, &rect, 0, 0, 4);

                    VectorOfPoint blob = new VectorOfPoint();

                    for (int i = rect.Y; i < (rect.Y + rect.Height); i++)
                    {

                        for (int j = rect.X; j < (rect.X + rect.Width); j++)
                        {
                            var val2 = label_image.GetData(y, x)[0];
                            if (val2 != label_count)
                            {
                                continue;
                            }

                            blob.Push(new System.Drawing.Point[] { new System.Drawing.Point(j, i) });
                        }
                    }

                    blobs.Push(blob);

                    label_count++;
                }
            }

            label_image.Save("labeled" + index + ".bmp");

            return blobs;
        }
 public DartContour(VectorOfPoint points, double area)
 {
     ContourPoints = new VectorOfPoint();
     ContourPoints.Push(points);
     Area = area;
 }
Beispiel #24
0
    Image <Bgr, byte> DrawPoints(Image <Bgr, byte> image, Matrix <int> defects, VectorOfPoint contour)
    {
        Matrix <int>[] channels   = defects.Split();
        Bgr            green      = new Bgr(100, 255, 100);
        Bgr            red        = new Bgr(100, 100, 255);
        Bgr            blue       = new Bgr(255, 100, 100);
        VectorOfPoint  fingerTips = new VectorOfPoint();
        VectorOfPoint  palmPoints = new VectorOfPoint();    //palmPoints are a vector of all the defects

        //populate vector of all defects
        for (int i = 0; i < defects.Rows; i++)
        {
            palmPoints.Push(new Point[] { contour[channels[1][i, 0]] });
        }

        //find center of contour
        MCvMoments moments     = CvInvoke.Moments(contour);
        double     cx          = moments.M10 / moments.M00;
        double     cy          = moments.M01 / moments.M00;
        PointF     centerPoint = new PointF((float)cx, (float)cy);

        palmCenter.X    = (int)cx - outWidth / 2;
        palmCenter.Y    = (int)cy - outHeight / 2;
        fingerPoints[5] = palmCenter;
        image.Draw(new CircleF(centerPoint, 5), green, 5);
        //using center of contour, find min enclosed circle around an area
        //CircleF palmCirlce = FindPalm(contour, new Point((int)centerPoint.X, (int)centerPoint.Y), 50);
        //image.Draw(palmCirlce, red, 5);

        if (accuratePalm)
        {
            CircleF palmCirlce = FindPalmAccurate(contour);
            image.Draw(palmCirlce, red, 5);
            image.Draw(new CircleF(palmCirlce.Center, 5), blue, 5);
            return(image);
        }

        double        greatestAngle = 0; //greatest angle to center of hand will be thumb
        Point         thumbPoint    = new Point(0, 0);
        VectorOfPoint defectPoints  = new VectorOfPoint();
        VectorOfPoint leftTips      = new VectorOfPoint();
        VectorOfPoint rightTips     = new VectorOfPoint();

        for (int i = 0; i < defects.Rows; i++)
        {
            image.Draw(new Point[] { contour[channels[0][i, 0]],        //[0] is right point
                                     contour[channels[1][i, 0]],        //[1] is left point
                                     contour[channels[2][i, 0]]         //[2] is midpoint, the defect
                       },
                       green, 2);
            Point p  = new Point[] { contour[channels[1][i, 0]] }[0];   //p is left
            Point p2 = new Point[] { contour[channels[0][i, 0]] }[0];   //p2 is right
            Point p3 = new Point[] { contour[channels[2][i, 0]] }[0];   //p3 is mid

            PointF[] pf      = new PointF[] { new PointF(p.X, p.Y) };
            CircleF  circle  = new CircleF(pf[0], 5);
            PointF[] pf2     = new PointF[] { new PointF(p2.X, p2.Y) };
            CircleF  circle2 = new CircleF(pf2[0], 5);
            PointF[] pf3     = new PointF[] { new PointF(p3.X, p3.Y) };
            CircleF  circle3 = new CircleF(pf3[0], 5);

            double[] angle = new double[1];
            angle[0] = -1;
            if (IsFingertip(contour, channels, i, angle))
            {
                leftTips.Push(new Point[] { p });
                rightTips.Push(new Point[] { p2 });
                defectPoints.Push(new Point[] { p3 });
                // image.Draw(circle, red, 5);
                // image.Draw(circle2, blue, 5);
                //CvInvoke.PutText(image, angle[0].ToString(), p, FontFace.HersheyPlain, 1, new MCvScalar(255,255,255), 2);
                image.Draw(circle3, blue, 5);

                //check if thumb
                double thumbAngle = AngleOf(p, p2, centerPoint);
                if (thumbAngle > greatestAngle && thumbAngle > 35)  //35 found though experimentation to be lowest thumb angle
                {
                    double distLM = Math.Sqrt((p.X - p3.X) * (p.X - p3.X) + (p.Y - p3.Y) * (p.Y - p3.Y));
                    double distRM = Math.Sqrt((p2.X - p3.X) * (p2.X - p3.X) + (p2.Y - p3.Y) * (p2.Y - p3.Y));
                    greatestAngle = angle[0];
                    //thumb should be smallest distance to the midpoint
                    if (distLM < distRM)
                    {
                        thumbPoint = p;
                    }
                    else
                    {
                        thumbPoint = p2;
                    }
                }
                fingerTips.Push(new Point[] { p });
            }
        }

        //find close by tips, choose left one. The three middle tips are each counted twice
        VectorOfPoint finalTips = new VectorOfPoint();

        if (leftTips.Size != 0 && rightTips.Size != 0)
        {
            finalTips = FinalizeTips(leftTips, rightTips);
        }
        //draw tips
        int thumbIndex = 0;

        for (int i = 0; i < finalTips.Size; i++)
        {
            Point   tip       = finalTips[i];
            PointF  tipF      = tip;
            CircleF tipCircle = new CircleF(tipF, 5);
            image.Draw(tipCircle, red, 5);
            if (CalculateDistance(tip, thumbPoint) < 20)
            {
                thumbIndex = i;
                Console.WriteLine("Found Thumb at index: " + i);
            }
        }
        double[] distances = new double[finalTips.Size];
        //get relative distance between thumb and all fingers
        for (int i = 0; i < finalTips.Size; i++)
        {
            Console.WriteLine("i:" + i + "\n thumb index:" + thumbIndex);
            distances[i] = CalculateDistance(finalTips[thumbIndex], finalTips[i]);
        }
        //label all fingers based on distance to thumb
        for (int i = 0; i < distances.Length; i++)
        {
            double smallest = 10000;
            int    j2       = -1;
            //loop to find smallest distance
            for (int j = 0; j < distances.Length; j++)
            {
                if (distances[j] < smallest)
                {
                    smallest = distances[j];
                    j2       = j;
                }
            }
            distances[j2] = 200000;  //make distance longer so we can see next shortest distance on next pass
                                     //then switch on index of said distance;
            switch (i)
            {
            case 0:
                CvInvoke.PutText(image, "Thumb", finalTips[j2], FontFace.HersheyPlain, 1, new MCvScalar(0, 0, 0), 2);
                fingerPoints[0] = new Point(finalTips[j2].X - outWidth / 2, finalTips[j2].Y - outHeight / 2);
                Debug.Log("thumb :" + fingerPoints[0]);

                break;

            case 1:
                CvInvoke.PutText(image, "Index", finalTips[j2], FontFace.HersheyPlain, 1, new MCvScalar(100, 100, 200), 2);
                fingerPoints[1] = new Point(finalTips[j2].X - outWidth / 2, finalTips[j2].Y - outHeight / 2);
                break;

            case 2:
                CvInvoke.PutText(image, "Middle", finalTips[j2], FontFace.HersheyPlain, 1, new MCvScalar(100, 200, 100), 2);
                fingerPoints[2] = new Point(finalTips[j2].X - outWidth / 2, finalTips[j2].Y - outHeight / 2);
                break;

            case 3:
                CvInvoke.PutText(image, "Ring", finalTips[j2], FontFace.HersheyPlain, 1, new MCvScalar(200, 100, 100), 2);
                fingerPoints[3] = new Point(finalTips[j2].X - outWidth / 2, finalTips[j2].Y - outHeight / 2);
                break;

            case 4:
                CvInvoke.PutText(image, "Pinky", finalTips[j2], FontFace.HersheyPlain, 1, new MCvScalar(200, 200, 200), 2);
                fingerPoints[4] = new Point(finalTips[j2].X - outWidth / 2, finalTips[j2].Y - outHeight / 2);
                break;
            }
        }

        //CvInvoke.PutText(image, "Thumb", thumbPoint, FontFace.HersheyPlain, 1, new MCvScalar(0, 0, 0), 2);
        if (defectPoints.Size != 0)
        {
            //CircleF palm = CvInvoke.MinEnclosingCircle(defectPoints);
            //image.Draw(palm, red, 1);
        }
        return(image);
    }
Beispiel #25
0
        /// <summary>
        /// 创建Seal图像并填入指定图像
        /// </summary>
        /// <param name="Result"></param>
        /// <param name="ImgSize"></param>
        /// <param name="Template"></param>
        /// <param name="ImgFilePath"></param>
        /// <param name="charStr"></param>
        /// <param name="direction"></param>
        public static void CreateImg(ref Mat Result, Size ImgSize, DataTable Template, string ImgFilePath, string charStr, Direction direction)
        {
            //异常检测
            if (Template.Rows.Count <= 0 || Template.Columns.Count <= 0)
            {
                return;
            }
            //确定基本图像大小
            int width  = ImgSize.Width;  //Columns
            int height = ImgSize.Height; //Rows

            //创建图像
            Result = new Mat(new Size(ImgSize.Width * Template.Columns.Count, ImgSize.Height * Template.Rows.Count), DepthType.Cv8U, 3);//大小,深度 - 8u,通道 - 3
            //获取ImgFileList
            List <FileInfo> ImgFile = GetFile(ImgFilePath, ProgramData.ImgSuffix);

            //Result追加图像
            string id   = ""; //ID编号
            string name = ""; //文件名

            for (int i = 0; i < Template.Rows.Count; i++)
            {
                for (int j = 0; j < Template.Columns.Count; j++)
                {
                    if (charStr == ProgramData.SealStr)
                    {
                        id = Template.Rows[i][j].ToString().PadLeft(3, '0');//获取ID
                        if (id == "000" || string.IsNullOrEmpty(id))
                        {
                            continue;
                        }
                    }
                    else
                    {
                        id = Template.Rows[i][j].ToString();//获取ID
                        if (id == "0" || string.IsNullOrEmpty(id))
                        {
                            continue;
                        }
                    }
                    //拼接文件名
                    name = charStr + id;
                    //检测文件是否存在
                    FileInfo fileInfo = ImgFile.Where(o => o.Name.Contains(name)).FirstOrDefault();
                    if (fileInfo == null)
                    {
                        CvInvoke.PutText(Result, "Lost:" + name, new Point(width * j, height * i + height / 2), FontFace.HersheySimplex, 2, new MCvScalar(255, 255, 0), 2);//追加文字lost+文件名
                    }
                    else//图片存在
                    {
                        //判断文件是否被移除
                        if (File.Exists(fileInfo.FullName))
                        {
                            Mat Img = new Mat(fileInfo.FullName, ImreadModes.Color);                                                //读取文件
                            //CvInvoke.Imshow("Result"+ id, Img);
                            Rectangle rectangle = new Rectangle(new Point(width * j, height * i), new Size(Img.Width, Img.Height)); //创建放置区域,点和大小
                            Mat       figureTo  = new Mat(Result, rectangle);                                                       //定义指向区域
                            Img.CopyTo(figureTo);                                                                                   //将图像粘贴过去
                        }
                        else
                        {
                            CvInvoke.PutText(Result, "Lost:" + fileInfo.Name, new Point(width * i + width / 2, height * j + height / 2), FontFace.HersheySimplex, 10, new MCvScalar(255, 255, 0), 5);//追加文字lost+文件名
                        }
                    }
                }
            }
            //绘制网格线
            for (int i = 0; i <= Template.Rows.Count; i++)//横线 Rows
            {
                CvInvoke.Line(Result, new Point(0, height * i), new Point(width * Template.Columns.Count, height * i), new MCvScalar(0, 255, 0), 2, LineType.EightConnected);
            }
            for (int j = 0; j <= Template.Columns.Count; j++)//竖线 Columns
            {
                CvInvoke.Line(Result, new Point(width * j, 0), new Point(width * j, height * Template.Rows.Count), new MCvScalar(0, 255, 0), 2, LineType.EightConnected);
            }
            //绘制方向
            if (ProgramData.DirectType == 0)
            {
                //绘制三角形 方式0
                VectorOfPoint pointsArray = new VectorOfPoint();
                Point[]       points      = new Point[3];
                switch (direction)
                {
                case Direction.TopLeft:
                    points[0] = new Point(0, 0);
                    points[1] = new Point(ProgramData.ArrowSize.Width, 0);
                    points[2] = new Point(0, ProgramData.ArrowSize.Height);
                    pointsArray.Push(points);
                    CvInvoke.FillConvexPoly(Result, pointsArray, new MCvScalar(0, 0, 255), LineType.EightConnected);
                    break;

                case Direction.BottomLeft:
                    points[0] = new Point(0, Result.Height - ProgramData.ArrowSize.Height);
                    points[1] = new Point(0, Result.Height);
                    points[2] = new Point(ProgramData.ArrowSize.Width, Result.Height);
                    pointsArray.Push(points);
                    CvInvoke.FillConvexPoly(Result, pointsArray, new MCvScalar(0, 0, 255), LineType.EightConnected);
                    break;

                case Direction.TopRigth:
                    points[0] = new Point(Result.Width - ProgramData.ArrowSize.Width, 0);
                    points[1] = new Point(Result.Width, 0);
                    points[2] = new Point(Result.Width, ProgramData.ArrowSize.Height);
                    pointsArray.Push(points);
                    CvInvoke.FillConvexPoly(Result, pointsArray, new MCvScalar(0, 0, 255), LineType.EightConnected);
                    break;

                case Direction.BottomRight:
                    points[0] = new Point(Result.Width, Result.Height - ProgramData.ArrowSize.Height);
                    points[1] = new Point(Result.Width, Result.Height);
                    points[2] = new Point(Result.Width - ProgramData.ArrowSize.Width, Result.Height);
                    pointsArray.Push(points);
                    CvInvoke.FillConvexPoly(Result, pointsArray, new MCvScalar(0, 0, 255), LineType.EightConnected);
                    break;

                default:
                    break;
                }
            }
            else if (ProgramData.DirectType == 1)
            {
                //绘制箭头 方式1
                switch (direction)
                {
                case Direction.TopLeft:
                    CvInvoke.ArrowedLine(Result, new Point(ProgramData.ArrowSize), new Point(0, 0), new MCvScalar(0, 0, 255), 2, LineType.EightConnected);
                    break;

                case Direction.BottomLeft:
                    CvInvoke.ArrowedLine(Result, new Point(ProgramData.ArrowSize.Width, Result.Height - ProgramData.ArrowSize.Height), new Point(0, Result.Height), new MCvScalar(0, 0, 255), 5, LineType.EightConnected);
                    break;

                case Direction.TopRigth:
                    CvInvoke.ArrowedLine(Result, new Point(Result.Width - ProgramData.ArrowSize.Width, ProgramData.ArrowSize.Height), new Point(Result.Width, 0), new MCvScalar(0, 0, 255), 5, LineType.EightConnected);
                    break;

                case Direction.BottomRight:
                    CvInvoke.ArrowedLine(Result, new Point(Result.Width - ProgramData.ArrowSize.Width, Result.Height - ProgramData.ArrowSize.Height), new Point(Result.Width, Result.Height), new MCvScalar(0, 0, 255), 5, LineType.EightConnected);
                    break;

                default:
                    break;
                }
            }
            GC.Collect();//回收资源
        }
Beispiel #26
0
        private void loadLibrary(Mat image, int color)
        {
            Mat gray = new Mat(), blur = new Mat(), thresh = new Mat();

            CvInvoke.CvtColor(image, gray, ColorConversion.Bgr2Gray);
            CvInvoke.GaussianBlur(gray, blur, new System.Drawing.Size(1, 1), 1000);
            CvInvoke.Threshold(blur, thresh, 200, 255, ThresholdType.Binary);
            Mat hierarchy = new Mat();
            VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();

            CvInvoke.FindContours(thresh, contours, hierarchy, RetrType.Tree, ChainApproxMethod.ChainApproxNone);

            List <RotatedRect> foundCards = new List <RotatedRect>();

            for (int i = 0; i < contours.Size; ++i)
            {
                int j = i;
                while (j > 0 && CvInvoke.ContourArea(contours[j - 1], false) < CvInvoke.ContourArea(contours[j], false))
                {
                    VectorOfPoint tmp = new VectorOfPoint();
                    tmp.Push(contours[j]);
                    contours[j].Clear();
                    contours[j].Push(contours[j - 1]);
                    contours[j - 1].Clear();
                    contours[j - 1].Push(tmp);
                    j--;
                }
            }

            Image <Bgr, byte> tst = new Image <Bgr, byte>(image.Bitmap);

            int numCards = 0;

            for (int i = 0; i < contours.Size && numCards < 13; ++i)
            {
                VectorOfPoint card = contours[i];
                double        area = CvInvoke.ContourArea(card, false);

                double        peri   = CvInvoke.ArcLength(card, true);
                VectorOfPoint approx = new VectorOfPoint();
                CvInvoke.ApproxPolyDP(card, approx, 0.02 * peri, true);
                RotatedRect             rect = CvInvoke.MinAreaRect(card);
                System.Drawing.PointF[] r    = CvInvoke.BoxPoints(rect);

                bool stop = false;
                for (int j = 0; j < foundCards.Count; ++j)
                {
                    RotatedRect           crd    = foundCards[j];
                    System.Drawing.PointF center = crd.Center;
                    if (rect.MinAreaRect().Left < center.X && rect.MinAreaRect().Right > center.X && rect.MinAreaRect().Top < center.Y && rect.MinAreaRect().Bottom > center.Y)
                    {
                        stop = true;
                    }
                }
                if (stop)
                {
                    continue;
                }

                numCards++;
                System.Drawing.PointF[] points = new System.Drawing.PointF[4], points2 = new System.Drawing.PointF[4];
                points[0] = new System.Drawing.PointF(0, 0);
                points[1] = new System.Drawing.PointF(799, 0);
                points[2] = new System.Drawing.PointF(799, 799);
                points[3] = new System.Drawing.PointF(0, 799);

                //ImageViewer asd2 = new ImageViewer(thresh);
                //asd2.ShowDialog();

                for (int j = 0; j < approx.Size && j < 4; ++j)
                {
                    points2[j] = approx[j];
                }

                Array.Sort(points2, (a, b) => (int)(a.Y - b.Y));
                if (points2[0].X < points2[1].X)
                {
                    System.Drawing.PointF tmp = points2[0];
                    points2[0] = points2[1];
                    points2[1] = tmp;
                }
                if (points2[2].X > points2[3].X)
                {
                    System.Drawing.PointF tmp = points2[2];
                    points2[2] = points2[3];
                    points2[3] = tmp;
                }

                Mat transform = CvInvoke.GetPerspectiveTransform(points2, points);
                Mat warp      = new Mat();
                CvInvoke.WarpPerspective(blur, warp, transform, new System.Drawing.Size(800, 800));
                switch (numCards)
                {
                case 1:
                    library.Add(new Card(warp, color, 10));
                    break;

                case 2:
                    library.Add(new Card(warp, color, 11));
                    break;

                case 3:
                    library.Add(new Card(warp, color, 12));
                    break;

                case 4:
                    library.Add(new Card(warp, color, 13));
                    break;

                case 5:
                    library.Add(new Card(warp, color, 5));
                    break;

                case 6:
                    library.Add(new Card(warp, color, 6));
                    break;

                case 7:
                    library.Add(new Card(warp, color, 7));
                    break;

                case 8:
                    library.Add(new Card(warp, color, 8));
                    break;

                case 9:
                    library.Add(new Card(warp, color, 9));
                    break;

                case 10:
                    library.Add(new Card(warp, color, 1));
                    break;

                case 11:
                    library.Add(new Card(warp, color, 2));
                    break;

                case 12:
                    library.Add(new Card(warp, color, 3));
                    break;

                case 13:
                    library.Add(new Card(warp, color, 4));
                    break;
                }

                foundCards.Add(rect);
            }
        }
Beispiel #27
0
        //**********************************************************************************************************************************************************************************************
        //**********************************************************************************************************************************************************************************************
        //**********************************************************************************************************************************************************************************************

        /// <summary>
        /// Extract the contour.
        /// TODO: probably should have this passed in from the puzzle, since it already does this. It was done this way because the contours don't correspond to the correct pixel locations in this cropped version of the image.
        /// </summary>
        private void extract_edges()
        {
            Bitmap bwImg = PieceImgBw.Bmp;
            _logHandle.Report(new LogEventInfo(PieceID + " Extracting edges"));

            if (corners.Size != 4) { return; }

            VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();
            CvInvoke.FindContours(new Image<Gray, byte>(bwImg), contours, null, RetrType.List, ChainApproxMethod.ChainApproxNone);
            bwImg.Dispose();
            if (contours.Size == 0)
            {
                _logHandle.Report(new LogEventError(PieceID + " No contours found."));
                return;
            }

            int indexLargestContour = 0;                // Find the largest contour
            double largestContourArea = 0;
            for(int i = 0; i < contours.Size; i++)
            {
                double contourAreaTmp = CvInvoke.ContourArea(contours[i]);
                if(contourAreaTmp > largestContourArea) { largestContourArea = contourAreaTmp; indexLargestContour = i; }
            }

            VectorOfPoint contour = contours[indexLargestContour];

            VectorOfPoint new_corners = new VectorOfPoint();
            for (int i = 0; i < corners.Size; i++)      //out of all of the found corners, find the closest points in the contour, these will become the endpoints of the edges
            {
                double best = 10000000000;
                Point closest_point = contour[0];
                for (int j = 0; j < contour.Size; j++)
                {
                    double d = Utils.Distance(corners[i], contour[j]);
                    if (d < best)
                    {
                        best = d;
                        closest_point = contour[j];
                    }
                }
                new_corners.Push(closest_point);
            }
            corners = new_corners;

            if (PluginFactory.GetGeneralSettingsPlugin().SolverShowDebugResults)
            {
                Bitmap colorImg = PieceImgColor.Bmp;
                Image<Rgb, byte> edge_img = new Image<Rgb, byte>(colorImg);
                for (int i = 0; i < corners.Size; i++) { CvInvoke.Circle(edge_img, Point.Round(corners[i]), 2, new MCvScalar(255, 0, 0), 1); }
                _logHandle.Report(new LogEventImage(PieceID + " New corners", edge_img.Bitmap));
                colorImg.Dispose();
                edge_img.Dispose();
            }

            List<int> sections = find_all_in(contour, corners);

            //Make corners go in the correct order
            Point[] new_corners2 = new Point[4];
            int cornerIndexUpperLeft = -1;
            double cornerDistUpperLeft = double.MaxValue;
            for (int i = 0; i < 4; i++)
            {
                new_corners2[i] = contour[sections[i]];
                double cornerDist = Utils.DistanceToOrigin(contour[sections[i]]);
                if(cornerDist < cornerDistUpperLeft)
                {
                    cornerDistUpperLeft = cornerDist;
                    cornerIndexUpperLeft = i;
                }
            }
            new_corners2.Rotate(-cornerIndexUpperLeft);
            corners.Push(new_corners2);
            sections.Rotate(-cornerIndexUpperLeft);

            Edges[0] = new Edge(PieceID, 0, PieceImgColor, contour.GetSubsetOfVector(sections[0], sections[1]), _logHandle, _cancelToken);
            Edges[1] = new Edge(PieceID, 1, PieceImgColor, contour.GetSubsetOfVector(sections[1], sections[2]), _logHandle, _cancelToken);
            Edges[2] = new Edge(PieceID, 2, PieceImgColor, contour.GetSubsetOfVector(sections[2], sections[3]), _logHandle, _cancelToken);
            Edges[3] = new Edge(PieceID, 3, PieceImgColor, contour.GetSubsetOfVector(sections[3], sections[0]), _logHandle, _cancelToken);
        }
Beispiel #28
0
        //**********************************************************************************************************************************************************************************************

        /// <summary>
        /// Push a single point to a vector of points
        /// </summary>
        /// <param name="vector">Vector to push the point to</param>
        /// <param name="point">Point to push to the vector</param>
        public static void Push(this VectorOfPoint vector, Point point)
        {
            vector.Push(new Point[] { point });
        }
Beispiel #29
0
        static MapMoveInfo GoToOrtogonalRight(byte[,,] data, int incX, int incY, Point playerCord)
        {
            VectorOfPoint vectorOfPoint = new VectorOfPoint();

            vectorOfPoint.Push(playerCord.YieldToArray());
            var angle = 0d;

            if (incX == 1 && incY == 0)
            {
                angle = 0;
            }

            if (incX == 2 && incY == 1)
            {
                angle = 360 - 45 / 2d;
            }

            if (incX == 2 && incY == -1)
            {
                angle = 45 / 2d;
            }

            if (incX == 1 && incY == 1)
            {
                angle = 360 - 45;
            }

            if (incX == 1 && incY == -1)
            {
                angle = 45;
            }

            if (incX == 1 && incY == -2)
            {
                angle = 45 + 45 / 2d;
            }

            if (incX == 1 && incY == 2)
            {
                angle = 360 - 45 / 2d - 45;
            }

            var yCord = playerCord.Y;
            List <IntersectionType> accum = new List <IntersectionType>();

            for (int i = playerCord.X; i < data.GetLength(1); i += incX)
            {
                yCord += incY;
                var convStep = CalculateConvolutionStep(data, yCord, i, 3);
                if (convStep != IntersectionType.Nothing)
                {
                    accum.Add(convStep);
                }
                if (accum.Any() && convStep == IntersectionType.Nothing)
                {
                    vectorOfPoint.Push(new Point(i, yCord).YieldToArray());
                    var wallsCount = accum.Where(a => a == IntersectionType.Wall).Count();
                    var newArea    = accum.Where(a => a == IntersectionType.NewAreaFlag).Count();
                    return(new MapMoveInfo()
                    {
                        Vector = vectorOfPoint, Angle = angle, IntersectionType = wallsCount > newArea ? IntersectionType.Wall : IntersectionType.NewAreaFlag
                    });
                }
            }
            vectorOfPoint.Push(new Point(data.GetLength(1) - 1, yCord).YieldToArray());
            return(new MapMoveInfo()
            {
                Angle = angle, IntersectionType = IntersectionType.Nothing, Vector = vectorOfPoint
            });
        }
Beispiel #30
0
        public void ShellingCountour(Image <Gray, byte> convertImage)
        {
            this.DefectsVectorOfPoint = new VectorOfPoint();
            this.BoxRect = new RotatedRect();

            var copyImage = convertImage.Convert <Gray, byte>();

            var           largeContour        = 0;
            double        largestArea         = 0;
            VectorOfPoint largeContourOfPoint = null;
            VectorOfPoint hullPoint           = new VectorOfPoint();
            VectorOfPoint filtrRedHullPoint   = new VectorOfPoint();

            using (var contoursOfPoint = new VectorOfVectorOfPoint())
            {
                CvInvoke.FindContours(
                    copyImage,
                    contoursOfPoint,
                    null,
                    RetrType.External,
                    ChainApproxMethod.ChainApproxTc89Kcos);

                var count = contoursOfPoint.Size;

                for (var i = 0; i < count; i++)
                {
                    var approx = ContourArea(contoursOfPoint[i], false);

                    if (approx > largestArea)
                    {
                        largestArea         = approx;
                        largeContourOfPoint = new VectorOfPoint(contoursOfPoint[i].ToArray());
                        largeContour        = i;
                    }
                }

                if (largeContourOfPoint != null)
                {
                    var currentContour = new VectorOfPoint();

                    ApproxPolyDP(
                        largeContourOfPoint,
                        currentContour,
                        ArcLength(largeContourOfPoint, true) * 0.85,
                        true);

                    ContourArea(currentContour, false);
                    DrawContours(this.CurrentImage, contoursOfPoint, largeContour, new MCvScalar(0, 255, 0));


                    ConvexHull(largeContourOfPoint, hullPoint, false, true);
                    this.BoxRect = MinAreaRect(largeContourOfPoint);
                    PointF[] points = this.BoxRect.GetVertices();

                    ConvexityDefects(currentContour, hullPoint, this.DefectsVectorOfPoint);

                    Point[] ps = new Point[points.Length];
                    for (var j = 0; j < points.Length; j++)
                    {
                        ps[j] = new Point((int)points[j].X, (int)points[j].Y);
                    }

                    this.CurrentImage.DrawPolyline(hullPoint.ToArray(), true, new Bgr(200, 125, 75), 2);
                    this.CurrentImage.Draw(new CircleF(new PointF(this.BoxRect.Center.X, this.BoxRect.Center.Y), 3), new Bgr(200, 125, 75), 2);

                    for (var k = 0; k < hullPoint.Size - 1; k++)
                    {
                        var itemX = hullPoint[k].X - hullPoint[k + 1].X;
                        var itemY = hullPoint[k].Y - hullPoint[k + 1].Y;

                        var result = Math.Sqrt(Math.Pow(itemX, 2) + Math.Pow(itemY, 2));

                        if (result > (this.BoxRect.Size.Width / 10))
                        {
                            filtrRedHullPoint.Push(new[] { hullPoint[k] });
                        }
                    }
                }
            }
        }
Beispiel #31
0
        private void detectCards(Mat image, int cardsToDetect)
        {
            Mat gray = new Mat(), blur = new Mat(), thresh = new Mat();

            CvInvoke.CvtColor(image, gray, ColorConversion.Bgr2Gray);

            /*
             * Mat binary = new Mat(gray.Size, gray.Depth, gray.NumberOfChannels);
             * for(int i = 0; i < gray.Rows*gray.Cols; ++i)
             * {
             *  if (gray.GetData()[i] > 200)
             *  {
             *      binary.GetData()[i] = 201;
             *  }
             *  else
             *  {
             *      binary.GetData()[i] = 0;
             *  }
             * }*/

            CvInvoke.GaussianBlur(gray, blur, new System.Drawing.Size(1, 1), 1000);
            CvInvoke.Threshold(blur, thresh, 200, 255, ThresholdType.Binary);
            Mat hierarchy = new Mat();
            VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();

            CvInvoke.FindContours(thresh, contours, hierarchy, RetrType.Tree, ChainApproxMethod.ChainApproxNone);
            for (int i = 0; i < contours.Size; ++i)
            {
                int j = i;
                while (j > 0 && CvInvoke.ContourArea(contours[j - 1], false) < CvInvoke.ContourArea(contours[j], false))
                {
                    VectorOfPoint tmp = new VectorOfPoint();
                    tmp.Push(contours[j]);
                    contours[j].Clear();
                    contours[j].Push(contours[j - 1]);
                    contours[j - 1].Clear();
                    contours[j - 1].Push(tmp);
                    j--;
                }
            }

            List <RotatedRect> foundCards = new List <RotatedRect>();

            Image <Bgr, byte> tst = new Image <Bgr, byte>(image.Bitmap);

            int numCards = 0;

            for (int i = 0; i < contours.Size && numCards < cardsToDetect; ++i)
            {
                VectorOfPoint card = contours[i];
                double        area = CvInvoke.ContourArea(card, false);

                double        peri   = CvInvoke.ArcLength(card, true);
                VectorOfPoint approx = new VectorOfPoint();
                CvInvoke.ApproxPolyDP(card, approx, 0.02 * peri, true);
                RotatedRect             rect = CvInvoke.MinAreaRect(card);
                System.Drawing.PointF[] r    = CvInvoke.BoxPoints(rect);

                bool stop = false;
                for (int j = 0; j < foundCards.Count; ++j)
                {
                    RotatedRect           crd    = foundCards[j];
                    System.Drawing.PointF center = crd.Center;
                    if (rect.MinAreaRect().Left < center.X && rect.MinAreaRect().Right > center.X && rect.MinAreaRect().Top < center.Y && rect.MinAreaRect().Bottom > center.Y)
                    {
                        stop = true;
                    }
                }
                if (stop)
                {
                    continue;
                }

                numCards++;
                System.Drawing.PointF[] points = new System.Drawing.PointF[4], points2 = new System.Drawing.PointF[4];
                points[0] = new System.Drawing.PointF(0, 0);
                points[1] = new System.Drawing.PointF(799, 0);
                points[2] = new System.Drawing.PointF(799, 799);
                points[3] = new System.Drawing.PointF(0, 799);

                for (int j = 0; j < approx.Size && j < 4; ++j)
                {
                    points2[j] = approx[j];
                }

                Array.Sort(points2, (a, b) => (int)(a.Y - b.Y));
                if (points2[0].X < points2[1].X)
                {
                    System.Drawing.PointF tmp = points2[0];
                    points2[0] = points2[1];
                    points2[1] = tmp;
                }
                if (points2[2].X > points2[3].X)
                {
                    System.Drawing.PointF tmp = points2[2];
                    points2[2] = points2[3];
                    points2[3] = tmp;
                }

                Mat transform = CvInvoke.GetPerspectiveTransform(points2, points);
                Mat warp      = new Mat();
                CvInvoke.WarpPerspective(blur, warp, transform, new System.Drawing.Size(800, 800));
                //ImageViewer viewer = new ImageViewer(binary);
                //viewer.ShowDialog();
                Card recognizedCard = null;
                foreach (var c in library)
                {
                    if (recognizedCard == null)
                    {
                        recognizedCard = library[0];
                    }
                    Mat diff1 = new Mat(), diff2 = new Mat();
                    CvInvoke.AbsDiff(recognizedCard.GetImage(), warp, diff1);
                    CvInvoke.AbsDiff(c.GetImage(), warp, diff2);
                    var data1 = diff1.GetData();
                    int sum1  = 0;
                    foreach (var d in data1)
                    {
                        sum1 += d;
                    }
                    var data2 = diff2.GetData();
                    int sum2  = 0;
                    foreach (var d in data2)
                    {
                        sum2 += d;
                    }
                    if (sum2 <= sum1)
                    {
                        recognizedCard = c;
                    }
                }
                //ImageViewer asd = new ImageViewer(recognizedCard.GetImage());
                //asd.ShowDialog();
                Console.WriteLine(recognizedCard.GetColor() + ", " + recognizedCard.GetValue());
                if (cardsOnTable.Count == 0 || (cardsOnTable[cardsOnTable.Count - 1].GetColor() == recognizedCard.GetColor() && cardsOnTable[cardsOnTable.Count - 1].GetValue() == recognizedCard.GetValue()))
                {
                    cardsOnTable.Add(recognizedCard);
                }

                foundCards.Add(rect);
            }
        }