コード例 #1
0
        /// <summary>
        /// バイラテラルフィルタの算出
        /// </summary>
        /// <param name="sourceImage">画像の2次元配列</param>
        /// <param name="filterSize">フィルタのサイズ</param>
        /// <param name="x">注目画素の横方向の座標</param>
        /// <param name="y">注目画素の縦方向の座標</param>
        /// <param name="sigma1">ガウシアンフィルタを制御するパラメータ</param>
        /// <param name="sigma2">注目画素との画素値の差を制御するパラメータ</param>
        /// <returns>指定された座標に対するフィルタの2次元配列</returns>
        public static double[,] CalculateBilateralFilter(
            byte[,] sourceImage, int filterSize,
            int x, int y, double sigma1, double sigma2)
        {
            Debug.Assert(filterSize % 2 == 1);
            Debug.Assert(x >= 0 && x < sourceImage.GetLength(0));
            Debug.Assert(y >= 0 && y < sourceImage.GetLength(1));

            double[,] filter = new double[filterSize, filterSize];

            for (int m = -filterSize / 2; m <= filterSize / 2; ++m)
            {
                for (int n = -filterSize / 2; n <= filterSize / 2; ++n)
                {
                    filter[m + filterSize / 2, n + filterSize / 2] =
                        Math.Exp(-(Math.Pow(m, 2.0) + Math.Pow(n, 2.0))
                                 / (2.0 * Math.Pow(sigma1, 2.0))) *
                        Math.Exp(-Math.Pow(Utility.GetPixel(sourceImage, x, y) -
                                           Utility.GetPixel(sourceImage, x + m, y + n), 2.0)
                                 / (2.0 * Math.Pow(sigma2, 2.0)));
                }
            }

            ImageFiltering.NormalizeFilter(filter);

            return(filter);
        }
コード例 #2
0
        /// <summary>
        /// 画像にバイラテラルフィルタを適用
        /// </summary>
        /// <param name="sourceImage">画像の2次元配列</param>
        /// <param name="filterSize">フィルタのサイズ</param>
        /// <param name="sigma1">ガウシアンフィルタを制御するパラメータ</param>
        /// <param name="sigma2">注目画素との画素値の差を制御するパラメータ</param>
        /// <returns>フィルタを適用した画像の2次元配列</returns>
        public static byte[,] ApplyBilateralFilter(
            byte[,] sourceImage, int filterSize, double sigma1, double sigma2)
        {
            Debug.Assert(filterSize % 2 == 1);

            int imageWidth  = sourceImage.GetLength(0);
            int imageHeight = sourceImage.GetLength(1);

            byte[,] destImage = new byte[imageWidth, imageHeight];
            double[,] filter;
            double pixelValue;

            for (int x = 0; x < imageWidth; ++x)
            {
                for (int y = 0; y < imageHeight; ++y)
                {
                    filter = ImageFiltering.CalculateBilateralFilter(
                        sourceImage, filterSize, x, y, sigma1, sigma2);
                    pixelValue = 0.0;

                    for (int m = -filterSize / 2; m <= filterSize / 2; ++m)
                    {
                        for (int n = -filterSize / 2; n <= filterSize / 2; ++n)
                        {
                            pixelValue += Utility.GetPixel(sourceImage, x + m, y + n) *
                                          filter[m + filterSize / 2, n + filterSize / 2];
                        }
                    }

                    destImage[x, y] = (byte)Utility.Clamp(pixelValue, byte.MinValue, byte.MaxValue);
                }
            }

            return(destImage);
        }
コード例 #3
0
        /// <summary>
        /// LoGフィルタを用いたゼロ交差法によりエッジを検出
        /// </summary>
        /// <param name="sourceImage">画像の2次元配列</param>
        /// <param name="filterSize">フィルタのサイズ</param>
        /// <param name="standardDeviation">ガウス分布の標準偏差</param>
        /// <returns>検出されたエッジを示す白黒画像</returns>
        public static byte[,] DetectEdges(byte[,] sourceImage, int filterSize, double standardDeviation)
        {
            double[,] zeroCrossingImage = ImageFiltering.ApplyLoGFilter(
                sourceImage, filterSize, standardDeviation);
            int imageWidth  = zeroCrossingImage.GetLength(0);
            int imageHeight = zeroCrossingImage.GetLength(1);

            byte[,] destImage = new byte[imageWidth, imageHeight];

            for (int x = 0; x < imageWidth - 1; ++x)
            {
                for (int y = 0; y < imageHeight - 1; ++y)
                {
                    if (zeroCrossingImage[x, y] * zeroCrossingImage[x + 1, y] < 0.0 ||
                        zeroCrossingImage[x, y] * zeroCrossingImage[x, y + 1] < 0.0)
                    {
                        destImage[x, y] = 255;
                    }
                    else
                    {
                        destImage[x, y] = 0;
                    }
                }
            }

            return(destImage);
        }
