/// <summary>
 /// Construct from values.
 /// </summary>
 /// <param name="contour"></param>
 /// <param name="ellipse"></param>
 /// <param name="rating"></param>
 public DetectedEllipse(
   Emgu.CV.Contour<System.Drawing.Point> contour,
   Emgu.CV.Structure.Ellipse ellipse,
   double rating) {
   _contour = contour;
   _ellipse = ellipse;
   _rating = rating;
 }
示例#2
0
 /// <summary>
 /// Construct from values.
 /// </summary>
 /// <param name="contour"></param>
 /// <param name="ellipse"></param>
 /// <param name="rating"></param>
 public DetectedEllipse(
     Emgu.CV.Contour <System.Drawing.Point> contour,
     Emgu.CV.Structure.Ellipse ellipse,
     double rating)
 {
     _contour = contour;
     _ellipse = ellipse;
     _rating  = rating;
 }
示例#3
0
        /// <summary>
        /// this function used to perform the " Initialization step " in Hand Tracking Algorithm
        /// </summary>
        /// <param name="h">a contour point used to determine the bounding recatnagle around the hand</param>
        internal void ExtractFeatures(Emgu.CV.Contour <System.Drawing.Point> h)
        {
            GetImages();

            contour_rect      = h.BoundingRectangle;
            temp_Image.ROI    = contour_rect;
            current_image.ROI = contour_rect;

            foundFeaturesInChannels = current_image.GoodFeaturesToTrack(tracking_features_number, quality, min_distance, block_size);


            int founded_features = foundFeaturesInChannels[0].Length;

            for (int i = 0; i < founded_features; i++)
            {
                foundFeaturesInChannels[0][i].X += current_image.ROI.X;
                foundFeaturesInChannels[0][i].Y += current_image.ROI.Y;
                good_features.Add(foundFeaturesInChannels[0][i]);
            }



            temp_Image.ROI    = Rectangle.Empty;
            current_image.ROI = Rectangle.Empty;



            int ptt = tracking_features_number - founded_features;

            if (ptt > 0)
            {
                AddNewFeatures(ptt, foundFeaturesInChannels[0]);
            }


            previous_features = good_features.ToArray();

            for (int i = 0; i < previous_features.Length; i++)
            {
                feature_speeds[i] = 1;
                lost_feature[i]   = false;
            }


            good_features.Clear();
            bad_features.Clear();



            previous_image = current_image;

            Form1.NewImage = colored_temp_image;
        }
示例#4
0
        /// <summary>
        /// Fit ellipse through contour points in a least square sense.
        /// </summary>
        /// <param name="c">Contour</param>
        /// <returns>Ellipse</returns>
        private Emgu.CV.Structure.Ellipse FitByContour(Emgu.CV.Contour <System.Drawing.Point> c)
        {
            System.Drawing.PointF[] mypoints = Array.ConvertAll(
                c.ToArray <System.Drawing.Point>(),
                value => new System.Drawing.PointF(value.X, value.Y)
                );

            Emgu.CV.Structure.Ellipse  e   = Emgu.CV.PointCollection.EllipseLeastSquareFitting(mypoints);
            Emgu.CV.Structure.MCvBox2D box = e.MCvBox2D;
            // Modify ellipse to have width = a, height = b in the ellipse equation.
            box.size.Height *= 0.5f;
            box.size.Width  *= 0.5f;
            return(new Emgu.CV.Structure.Ellipse(box));
        }
示例#5
0
        /// <summary>
        /// Detect ellipses in image
        /// </summary>
        /// <param name="image">Binary image with white foreground</param>
        /// <returns>List of ellipses found</returns>
        public DetectedEllipse[] DetectEllipses(Emgu.CV.Image <Emgu.CV.Structure.Gray, byte> image)
        {
            List <DetectedEllipse> ellipses = new List <DetectedEllipse>();

            Emgu.CV.Contour <System.Drawing.Point> c = image.FindContours();

            while (c != null)
            {
                if (c.Count() >= _min_contour_count)
                {
                    Emgu.CV.Structure.Ellipse e = FitByContour(c);
                    double rating = GoodnessOfFit(e, c);
                    ellipses.Add(new DetectedEllipse(c, e, rating));
                }
                c = c.HNext;
            }

            return(ellipses.ToArray());
        }
