示例#1
0
        public unsafe Contour AutoCorrelation(bool normalize)
        {
            int     capacity = this.Count / 2;
            Contour contour  = new Contour(capacity);

            fixed(Complex *complexRef = contour.array)
            {
                Complex *complexPtr = complexRef;
                double   d          = 0.0;
                int      shift      = 0;

                while (shift < capacity)
                {
                    complexPtr[0] = this.Dot(this, shift);
                    double normaSquare = complexPtr->NormaSquare;
                    if (normaSquare > d)
                    {
                        d = normaSquare;
                    }
                    complexPtr++;
                    shift++;
                }
                if (normalize)
                {
                    d          = Math.Sqrt(d);
                    complexPtr = complexRef;
                    for (shift = 0; shift < capacity; shift++)
                    {
                        complexPtr[0] = new Complex(complexPtr->a / d, complexPtr->b / d);
                        complexPtr++;
                    }
                }
            }

            return(contour);
        }
示例#2
0
 /// <summary>
 /// Scalar product
 /// </summary>
 public Complex Dot(Contour c)
 {
     return Dot(c, 0);
 }
示例#3
0
        /// <summary>
        /// Scalar product
        /// </summary>
        public unsafe Complex Dot(Contour c, int shift)
        {
            var count = Count;
            double sumA = 0;
            double sumB = 0;
            fixed (Complex* ptr1 = &array[0])
            fixed (Complex* ptr2 = &c.array[shift])
            fixed (Complex* ptr22 = &c.array[0])
            fixed (Complex* ptr3 = &c.array[c.Count - 1])
            {
                Complex* p1 = ptr1;
                Complex* p2 = ptr2;
                for (int i = 0; i < count; i++)
                {
                    Complex x1 = *p1;
                    Complex x2 = *p2;
                    sumA += x1.a * x2.a + x1.b * x2.b;
                    sumB += x1.b * x2.a - x1.a * x2.b;

                    p1++;
                    if (p2 == ptr3)
                        p2 = ptr22;
                    else
                        p2++;
                }
            }
            return new Complex(sumA, sumB);
        }
示例#4
0
 public double Distance(Contour c)
 {
     double n1 = this.Norma;
     double n2 = c.Norma;
     return n1 * n1 + n2 * n2 - 2 * (this.Dot(c).a);
 }
示例#5
0
 /// <summary>
 /// Returns R^2 of difference of norms
 /// </summary>
 /// <param name="c"></param>
 /// <returns></returns>
 public double DiffR2(Contour c)
 {
     double max1 = 0;
     double max2 = 0;
     double sum = 0;
     for (int i = 0; i < Count; i++)
     {
         double v1 = array[i].Norma;
         double v2 = c.array[i].Norma;
         if (v1 > max1) max1 = v1;
         if (v2 > max2) max2 = v2;
         double v = v1 - v2;
         sum += v * v;
     }
     double max = Math.Max(max1, max2);
     return 1 - sum / Count / max / max;
 }
 private List<Contour<Point>> ConvertContours(Contour<Point> contours)
 {
     var c = contours;
     List<Contour<Point>> result = new List<Contour<Point>>();
     while (c != null)
     {
         result.Add(c);
         c = c.HNext;
     }
     return result;
 }
示例#7
0
        public void FindBestContour(ImageProcessor processor, double owerflowContoursRatio)
        {
            int secondBiggestContourIndex;
            processor.ProcessImage(new Image<Bgr, Byte>(new Bitmap(_digit)), true);
            var biggestContourIndex = SortContour(processor, out secondBiggestContourIndex);

            if (((biggestContourIndex != secondBiggestContourIndex) &&
                (processor.contours[biggestContourIndex].Area / processor.contours[secondBiggestContourIndex].Area <
                 owerflowContoursRatio)) || (processor.contours.Count < 3))
            {
                _contour = processor.contours[secondBiggestContourIndex];
            }
            else
            {
                _contour = processor.contours[biggestContourIndex];
            }
        }
