public Bitmap[,] GetDoGs(Bitmap[,] gaussainPyramid)
 {
     Bitmap[,] dogs = new Bitmap[gaussainPyramid.GetLength(0), gaussainPyramid.GetLength(1) - 1];
     for (int i = 0; i < dogs.GetLength(0); i++)
     {
         for (int j = 0; j < dogs.GetLength(1); j++)
         {
             dogs[i, j] = UnityTools.Diff(gaussainPyramid[i, j], gaussainPyramid[i, j + 1]);
         }
     }
     return(dogs);
 }
        public Bitmap[,] GetGaussianPyramid(Bitmap originBit, int octaves, int layers)
        {
            Bitmap[,] gaussianPyramid = new Bitmap[octaves, layers];
            for (int i = 0; i < octaves; i++)
            {
                float sigmaInit = 1.0f;
                for (int j = 0; j < layers; j++)
                {
                    originBit             = Conv(originBit, (j + 1) * Sigma / sigmaInit);
                    gaussianPyramid[i, j] = new Bitmap(Bitmap.FromHbitmap(originBit.GetHbitmap()));
                    sigmaInit             = (j + 1) * Sigma / sigmaInit;
                }
                originBit = new Bitmap(Bitmap.FromHbitmap(gaussianPyramid[i, layers - 2].GetHbitmap()));
                originBit = UnityTools.ImageScale(originBit, 0.5f);
            }

            return(gaussianPyramid);
        }
        public Bitmap Conv(Bitmap originBitmap)
        {
            int range = (int)(3 * Sigma + 1);

            int[,] gaussianMap = new int[2 * range + 1, 2 * range + 1];

            for (int i = 0; i < 2 * range + 1; i++)
            {
                for (int j = 0; j < 2 * range + 1; j++)
                {
                    gaussianMap[i, j] = (int)(GaussianSolve(i, j, range, range) * 100000);
                }
            }
            int[,,] rgbMapInput  = new int[originBitmap.Width, originBitmap.Height, 3];
            int[,,] rgbMapOutput = new int[originBitmap.Width, originBitmap.Height, 3];

            int maxIn = 0;

            for (int i = 0; i < originBitmap.Height; i++)
            {
                for (int j = 0; j < originBitmap.Width; j++)
                {
                    if (ColorFormat == ColorFormat.RGB)
                    {
                        rgbMapInput[j, i, 0] = originBitmap.GetPixel(j, i).R;
                        rgbMapInput[j, i, 1] = originBitmap.GetPixel(j, i).G;
                        rgbMapInput[j, i, 2] = originBitmap.GetPixel(j, i).B;
                        maxIn = Math.Max(rgbMapInput[j, i, 0], maxIn);
                        maxIn = Math.Max(rgbMapInput[j, i, 1], maxIn);
                        maxIn = Math.Max(rgbMapInput[j, i, 2], maxIn);
                    }
                    if (ColorFormat == ColorFormat.GrayScale)
                    {
                        rgbMapInput[j, i, 0] = originBitmap.GetPixel(j, i).R;
                        maxIn = Math.Max(rgbMapInput[j, i, 0], maxIn);
                    }
                }
            }

            Bitmap convedBitmap = new Bitmap(originBitmap.Width, originBitmap.Height);
            int    maxOut       = 0;

            for (int i = 0; i < originBitmap.Height; i++)
            {
                for (int j = 0; j < originBitmap.Width; j++)
                {
                    for (int ii = 0; ii < 2 * range + 1; ii++)
                    {
                        for (int jj = 0; jj < 2 * range + 1; jj++)
                        {
                            int x = j + jj - range, y = i + ii - range;
                            if (x < 0)
                            {
                                x = -x;
                            }

                            if (y < 0)
                            {
                                y = -y;
                            }

                            if (x >= originBitmap.Width)
                            {
                                x = 2 * originBitmap.Width - x - 1;
                            }
                            if (y >= originBitmap.Height)
                            {
                                y = 2 * originBitmap.Height - y - 1;
                            }

                            if (ColorFormat == ColorFormat.RGB)
                            {
                                rgbMapOutput[j, i, 0] += gaussianMap[jj, ii] * rgbMapInput[x, y, 0];
                                rgbMapOutput[j, i, 1] += gaussianMap[jj, ii] * rgbMapInput[x, y, 1];
                                rgbMapOutput[j, i, 2] += gaussianMap[jj, ii] * rgbMapInput[x, y, 2];
                            }

                            if (ColorFormat == ColorFormat.GrayScale)
                            {
                                rgbMapOutput[j, i, 0] += gaussianMap[jj, ii] * rgbMapInput[x, y, 0];
                            }
                        }
                    }

                    if (ColorFormat == ColorFormat.RGB)
                    {
                        maxOut = Math.Max(rgbMapOutput[j, i, 0], maxOut);
                        maxOut = Math.Max(rgbMapOutput[j, i, 1], maxOut);
                        maxOut = Math.Max(rgbMapOutput[j, i, 2], maxOut);
                    }

                    if (ColorFormat == ColorFormat.GrayScale)
                    {
                        maxOut = Math.Max(rgbMapOutput[j, i, 0], maxOut);
                    }
                }
            }

            int[,,] rgbMapOutputs = UnityTools.TupleScale(rgbMapOutput, maxOut, maxIn);

            for (int i = 0; i < originBitmap.Height; i++)
            {
                for (int j = 0; j < originBitmap.Width; j++)
                {
                    Color color;
                    if (ColorFormat == ColorFormat.RGB)
                    {
                        color = Color.FromArgb(Convert.ToInt16(originBitmap.GetPixel(j, i).A), rgbMapOutputs[j, i, 0], rgbMapOutputs[j, i, 1], rgbMapOutputs[j, i, 2]);
                        convedBitmap.SetPixel(j, i, color);
                    }

                    if (ColorFormat == ColorFormat.GrayScale)
                    {
                        color = Color.FromArgb(Convert.ToInt16(originBitmap.GetPixel(j, i).A), rgbMapOutputs[j, i, 0], rgbMapOutputs[j, i, 0], rgbMapOutputs[j, i, 0]);
                        convedBitmap.SetPixel(j, i, color);
                    }
                }
            }
            return(convedBitmap);
        }