示例#6
0
        /// <summary>
        /// Evaluate goodness of fit.
        /// </summary>
        /// <remarks>
        /// Calculates the average distance of all contour points to the ellipse. The distance of point to
        /// an ellipse is given by calculating the point on the ellipse that is closest to the query. This calculation
        /// is performed by transforming the point into a coordinate system where the ellipse is in main-pose
        /// (x-axis points toward a, y-axis points toward b, the origin is the center of the ellipse). Additionally,
        /// the coordinate system is crafted in such a way (non-uniform scaling) that the ellipse becomes a circle.
        /// Then, the closest point is simply the closest point on the circle. This point is transformed back into
        /// the world coordinate system where the distance between the query and the returned point is computed.
        /// </remarks>
        /// <param name="e">Ellipse</param>
        /// <param name="c">Contour points</param>
        /// <returns>Goodness of fit</returns>
        private double GoodnessOfFit(Emgu.CV.Structure.Ellipse e, Emgu.CV.Contour <System.Drawing.Point> c)
        {
            Matrix        m         = EllipseDetector.GetAffineFrame(e);
            Matrix        inv       = m.Inverse();
            List <double> distances = new List <double>();

            double avg_distance = 0.0;

            foreach (System.Drawing.Point p in c)
            {
                // Bring the point into the ellipse coordinate frame
                Vector x = p.ToParsley().ToHomogeneous(1.0);
                Vector r = (inv.Multiply(x.ToColumnMatrix())).GetColumnVector(0);
                // Find the closest point on the circle to r
                // From the above scaling construction the resulting circle has radius b
                Vector closest = r.ToNonHomogeneous().Normalize().Scale(e.MCvBox2D.size.Height);
                // Transform the closest point back
                Vector closest_in_world = (m.Multiply(closest.ToHomogeneous(1.0).ToColumnMatrix())).GetColumnVector(0);
                // Calculate the squared distance between the query and the point.
                avg_distance += (closest_in_world - x).ToNonHomogeneous().SquaredNorm();
            }
            return(Math.Sqrt(avg_distance / c.Count()));
        }