示例#8
0
 /// <summary>
 /// Intercorrelcation function (ICF)
 /// maxShift - max deviation (left+right)
 /// </summary>
 public Contour InterCorrelation(Contour c, int maxShift)
 {
     Contour result = new Contour(maxShift);
     int i = 0;
     int count = Count;
     while (i < maxShift/2)
     {
         result.array[i] = Dot(c, i);
         result.array[maxShift - i - 1] = Dot(c, c.Count - i - 1);
         i++;
     }
     return result;
 }
示例#9
0
        public void Draw(Graphics gr, Rectangle rect)
        {
            int num8;
            int right;

            gr.DrawRectangle(Pens.SteelBlue, rect);
            rect = new Rectangle(rect.Left, rect.Top, rect.Width - 0x18, rect.Height);
            Contour contour  = this.contour.Clone();
            Contour contour2 = this.autoCorr.Clone();

            contour2.Normalize();
            Rectangle rectangle = new Rectangle(rect.X, rect.Y, rect.Width / 2, rect.Height);

            rectangle.Inflate(-20, -20);
            Point[]   points     = contour.GetPoints(this.startPoint);
            Rectangle rectangle2 = Rectangle.Round(contour.GetBoundsRect());
            double    width      = rectangle2.Width;
            double    height     = rectangle2.Height;
            float     num3       = (float)Math.Min((double)(((double)rectangle.Width) / width), (double)(((double)rectangle.Height) / height));
            int       num4       = this.startPoint.X - contour.SourceBoundingRect.Left;
            int       num5       = this.startPoint.Y - contour.SourceBoundingRect.Top;
            int       num6       = -((int)(rectangle2.Left * num3));
            int       num7       = (int)(rectangle2.Bottom * num3);

            for (num8 = 0; num8 < points.Length; num8++)
            {
                points[num8] = new Point((rectangle.Left + num6) + ((int)(((points[num8].X - contour.SourceBoundingRect.Left) - num4) * num3)), (rectangle.Top + num7) + ((int)(((points[num8].Y - contour.SourceBoundingRect.Top) - num5) * num3)));
            }
            gr.DrawPolygon(Pens.Red, points);
            rectangle = new Rectangle((rect.Width / 2) + rect.X, rect.Y, rect.Width / 2, rect.Height);
            rectangle.Inflate(-20, -20);
            List <Point> list = new List <Point>();

            for (num8 = 0; num8 < contour2.Count; num8++)
            {
                right = (rectangle.X + 5) + (num8 * 3);
                Complex complex = contour2[num8 % contour2.Count];
                int     num10   = (int)(complex.Norma * rectangle.Height);
                gr.FillRectangle(Brushes.Blue, right, rectangle.Bottom - num10, 3, num10);
                complex = contour2[num8 % contour2.Count];
                list.Add(new Point(right, rectangle.Bottom - ((int)(rectangle.Height * (0.5 + ((complex.Angle / 2.0) / 3.1415926535897931))))));
            }
            try
            {
                gr.DrawLines(Pens.Red, list.ToArray());
            }
            catch (OverflowException)
            {
            }
            Pen pen = new Pen(Color.FromArgb(100, Color.Black));

            for (num8 = 0; num8 <= 10; num8++)
            {
                gr.DrawLine(pen, rectangle.X, rectangle.Bottom - ((num8 * rectangle.Height) / 10), rectangle.X + rectangle.Width, rectangle.Bottom - ((num8 * rectangle.Height) / 10));
            }
            right = rect.Right;
            int num11 = rectangle.Bottom - (rectangle.Height / 2);

            gr.DrawLine(Pens.Gray, right, num11, right + 0x17, num11);
            if ((this.autoCorrDescriptor1 < 0x7fffffff) && (this.autoCorrDescriptor1 > -2147483648))
            {
                gr.FillRectangle(Brushes.Red, right, num11 - ((this.autoCorrDescriptor1 < 0) ? 0 : ((this.autoCorrDescriptor1 * rectangle.Height) / 100)), 5, (Math.Abs(this.autoCorrDescriptor1) * rectangle.Height) / 100);
                gr.FillRectangle(Brushes.Red, right + 6, num11 - ((this.autoCorrDescriptor2 < 0) ? 0 : ((this.autoCorrDescriptor2 * rectangle.Height) / 100)), 5, (Math.Abs(this.autoCorrDescriptor2) * rectangle.Height) / 100);
                gr.FillRectangle(Brushes.Red, right + 12, num11 - ((this.autoCorrDescriptor3 < 0) ? 0 : ((this.autoCorrDescriptor3 * rectangle.Height) / 100)), 5, (Math.Abs(this.autoCorrDescriptor3) * rectangle.Height) / 100);
                gr.FillRectangle(Brushes.Red, right + 0x12, num11 - ((this.autoCorrDescriptor4 < 0) ? 0 : ((this.autoCorrDescriptor4 * rectangle.Height) / 100)), 5, (Math.Abs(this.autoCorrDescriptor4) * rectangle.Height) / 100);
            }
        }
