예제 #1
0
        public static Mat Convolution(Mat source, Kernel kernel, BorderWrapType borderWrap = BorderWrapType.Copy)
        {
            var target = new Mat(source.Width, source.Height);

            Separable(source, target, kernel, borderWrap);
            return(target);
        }
예제 #2
0
        public static Mat GetSobelY(Mat source, BorderWrapType borderWrapType)
        {
            Mat dy = source.Clone();

            ConvolutionHelper.NonSeparable(source, dy, SobelKernelY, borderWrapType);
            return(dy);
        }
예제 #3
0
        public static Mat Sobel(Mat source, Mat dx, Mat dy, BorderWrapType borderWrapType)
        {
            ConvolutionHelper.Separable(source, dx, SobelKernelA, borderWrapType);
            ConvolutionHelper.Separable(source, dy, SobelKernelB, borderWrapType);

            var target = new Mat(source.Width, source.Height);

            for (var x = 0; x < source.Width; x++)
            {
                for (var y = 0; y < source.Height; y++)
                {
                    target.Set(x, y, MathHelper.SqrtOfSqrSum(dx.GetAt(x, y), dy.GetAt(x, y)));
                }
            }

            return(target);
        }
예제 #4
0
        public static void Separable(Mat source, Mat target, Kernel kernel, BorderWrapType borderWrap)
        {
            int kx = kernel.GetXVector().Width / 2,
                ky = kernel.GetYVector().Width / 2;

            var tmp = source.Clone();

            for (var x = 0; x < source.Width; x++)
            {
                for (var y = 0; y < source.Height; y++)
                {
                    double value = 0;

                    for (var dx = -kx; dx <= kx; dx++)
                    {
                        value += source.GetPixel(x - dx, y, borderWrap) * kernel.GetXVector().GetAt(dx + kx, 0);
                    }

                    tmp.Set(x, y, value);
                }
            }

            if (tmp == source)
            {
                tmp = null;
            }

            for (var x = 0; x < source.Width; x++)
            {
                for (var y = 0; y < source.Height; y++)
                {
                    double value = 0;

                    for (var dy = -ky; dy <= ky; dy++)
                    {
                        value += tmp.GetPixel(x, y - dy, borderWrap) * kernel.GetYVector().GetAt(dy + ky, 0);
                    }

                    target.Set(x, y, value);
                }
            }
        }
예제 #5
0
        private void button1_Click(object sender, EventArgs e)
        {
            BorderWrapType Edgemode = BorderWrapType.Mirror;

            if (RB_Zero.Checked == true)
            {
                Edgemode = BorderWrapType.Black;
            }
            if (RB_EdgeCoppy.Checked == true)
            {
                Edgemode = BorderWrapType.Copy;
            }
            if (RB_EdgeReflection.Checked == true)
            {
                Edgemode = BorderWrapType.Wrap;
            }
            if (RB_WrapImage.Checked == true)
            {
                Edgemode = BorderWrapType.Mirror;
            }

            Mat sobelMat  = new Mat(_image.Width, _image.Height);
            Mat sobelMatX = new Mat(_image.Width, _image.Height);
            Mat sobelMatY = new Mat(_image.Width, _image.Height);

            if (RB_Sobel.Checked == true)
            {
                sobelMat = SobelHelper.Sobel(_image, sobelMatX, sobelMatY, Edgemode);
            }

            Bitmap picture;

            picture           = Transformer.FromMatToBitmap(sobelMatX);
            pictureBox1.Image = picture;

            picture           = Transformer.FromMatToBitmap(sobelMatY);
            pictureBox2.Image = picture;

            picture           = Transformer.FromMatToBitmap(sobelMat);
            pictureBox3.Image = picture;
        }