示例#7
0
        public void Horizontal()
        {
            System.Diagnostics.Stopwatch stop = new System.Diagnostics.Stopwatch();
            stop.Start();

            u = Horiz(SobelGray);
            stop.Stop();
            u = Proizvodnij1(u);
            u = Proizvodnij2(u);


            float max = MAX(u);

            DrawLine(u, max, Sobel);
            float      sum     = DrawMiddleLineHoriz(u, max, Sobel);
            List <int> maximum = SearchMaximums(u, sum, max, Sobel, false);

            Greenze(maximum, u);


            for (int i = 0; i < Horizont.Count; i++)
            {
                //Sobel.Draw(new CircleF(new System.Drawing.PointF(Convert.ToSingle(Sobel.Width * u[Horizont[i].k1] / max), Horizont[i].k1), 3), new Bgr(System.Drawing.Color.Red), 3);
                //Sobel.Draw(new CircleF(new System.Drawing.PointF(Convert.ToSingle(Sobel.Width * u[Horizont[i].k2] / max), Horizont[i].k2), 3), new Bgr(System.Drawing.Color.Red), 3);
                Horizont[i].original = Original.Copy(new System.Drawing.Rectangle(0, Horizont[i].k1, Original.Width, Horizont[i].k2 - Horizont[i].k1));
                Horizont[i].sobel    = Horizont[i].original.Convert <Gray, byte>();
                Horizont[i].sobel1   = Horizont[i].original.Convert <Bgr, byte>();
                Vertical(i);
                Horizont[i].p = Proizvodnij1(Horizont[i].p);
                Horizont[i].p = Proizvodnij2(Horizont[i].p);
                Horizont[i].p = Proizvodnij2(Horizont[i].p);
                float max1 = MAX(Horizont[i].p);
                float sum1 = DrawMiddleLineVertical(i, max1);
                float h    = Horizont[i].sobel1.Height * sum1 / max1;
                Horizont[i].sobel1.Draw(new LineSegment2DF(new System.Drawing.PointF(0, h), new System.Drawing.PointF(Horizont[i].sobel1.Width, h)), new Bgr(System.Drawing.Color.Blue), 2);
                GetPlate(i, sum1, max1);
            }
            stop.Stop();
            System.Diagnostics.Stopwatch st = new System.Diagnostics.Stopwatch();
            st.Start();
            Int32 ret = 0;

            for (int i = 0; i < Plate.Count; i++)
            {
                Ugol(Plate[i]);
                Plate[i].rotate2 = Plate[i].rotate.Resize(260, 56, Emgu.CV.CvEnum.INTER.CV_INTER_AREA);
                //

                Plate[i].rotate1 = Plate[i].rotate2.Convert <Gray, byte>();
                CvInvoke.cvCLAHE(Plate[i].rotate1, 5, new System.Drawing.Size(8, 8), Plate[i].rotate1);
                //Plate[i].rotate1 = Threshold.GrayHCH(Plate[i].rotate1);
                CvInvoke.cvNormalize(Plate[i].rotate1, Plate[i].rotate1, 0, 255, Emgu.CV.CvEnum.NORM_TYPE.CV_MINMAX, Plate[i].rotate1);

                CvInvoke.cvAdaptiveThreshold(Plate[i].rotate1, Plate[i].rotate1, 255, Emgu.CV.CvEnum.ADAPTIVE_THRESHOLD_TYPE.CV_ADAPTIVE_THRESH_GAUSSIAN_C, Emgu.CV.CvEnum.THRESH.CV_THRESH_BINARY_INV, 15, 13);
                List <System.Drawing.Rectangle> rec = new List <System.Drawing.Rectangle>();
                // Plate[i].rotate1 = Plate[i].rotate1.MorphologyEx(new StructuringElementEx(5, 5, 3, 3, Emgu.CV.CvEnum.CV_ELEMENT_SHAPE.CV_SHAPE_RECT), Emgu.CV.CvEnum.CV_MORPH_OP.CV_MOP_CLOSE, 1);
                using (Emgu.CV.MemStorage storage = new MemStorage())
                {
                    int il = 0;
                    for (Emgu.CV.Contour <System.Drawing.Point> contours = Plate[i].rotate1.Convert <Gray, byte>().FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE, Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_CCOMP); contours != null; contours = contours.HNext)
                    {
                        Emgu.CV.Contour <System.Drawing.Point> currentContour = contours;

                        if (currentContour.BoundingRectangle.X > 3 && currentContour.BoundingRectangle.Width > 10 && currentContour.BoundingRectangle.Height > 10 && currentContour.BoundingRectangle.Height < 200 && currentContour.BoundingRectangle.Width < 50 && currentContour.BoundingRectangle.Height / currentContour.BoundingRectangle.Width < 1.5)
                        {
                            il++;
                            Plate[i].rotate2.Draw(currentContour.BoundingRectangle, new Bgr(System.Drawing.Color.Red), 2);
                            rec.Add(currentContour.BoundingRectangle);
                        }
                    }

                    /*if (il < 1)
                     * {
                     *  Plate.Remove(Plate[i]);
                     *  i--;
                     *  continue;
                     * }*/
                }
                for (int io = rec.Count - 1; io >= 0; io--)
                {
                    for (int ip = 0; ip < io; ip++)
                    {
                        if (rec[ip].X > rec[ip + 1].X)
                        {
                            System.Drawing.Rectangle r = rec[ip];
                            rec[ip]     = rec[ip + 1];
                            rec[ip + 1] = r;
                        }
                    }
                }

                GetRect(i, rec);

                if (!IsPlate(i, rec))
                {
                    Plate.Remove(Plate[i]);
                    i--;
                    continue;
                }
                for (int ih = 0; ih < rec.Count; ih++)
                {
                    LetterDigit l = new LetterDigit();
                    l.LD = Plate[i].rotate1.Copy(rec[ih]);
                    ret++;
                    Plate[i].digit.Add(l);
                }

                Plate[i].px = new float[Plate[i].rotate1.Width];
                for (int kl = 0; kl < Plate[i].rotate1.Width; kl++)
                {
                    for (int kp = 0; kp < Plate[i].rotate1.Height; kp++)
                    {
                        if (Convert.ToInt32(Plate[i].rotate1[kp, kl].Intensity) == 255)
                        {
                            Plate[i].px[kl]++;
                        }
                    }
                }
                Plate[i].px = Proizvodnij1(Plate[i].px);
                Plate[i].px = Proizvodnij2(Plate[i].px);
                float maxpx = MAX(Plate[i].px);


                for (int h1 = 0, x = 0; h1 < Plate[i].px.Length - 1; h1++, x++)
                {
                    float j  = Plate[i].rotate2.Height * Plate[i].px[h1] / (maxpx);
                    float j1 = Plate[i].rotate2.Height * Plate[i].px[h1 + 1] / (maxpx);
                    Plate[i].rotate2.Draw(new LineSegment2DF(new System.Drawing.PointF(x, j), new System.Drawing.PointF(x, j1)), new Bgr(System.Drawing.Color.Red), 2);
                }
                List <int> min1 = SearchMininum(Plate[i].px, i, maxpx);

                /* double sumraz = Plate[i].rotate1.Width / min1.Count - 10;
                 * for (int il = 0; il < min1.Count-1; il++)
                 * {
                 *   double ggg= Math.Abs( min1[il+1] - min1[il]);
                 *   if (ggg < sumraz)
                 *   {
                 *       min1.Remove(min1[il + 1]);
                 *       il--;
                 *       continue;
                 *   }
                 *  /* if (il % 2 == 0)
                 *       Plate[i].rotate2.Draw(new LineSegment2DF(new System.Drawing.PointF(min1[il], 10), new System.Drawing.PointF(Convert.ToSingle(min1[il+1]), 10)), new Bgr(System.Drawing.Color.Aqua), 2);
                 *   if (il % 2 == 1)
                 *       Plate[i].rotate2.Draw(new LineSegment2DF(new System.Drawing.PointF(min1[il], 15), new System.Drawing.PointF(Convert.ToSingle(min1[il+1]), 15)), new Bgr(System.Drawing.Color.Orange), 2);
                 * }*/
                for (int il = 0; il < Plate[i].digit.Count; il++)
                {
                    for (int gh = 0; gh < images.Length; gh++)
                    {
                        Image <Gray, byte> res = Plate[i].digit[il].LD.Resize(10, 18, Emgu.CV.CvEnum.INTER.CV_INTER_CUBIC).Sub(images[gh]);

                        Plate[i].digit[il]._list.Add(Value2(images[gh], res));
                    }
                }


                //xOOOxxOOO
                Plate[i].text = TextLetter(i, 0) + TextDigit(i, 1) + TextDigit(i, 2) + TextDigit(i, 3) + TextLetter(i, 4) + TextLetter(i, 5) + TextDigit(i, 6) + TextDigit(i, 7) + TextDigit(i, 8);
                Original.Draw(new System.Drawing.Rectangle(Plate[i].x1, Plate[i].y1, Plate[i].x2 - Plate[i].x1, Plate[i].y2 - Plate[i].y1), new Bgr(System.Drawing.Color.Red), 2);
            }
            st.Stop();
        }
