c#中实现图像图像卷积与滤波-高斯平滑

36 篇文章 29 订阅
18 篇文章 2 订阅

使用C#语言编写高斯平滑。

一、线性滤波与卷积的基本概念
2D卷积需要4个嵌套循环4-double loop,所以它并不快,除非我们使用很小的卷积核。这里一般使用3×3或者5×5。而且,对于滤波器,也有一定的规则要求:

1)滤波器的大小应该是奇数,这样它才有一个中心,例如3×3,5×5或者7×7。有中心了,也有了半径的称呼,例如5×5大小的核的半径就是2。

2)滤波器矩阵所有的元素之和应该要等于1,这是为了保证滤波前后图像的亮度保持不变。当然了,这不是硬性要求了。

3)如果滤波器矩阵所有元素之和大于1,那么滤波后的图像就会比原图像更亮,反之,如果小于1,那么得到的图像就会变暗。如果和为0,图像不会变黑,但也会非常暗。

4)对于滤波后的结构,可能会出现负数或者大于255的数值。对这种情况,我们将他们直接截断到0和255之间即可。对于负数,也可以取绝对值。

二、卷积核
        private double[,] GaussianBlur;//声明私有的高斯模糊卷积核函数
 
        /// <summary>
        /// 构造卷积(Convolution)类函数
        /// </summary>
        public Convolution()
        {
            //初始化高斯模糊卷积核
            int k=273;
            GaussianBlur = new double[5, 5]{{(double)1/k,(double)4/k,(double)7/k,(double)4/k,(double)1/k},
                                            {(double)4/k,(double)16/k,(double)26/k,(double)16/k,(double)4/k},
                                            {(double)7/k,(double)26/k,(double)41/k,(double)26/k,(double)7/k},
                                            {(double)4/k,(double)16/k,(double)26/k,(double)16/k,(double)4/k},
                                            {(double)1/k,(double)4/k,(double)7/k,(double)4/k,(double)1/k}};
        }