示例#10
0
 public Complex Dot(Contour c) =>
 this.Dot(c, 0);
示例#11
0
        /// <summary>
        /// Normalized Scalar Product
        /// </summary>
        public Complex NotmalizedScalarProduct(Contour otherContour)
        {
            var res = ScalarProduct(otherContour) * (1 / (Norma * otherContour.Norma));

            return(res);
        }
示例#12
0
 public Complex ScalarProduct(Contour c)
 {
     return(ScalarProduct(c, 0));
 }
        /**
         * отсеивает контуры по длинне контура и площади
         * */
        private List<Contour<Point>> FilterContours(Contour<Point> contours, 
            Image<Gray, byte> cannyFrame, int frameWidth, int frameHeight)
        {
            int maxArea = frameWidth * frameHeight / 5;
            var c = contours;
            List<Contour<Point>> result = new List<Contour<Point>>();
            while (c != null)
            {
                if (filterContoursBySize)
                    if (c.Total < minContourLength ||
                        c.Area < minContourArea || c.Area > maxArea ||
                        c.Area / c.Total <= minFormFactor)
                        goto next;

                if (noiseFilter)
                {
                    Point p1 = c[0];
                    Point p2 = c[(c.Total / 2) % c.Total];
                    if (cannyFrame[p1].Intensity <= double.Epsilon &&
                        cannyFrame[p2].Intensity <= double.Epsilon)
                        goto next;
                }
                result.Add(c);

            next:
                c = c.HNext;
            }

            return result;
        }
示例#14
0
        /// <summary>
        /// Discrete Fourier Transform
        /// </summary>
        public Contour Fourier()
        {
            int count = Count;
            Contour result = new Contour(count);
            for (int m = 0; m < count; m++)
            {
                Complex sum = new Complex(0, 0);
                double k = -2d*Math.PI*m/count;
                for (int n = 0; n < count; n++)
                    sum += this[n].Rotate(k * n);

                result.array[m]=sum;
            }

            return result;
        }
示例#15
0
 /// <summary>
 /// Scalar product
 /// </summary>
 public Complex Dot(Contour c)
 {
     return(Dot(c, 0));
 }
示例#16
0
        /// <summary>
        /// Intercorrelcation function (ICF)
        /// </summary>
        public Contour InterCorrelation(Contour c)
        {
            int count = Count;
            Contour result = new Contour(count);
            for (int i = 0; i < count; i++)
                result.array[i] = Dot(c, i);

            return result;
        }