示例#8
0
        public void ProcessImage(Emgu.CV.Image <Emgu.CV.Structure.Bgr, byte> image)
        {
            Emgu.CV.Image <Gray, byte> gray = image.Convert <Gray, byte>();



            Emgu.CV.Image <Gray, byte> binary = new Image <Gray, byte>(image.Size);
            CvInvoke.cvThreshold(gray, binary, 40, 255, THRESH.CV_THRESH_BINARY | THRESH.CV_THRESH_OTSU);
            binary._Not();
            Emgu.CV.Contour <System.Drawing.Point> contour_points = binary.FindContours();

            MemStorage      storage = new MemStorage();
            Matrix <double> warp    = new Matrix <double>(3, 3);

            while (contour_points != null)
            {
                Contour <Point> c = contour_points.ApproxPoly(contour_points.Perimeter * 0.05, storage);
                double          p = c.Perimeter;
                if (c.Total == 4 && p > 300)
                {
                    PointF[] src = new PointF[] {
                        new PointF(c[0].X, c[0].Y),
                        new PointF(c[1].X, c[1].Y),
                        new PointF(c[2].X, c[2].Y),
                        new PointF(c[3].X, c[3].Y)
                    };

                    CvInvoke.cvGetPerspectiveTransform(src, _dest, warp);
                    int flags = (int)INTER.CV_INTER_LINEAR + (int)WARP.CV_WARP_FILL_OUTLIERS;
                    CvInvoke.cvWarpPerspective(gray, _roi, warp, flags, new MCvScalar(0));


                    double      min_error;
                    Orientation orient;

                    FindBestOrientation(out min_error, out orient);
                    if (min_error < 0.4)
                    {
                        image.DrawPolyline(c.ToArray(), true, new Bgr(Color.Green), 2);
                        System.Console.WriteLine(min_error + " " + orient);

                        switch (orient)
                        {
                        case Orientation.Degrees0:
                            image.Draw(new LineSegment2D(c[0], c[3]), new Bgr(System.Drawing.Color.Red), 2);
                            break;

                        case Orientation.Degrees90:
                            image.Draw(new LineSegment2D(c[1], c[0]), new Bgr(System.Drawing.Color.Red), 2);
                            break;

                        case Orientation.Degrees180:
                            image.Draw(new LineSegment2D(c[2], c[1]), new Bgr(System.Drawing.Color.Red), 2);
                            break;

                        case Orientation.Degrees270:
                            image.Draw(new LineSegment2D(c[3], c[2]), new Bgr(System.Drawing.Color.Red), 2);
                            break;
                        }
                    }

                    // 0 degrees
                }
                contour_points = contour_points.HNext;
            }
        }