예제 #6
0
        public double GetPixel(int x, int y, BorderWrapType borderHandling)
        {
            switch (borderHandling)
            {
            case BorderWrapType.Black:
                if (IsCoordinatesOutOfBounds(x, y))
                {
                    return(0);
                }
                break;

            case BorderWrapType.Copy:
                x = Math.Max(0, Math.Min(x, Width - 1));
                y = Math.Max(0, Math.Min(y, Height - 1));
                break;

            case BorderWrapType.Wrap:
                x = (x + Width) % Width;
                y = (y + Height) % Height;
                break;

            case BorderWrapType.Mirror:
                x = Math.Abs(x);
                y = Math.Abs(y);
                if (x < 0 || x >= Width)
                {
                    x = x - x % Width * 2 - 1;
                }
                if (y < 0 || y >= Height)
                {
                    y = y - y % Height * 2 - 1;                           // Где то здесь есть косяк
                }
                break;

            default:
                throw new ArgumentException("Illegal border wrap type " + borderHandling);
            }

            return(GetAt(x, y));
        }
예제 #7
0
        public static void NonSeparable(Mat source, Mat target, Mat kernel, BorderWrapType borderWrap)
        {
            int kx = kernel.Width / 2,
                ky = kernel.Height / 2;

            for (var x = 0; x < source.Width; x++)
            {
                for (var y = 0; y < source.Height; y++)
                {
                    double value = 0;

                    for (var dx = -kx; dx <= kx; dx++)
                    {
                        for (var dy = -ky; dy <= ky; dy++)
                        {
                            value += source.GetPixel(x - dx, y - dy, borderWrap) * kernel.GetAt(dx + kx, dy + ky);
                        }
                    }

                    target.Set(x, y, value);
                }
            }
        }
예제 #8
0
        /*
         * public static WrappedImage GetHarrisMatrix(int windowSize, int windowRadius, int width, int height)
         * {
         *  WrappedImage harrisMat = new WrappedImage(height, width);
         *
         *  Mat SobelX = SobelHelper.GetSobelX(_image, BorderHandling.Mirror);
         *  Mat SobelY = SobelHelper.GetSobelY(_image, BorderHandling.Mirror);
         *
         *  for (int y = 0; y < height; y++)
         *  {
         *      for (int x = 0; x < width; x++)
         *      {
         *          double[,] gauss = ConvolutionMatrix.CountGaussMatrix(windowSize);
         *
         *          // Считаем матрицу H
         *          double[,] currentMatrix = new double[2, 2];
         *          for (int u = -windowRadius; u <= windowRadius; u++)
         *          {
         *              for (int v = -windowRadius; v <= windowRadius; v++)
         *              {
         *                  double Ix = WrappedImage.getPixel(SobelX, y + u, x + v, BorderHandling.Mirror);
         *                  double Iy = WrappedImage.getPixel(SobelY, y + u, x + v, BorderHandling.Mirror);
         *
         *                  double gaussPoint = CommonMath.getPixel(gauss, u + windowRadius, v + windowRadius, 3);
         *
         *                  currentMatrix[0, 0] += Math.Pow(Ix, 2) * gaussPoint;
         *                  currentMatrix[0, 1] += Ix * Iy * gaussPoint;
         *                  currentMatrix[1, 0] += Ix * Iy * gaussPoint;
         *                  currentMatrix[1, 1] += Math.Pow(Iy, 2) * gaussPoint;
         *              }
         *          }
         *
         *          double[] eigenvalues = getEigenvalues(currentMatrix);
         *          harrisMat.buffer[y, x] = Math.Min(eigenvalues[0], eigenvalues[1]);
         *      }
         *  }
         *
         *  return harrisMat;
         * }
         *
         * static public double[] getEigenvalues(double[,] matrix) // Считаем собственные числа
         * {
         *  double[] eigenvalues = new double[2];
         *
         *  double a = 1;
         *  double b = -matrix[0, 0] - matrix[1, 1];
         *  double c = matrix[0, 0] * matrix[1, 1] - matrix[0, 1] * matrix[1, 0];
         *  double d = Math.Pow(b, 2) - 4 * a * c;
         *  if (Math.Abs(d) < 1e-4)
         *      d = 0;
         *  if (d < 0)
         *  {
         *      return eigenvalues;
         *  }
         *
         *  eigenvalues[0] = (-b + Math.Sqrt(d)) / (2 * a);
         *  eigenvalues[1] = (-b - Math.Sqrt(d)) / (2 * a);
         *
         *  return eigenvalues;
         * }
         */


        public static Mat Find(Mat image, int radius, double threshold, BorderWrapType borderWrap)
        {
            var gauss  = Gauss.GetFullKernel(radius / 3D);
            var gaussK = gauss.Width / 2;

            var dx = new Mat(image.Width, image.Height);
            var dy = new Mat(image.Width, image.Height);

            SobelHelper.Sobel(image, dx, dy, BorderWrapType.Mirror);

            var lambdas = new Mat(image.Width, image.Height);

            for (var x = 0; x < image.Width; x++)
            {
                for (var y = 0; y < image.Height; y++)
                {
                    double a = 0, b = 0, c = 0;

                    for (var u = -radius; u <= radius; u++)
                    {
                        for (var v = -radius; v <= radius; v++)
                        {
                            var multiplier = gauss.GetAt(u + gaussK, v + gaussK);

                            a += multiplier * MathHelper.Sqr(dx.GetPixel(x + u, y + v, borderWrap));
                            b += multiplier * dx.GetPixel(x + u, y + v, borderWrap) *
                                 dy.GetPixel(x + u, y + v, borderWrap);
                            c += multiplier * MathHelper.Sqr(dy.GetPixel(x + u, y + v, borderWrap));
                        }
                    }

                    lambdas.Set(x, y, LambdaMin(a, b, c));
                }
            }

            return(CornerDetectionHelper.FindPoints(lambdas, threshold));
        }