示例#17
0
        /// <summary>
        /// Autocorrelation function (ACF)
        /// </summary>
        public unsafe Contour AutoCorrelation(bool normalize)
        {
            int count = Count/2;
            Contour result = new Contour(count);
            fixed (Complex* ptr = &result.array[0])
            {
                Complex* p = ptr;
                double maxNormaSq = 0;
                for (int i = 0; i < count; i++)
                {
                     *p = Dot(this, i);
                     double normaSq = (*p).NormaSquare;
                     if (normaSq > maxNormaSq)
                         maxNormaSq = normaSq;
                     p++;
                }
                if (normalize)
                {
                    maxNormaSq = Math.Sqrt(maxNormaSq);
                    p = ptr;
                    for (int i = 0; i < count; i++)
                    {
                        *p = new Complex((*p).a / maxNormaSq, (*p).b / maxNormaSq);
                        p++;
                    }
                }
            }

            return result;
        }
示例#18
0
        /// <summary>
        /// Normalized Scalar Product
        /// </summary>
        public Complex NormDot(Contour c)
        {
            var count = this.Count;
            double sumA = 0;
            double sumB = 0;
            double norm1 = 0;
            double norm2 = 0;
            for (int i = 0; i < count; i++)
            {
                var x1 = this[i];
                var x2 = c[i];
                sumA += x1.a * x2.a + x1.b * x2.b;
                sumB += x1.b * x2.a - x1.a * x2.b;
                norm1 += x1.NormaSquare;
                norm2 += x2.NormaSquare;
            }

            double k = 1d / Math.Sqrt(norm1*norm2);
            return new Complex(sumA * k, sumB * k);
        }
示例#19
0
 public Contour Clone()
 {
     Contour result = new Contour();
     result.array = (Complex[])array.Clone();
     return result;
 }
示例#20
0
 public void FindMaxContour(ImageProcessor processor)
 {
     int secondLongestContourIndex;
     processor.ProcessImage(new Image<Bgr, Byte>(new Bitmap(_digit)), true);
     _contour = processor.contours[SortContour(processor, out secondLongestContourIndex)];
 }
示例#21
0
        public void ProcessImage(Image <Gray, byte> grayFrame)
        {
            Action <Contour <Point> > body = null;

            if (this.equalizeHist)
            {
                grayFrame._EqualizeHist();
            }
            Image <Gray, byte> image  = grayFrame.PyrDown().PyrUp();
            Image <Gray, byte> image2 = null;

            if (this.noiseFilter)
            {
                image2 = image.Canny(new Gray((double)this.cannyThreshold), new Gray((double)this.cannyThreshold));
            }
            if (this.blur)
            {
                grayFrame = image;
            }
            CvInvoke.cvAdaptiveThreshold((IntPtr)grayFrame, (IntPtr)grayFrame, 255.0, ADAPTIVE_THRESHOLD_TYPE.CV_ADAPTIVE_THRESH_MEAN_C, THRESH.CV_THRESH_BINARY, (this.adaptiveThresholdBlockSize + (this.adaptiveThresholdBlockSize % 2)) + 1, 1.0);
            grayFrame._Not();
            if (this.addCanny && (image2 != null))
            {
                grayFrame._Or(image2);
            }
            this.binarizedFrame = grayFrame;
            if (image2 != null)
            {
                image2 = image2.Dilate(3);
            }
            Contour <Point> contours = grayFrame.FindContours(CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_NONE, RETR_TYPE.CV_RETR_LIST);

            this.contours = this.FilterContours(contours, image2, grayFrame.Width, grayFrame.Height);
            lock (this.foundTemplates)
            {
                this.foundTemplates.Clear();
            }
            this.samples.Clear();
            lock (this.templates)
            {
                if (body == null)
                {
                    body = delegate(Contour <Point> contour) {
                        Template item = new Template(contour.ToArray(), contour.Area, this.samples.templateSize);
                        lock (this.samples)
                        {
                            this.samples.Add(item);
                        }
                        if (!this.onlyFindContours)
                        {
                            FoundTemplateDesc desc = this.finder.FindTemplate(this.templates, item);
                            if (desc != null)
                            {
                                lock (this.foundTemplates)
                                {
                                    this.foundTemplates.Add(desc);
                                }
                            }
                        }
                    };
                }
                Parallel.ForEach <Contour <Point> >(this.contours, body);
            }
            FilterByIntersection(ref this.foundTemplates);
        }