コード例 #4
0
        /// <summary>
        /// 画像にソーベルフィルタを適用
        /// </summary>
        /// <param name="sourceImage">画像の2次元配列</param>
        /// <param name="multiplyConstant">画像が見やすくなるように適当な定数倍を掛けるかどうか</param>
        /// <returns>エッジ強度画像の2次元配列</returns>
        public static byte[,] ApplySobelFilter(byte[,] sourceImage, bool multiplyConstant)
        {
            byte[,] destImage = ImageFiltering.CreateGradientImage(
                ImageFiltering.ApplyHorizontalSobelFilter(sourceImage),
                ImageFiltering.ApplyVerticalSobelFilter(sourceImage));

            if (!multiplyConstant)
            {
                return(destImage);
            }

            byte maxPixelValue = destImage.Cast <byte>().Max();
            int  imageWidth    = destImage.GetLength(0);
            int  imageHeight   = destImage.GetLength(1);

            // 見やすくなるように適当な定数倍を掛ける
            for (int x = 0; x < imageWidth; ++x)
            {
                for (int y = 0; y < imageHeight; ++y)
                {
                    destImage[x, y] = (byte)(destImage[x, y] * 255.0 / maxPixelValue);
                }
            }

            return(destImage);
        }
コード例 #5
0
        /// <summary>
        /// 画像に縦方向のソーベルフィルタを適用
        /// </summary>
        /// <param name="sourceImage">画像の2次元配列</param>
        /// <returns>フィルタ適用後の画像の2次元配列</returns>
        public static double[,] ApplyVerticalSobelFilter(byte[,] sourceImage)
        {
            double[,] filter = new double[3, 3] {
                { 1.0 / 8.0, 2.0 / 8.0, 1.0 / 8.0 },
                { 0.0, 0.0, 0.0 },
                { -1.0 / 8.0, -2.0 / 8.0, -1.0 / 8.0 }
            };

            return(ImageFiltering.ApplyFilterAllowNegativeValues(sourceImage, filter));
        }
コード例 #6
0
        /// <summary>
        /// 画像に横方向のプリューウィットフィルタを適用
        /// </summary>
        /// <param name="sourceImage">画像の2次元配列</param>
        /// <returns>フィルタ適用後の画像の2次元配列</returns>
        public static double[,] ApplyHorizontalPrewittFilter(byte[,] sourceImage)
        {
            double[,] filter = new double[3, 3] {
                { -1.0 / 6.0, 0.0, 1.0 / 6.0 },
                { -1.0 / 6.0, 0.0, 1.0 / 6.0 },
                { -1.0 / 6.0, 0.0, 1.0 / 6.0 }
            };

            return(ImageFiltering.ApplyFilterAllowNegativeValues(sourceImage, filter));
        }
コード例 #7
0
        /// <summary>
        /// 画像に縦方向の微分フィルタを適用
        /// </summary>
        /// <param name="sourceImage">画像の2次元配列</param>
        /// <returns>フィルタ適用後の画像の2次元配列</returns>
        public static double[,] ApplyVerticalDerivativeFilter(byte[,] sourceImage)
        {
            double[,] filter = new double[3, 3] {
                { 0.0, 0.5, 0.0 },
                { 0.0, 0.0, 0.0 },
                { 0.0, -0.5, 0.0 }
            };

            return(ImageFiltering.ApplyFilterAllowNegativeValues(sourceImage, filter));
        }