예제 #9
0
        private void button2_Click(object sender, EventArgs e)
        {
            BorderWrapType Edgemode = BorderWrapType.Mirror;

            if (RB_Zero.Checked == true)
            {
                Edgemode = BorderWrapType.Black;
            }
            if (RB_EdgeCoppy.Checked == true)
            {
                Edgemode = BorderWrapType.Copy;
            }
            if (RB_EdgeReflection.Checked == true)
            {
                Edgemode = BorderWrapType.Wrap;
            }
            if (RB_WrapImage.Checked == true)
            {
                Edgemode = BorderWrapType.Mirror;
            }


            double sigma0 = Convert.ToDouble(textBox2.Text);
            double sigma1 = Convert.ToDouble(textBox3.Text);
            int    levels = Convert.ToInt32(comboBox2.Text);


            picture           = Transformer.FromMatToBitmap(_image);
            pictureBox1.Image = picture;

            DeletePictures();

            picture.Save("..\\..\\..\\..\\Output\\" + "Исходное изображение.png");


            pyramid = Pyramid.Build(_image, levels, sigma0, sigma1);


            for (var octave = 0; octave < Pyramid.Depth; octave++)
            {
                for (var k = 0; k <= pyramid.OctaveSize; k++)
                {
                    var layer = pyramid.GetLayer(octave, k);

                    var path = "..\\..\\..\\..\\Output\\" + layer;
                    IOHelper.WriteMatToFile(layer.GetMat(), path);
                }
            }


            // Задаем новые значения для элементов управления выводом изображений
            comboBox3.Items.Clear();
            comboBox4.Items.Clear();
            comboBox3.Text = Convert.ToString(0);
            comboBox4.Text = Convert.ToString(0);
            for (int i = 0; i < Pyramid.Depth; i++)
            {
                comboBox3.Items.Add(i);
            }
            for (int i = 0; i < levels; i++)
            {
                comboBox4.Items.Add(i);
            }

            // Заполняем выходные данные
            lbl_CountOctavas.Text   = "Кол-во октав: " + Convert.ToString(Pyramid.Depth);
            lbl_LevelsInOctava.Text = "Уровней в октаве: " + Convert.ToString(levels);
        }