三、对图像进行卷积平滑
/// <summary>
        /// 对图像进行平滑处理(利用高斯平滑Gaussian Blur)
        /// </summary>
        /// <param name="bitmap">要处理的位图</param>
        /// <returns>返回平滑处理后的位图</returns>
        public Bitmap Smooth(Bitmap bitmap) 
        {
            int[, ,] InputPicture = new int[3, bitmap.Width, bitmap.Height];//以GRB以及位图的长宽建立整数输入的位图的数组
 
            Color color = new Color();//储存某一像素的颜色
            //循环使得InputPicture数组得到位图的RGB
            for (int i = 0; i < bitmap.Width; i++)
            {
                for (int j = 0; j < bitmap.Height; j++)
                {
                    color = bitmap.GetPixel(i, j);
                    InputPicture[0, i, j] = color.R;
                    InputPicture[1, i, j] = color.G;
                    InputPicture[2, i, j] = color.B;
                }
            }
 
            int[, ,] OutputPicture = new int[3, bitmap.Width, bitmap.Height];//以GRB以及位图的长宽建立整数输出的位图的数组
            Bitmap smooth = new Bitmap(bitmap.Width, bitmap.Height);//创建新位图
            //循环计算使得OutputPicture数组得到计算后位图的RGB
            for (int i = 0; i < bitmap.Width; i++)
            {
                for (int j = 0; j < bitmap.Height; j++)
                {
                    int R=0;
                    int G=0;
                    int B=0;
 
                    //每一个像素计算使用高斯模糊卷积核进行计算
                    for (int r = 0; r < 5; r++)//循环卷积核的每一行
                    {
                        for (int f = 0; f < 5; f++)//循环卷积核的每一列
                        {
                            //控制与卷积核相乘的元素
                            int row = i - 2 + r;
                            int index = j - 2 + f;
                            
                            //当超出位图的大小范围时,选择最边缘的像素值作为该点的像素值
                            row = row < 0 ? 0 : row;
                            index = index < 0 ? 0 : index;
                            row = row >= bitmap.Width ? bitmap.Width - 1 : row;
                            index = index >= bitmap.Height ? bitmap.Height - 1 : index;
 
                            //输出得到像素的RGB值
                            R += (int)(GaussianBlur[r, f] * InputPicture[0, row, index]);
                            G += (int)(GaussianBlur[r, f] * InputPicture[1, row, index]);
                            B += (int)(GaussianBlur[r, f] * InputPicture[2, row, index]);
                        }
                    }
                    color = Color.FromArgb(R,G,B);//颜色结构储存该点RGB
                    smooth.SetPixel(i, j, color);//位图存储该点像素值
                }
            }
            return smooth;
        }
 

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是Java代码实现图像平滑降噪的三种滤波方法: 1. 滤波: ```java import java.awt.Color; import java.awt.image.BufferedImage; public class MedianFilter { public static BufferedImage filter(BufferedImage image, int filterSize) { int width = image.getWidth(); int height = image.getHeight(); BufferedImage result = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { int[] pixels = new int[filterSize * filterSize]; int index = 0; for (int i = x - filterSize / 2; i <= x + filterSize / 2; i++) { for (int j = y - filterSize / 2; j <= y + filterSize / 2; j++) { if (i >= 0 && i < width && j >= 0 && j < height) { Color color = new Color(image.getRGB(i, j)); pixels[index++] = color.getRed(); } } } java.util.Arrays.sort(pixels); int median = pixels[filterSize * filterSize / 2]; result.setRGB(x, y, new Color(median, median, median).getRGB()); } } return result; } } ``` 2. 均值滤波: ```java import java.awt.Color; import java.awt.image.BufferedImage; public class MeanFilter { public static BufferedImage filter(BufferedImage image, int filterSize) { int width = image.getWidth(); int height = image.getHeight(); BufferedImage result = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { int sum = 0; int count = 0; for (int i = x - filterSize / 2; i <= x + filterSize / 2; i++) { for (int j = y - filterSize / 2; j <= y + filterSize / 2; j++) { if (i >= 0 && i < width && j >= 0 && j < height) { Color color = new Color(image.getRGB(i, j)); sum += color.getRed(); count++; } } } int mean = sum / count; result.setRGB(x, y, new Color(mean, mean, mean).getRGB()); } } return result; } } ``` 3. 高斯滤波: ```java import java.awt.Color; import java.awt.image.BufferedImage; public class GaussianFilter { public static BufferedImage filter(BufferedImage image, int filterSize, double sigma) { int width = image.getWidth(); int height = image.getHeight(); BufferedImage result = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); double[] kernel = new double[filterSize * filterSize]; double kernelSum = 0; for (int i = 0; i < filterSize; i++) { for (int j = 0; j < filterSize; j++) { int x = i - filterSize / 2; int y = j - filterSize / 2; kernel[i * filterSize + j] = Math.exp(-(x * x + y * y) / (2 * sigma * sigma)); kernelSum += kernel[i * filterSize + j]; } } for (int i = 0; i < kernel.length; i++) { kernel[i] /= kernelSum; } for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { double sum = 0; for (int i = x - filterSize / 2; i <= x + filterSize / 2; i++) { for (int j = y - filterSize / 2; j <= y + filterSize / 2; j++) { if (i >= 0 && i < width && j >= 0 && j < height) { Color color = new Color(image.getRGB(i, j)); double weight = kernel[(i - x + filterSize / 2) * filterSize + j - y + filterSize / 2]; sum += weight * color.getRed(); } } } int value = (int) Math.round(sum); if (value < 0) { value = 0; } if (value > 255) { value = 255; } result.setRGB(x, y, new Color(value, value, value).getRGB()); } } return result; } } ``` 以上代码,`image` 是输入的 BufferedImage 对象,`filterSize` 是滤波器的大小,`sigma` 是高斯滤波的标准差。对于滤波和均值滤波,`result` 是经过滤波处理后的 BufferedImage 对象;对于高斯滤波,`kernel` 是高斯卷积核,`kernelSum` 是卷积核的和,`sum` 是卷积结果的和,`value` 是最终的像素值。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值