コード例 #8
0
        /// <summary>
        /// 画像に平均化フィルタを適用
        /// </summary>
        /// <param name="sourceImage">画像の2次元配列</param>
        /// <param name="filterSize">フィルタのサイズ</param>
        /// <returns>フィルタ適用後の画像の2次元配列</returns>
        public static byte[,] ApplyAveragingFilter(byte[,] sourceImage, int filterSize)
        {
            Debug.Assert(filterSize % 2 == 1);

            double[,] filter = new double[filterSize, filterSize];

            for (int m = 0; m < filterSize; ++m)
            {
                for (int n = 0; n < filterSize; ++n)
                {
                    filter[m, n] = 1.0 / (filterSize * filterSize);
                }
            }

            return(ImageFiltering.ApplyFilter(sourceImage, filter));
        }
コード例 #9
0
        /// <summary>
        /// 画像にLoG(Laplacian of Gaussian)フィルタを適用
        /// </summary>
        /// <param name="sourceImage">画像の2次元配列</param>
        /// <param name="filterSize">フィルタのサイズ</param>
        /// <param name="standardDeviation">ガウス分布の標準偏差</param>
        /// <returns>フィルタ適用後の画像の2次元配列</returns>
        public static double[,] ApplyLoGFilter(byte[,] sourceImage, int filterSize, double standardDeviation)
        {
            Debug.Assert(filterSize % 2 == 1);

            double[,] filter = new double[filterSize, filterSize];

            for (int m = 0; m < filterSize; ++m)
            {
                for (int n = 0; n < filterSize; ++n)
                {
                    double r = Math.Pow(m - (filterSize / 2), 2.0) + Math.Pow(n - (filterSize / 2), 2.0);
                    filter[m, n] = Math.Exp(-r / (2.0 * Math.Pow(standardDeviation, 2.0))) *
                                   (r - 2.0 * Math.Pow(standardDeviation, 2.0)) /
                                   (2.0 * Math.PI * Math.Pow(standardDeviation, 6.0));
                }
            }

            return(ImageFiltering.ApplyFilterAllowNegativeValues(sourceImage, filter));
        }
コード例 #10
0
        /// <summary>
        /// 画像にガウシアンフィルタを適用
        /// </summary>
        /// <param name="sourceImage">画像の2次元配列</param>
        /// <param name="filterSize">フィルタのサイズ</param>
        /// <param name="standardDeviation">ガウス分布の標準偏差</param>
        /// <returns>フィルタ適用後の画像の2次元配列</returns>
        public static byte[,] ApplyGaussianFilter(byte[,] sourceImage, int filterSize, double standardDeviation)
        {
            Debug.Assert(filterSize % 2 == 1);

            double[,] filter = new double[filterSize, filterSize];

            // ガウシアンフィルタを作成
            for (int m = 0; m < filterSize; ++m)
            {
                for (int n = 0; n < filterSize; ++n)
                {
                    double r = Math.Pow(m - (filterSize / 2), 2.0) + Math.Pow(n - (filterSize / 2), 2.0);
                    filter[m, n] = Math.Exp(-r / (2.0 * Math.Pow(standardDeviation, 2.0)));
                }
            }

            // フィルタの各要素の合計値が1となるように正規化
            ImageFiltering.NormalizeFilter(filter);

            return(ImageFiltering.ApplyFilter(sourceImage, filter));
        }
コード例 #11
0
        /// <summary>
        /// 画像に鮮鋭化フィルタを適用
        /// </summary>
        /// <param name="sourceImage">画像の2次元配列</param>
        /// <param name="filterSize">フィルタのサイズ</param>
        /// <param name="k">鮮鋭化フィルタのパラメータ</param>
        /// <returns>フィルタを適用した画像の2次元配列</returns>
        public static byte[,] ApplySharpeningFilter(byte[,] sourceImage, int filterSize, double k)
        {
            Debug.Assert(filterSize % 2 == 1);

            double[,] filter = new double[filterSize, filterSize];

            for (int m = 0; m < filterSize; ++m)
            {
                for (int n = 0; n < filterSize; ++n)
                {
                    if (m == filterSize / 2 && n == filterSize / 2)
                    {
                        filter[m, n] = 1.0 + k * ((filterSize * filterSize) - 1) /
                                       (filterSize * filterSize);
                    }
                    else
                    {
                        filter[m, n] = -k / (filterSize * filterSize);
                    }
                }
            }

            return(ImageFiltering.ApplyFilter(sourceImage, filter));
        }