当前位置: 代码网 > it编程>编程语言>Asp.net > C#实现高斯模糊(图像处理)

C#实现高斯模糊(图像处理)

2024年08月05日 Asp.net 我要评论
在C#中实现高斯模糊,可以使用System.Drawing库。高斯模糊是一种基于高斯函数的滤波器,它可以有效地平滑图像。
1. 生成高斯核

首先,我们需要编写一个方法来生成高斯核。

public static float[,] creategaussiankernel(int length, float weight)
{
    float[,] kernel = new float[length, length];
    float sumtotal = 0;
    int kernelradius = length / 2;
    float distance = 0;
    float calculatedeuler = 1.0f / (2.0f * (float)math.pi * weight * weight);

    for (int filtery = -kernelradius; filtery <= kernelradius; filtery++)
    {
        for (int filterx = -kernelradius; filterx <= kernelradius; filterx++)
        {
            distance = ((filterx * filterx) + (filtery * filtery)) / (2 * (weight * weight));
            kernel[filtery + kernelradius, filterx + kernelradius] = calculatedeuler * (float)math.exp(-distance);
            sumtotal += kernel[filtery + kernelradius, filterx + kernelradius];
        }
    }

    for (int y = 0; y < length; y++)
    {
        for (int x = 0; x < length; x++)
        {
            kernel[y, x] = kernel[y, x] * (1.0f / sumtotal);
        }
    }

    return kernel;
}
2. 应用卷积滤波器

编写一个方法来应用卷积滤波器,将高斯核应用到图像上。

public static bitmap applyconvolutionfilter(bitmap sourceimage, float[,] kernel)
{
    int width = sourceimage.width;
    int height = sourceimage.height;
    bitmapdata srcdata = sourceimage.lockbits(new rectangle(0, 0, width, height), imagelockmode.readonly, pixelformat.format32bppargb);
    bitmap resultimage = new bitmap(width, height);
    bitmapdata resultdata = resultimage.lockbits(new rectangle(0, 0, width, height), imagelockmode.writeonly, pixelformat.format32bppargb);

    int bytesperpixel = 4;
    int stride = srcdata.stride;
    intptr srcscan0 = srcdata.scan0;
    intptr resultscan0 = resultdata.scan0;
    int kernelwidth = kernel.getlength(1);
    int kernelheight = kernel.getlength(0);
    int kerneloffset = kernelwidth / 2;

    unsafe
    {
        byte* srcptr = (byte*)srcscan0.topointer();
        byte* resultptr = (byte*)resultscan0.topointer();

        for (int y = kerneloffset; y < height - kerneloffset; y++)
        {
            for (int x = kerneloffset; x < width - kerneloffset; x++)
            {
                float blue = 0.0f;
                float green = 0.0f;
                float red = 0.0f;

                for (int ky = -kerneloffset; ky <= kerneloffset; ky++)
                {
                    for (int kx = -kerneloffset; kx <= kerneloffset; kx++)
                    {
                        int pixelpos = ((y + ky) * stride) + ((x + kx) * bytesperpixel);
                        blue += srcptr[pixelpos] * kernel[ky + kerneloffset, kx + kerneloffset];
                        green += srcptr[pixelpos + 1] * kernel[ky + kerneloffset, kx + kerneloffset];
                        red += srcptr[pixelpos + 2] * kernel[ky + kerneloffset, kx + kerneloffset];
                    }
                }

                int resultpos = (y * stride) + (x * bytesperpixel);
                resultptr[resultpos] = (byte)math.min(math.max(blue, 0), 255);
                resultptr[resultpos + 1] = (byte)math.min(math.max(green, 0), 255);
                resultptr[resultpos + 2] = (byte)math.min(math.max(red, 0), 255);
                resultptr[resultpos + 3] = 255; // alpha channel
            }
        }
    }

    sourceimage.unlockbits(srcdata);
    resultimage.unlockbits(resultdata);

    return resultimage;
}
3. 使用高斯模糊处理图像

最后,编写一个程序来加载图像、应用高斯模糊滤波器,并保存处理后的图像。

using system;using system.drawing;using system.drawing.imaging;
class program
{
    static void main()
    {
        // 加载原始图像
        bitmap sourceimage = new bitmap("path_to_your_image.jpg");

        // 创建高斯核
        float weight = 1.0f;
        int kernelsize = 5; // 核大小可以根据需要调整
        float[,] kernel = creategaussiankernel(kernelsize, weight);

        // 应用高斯模糊滤波器
        bitmap resultimage = applyconvolutionfilter(sourceimage, kernel);

        // 保存处理后的图像
        resultimage.save("path_to_save_filtered_image.jpg");
    }

    public static float[,] creategaussiankernel(int length, float weight)
    {
        float[,] kernel = new float[length, length];
        float sumtotal = 0;
        int kernelradius = length / 2;
        float distance = 0;
        float calculatedeuler = 1.0f / (2.0f * (float)math.pi * weight * weight);

        for (int filtery = -kernelradius; filtery <= kernelradius; filtery++)
        {
            for (int filterx = -kernelradius; filterx <= kernelradius; filterx++)
            {
                distance = ((filterx * filterx) + (filtery * filtery)) / (2 * (weight * weight));
                kernel[filtery + kernelradius, filterx + kernelradius] = calculatedeuler * (float)math.exp(-distance);
                sumtotal += kernel[filtery + kernelradius, filterx + kernelradius];
            }
        }

        for (int y = 0; y < length; y++)
        {
            for (int x = 0; x < length; x++)
            {
                kernel[y, x] = kernel[y, x] * (1.0f / sumtotal);
            }
        }

        return kernel;
    }

    public static bitmap applyconvolutionfilter(bitmap sourceimage, float[,] kernel)
    {
        int width = sourceimage.width;
        int height = sourceimage.height;
        bitmapdata srcdata = sourceimage.lockbits(new rectangle(0, 0, width, height), imagelockmode.readonly, pixelformat.format32bppargb);
        bitmap resultimage = new bitmap(width, height);
        bitmapdata resultdata = resultimage.lockbits(new rectangle(0, 0, width, height), imagelockmode.writeonly, pixelformat.format32bppargb);

        int bytesperpixel = 4;
        int stride = srcdata.stride;
        intptr srcscan0 = srcdata.scan0;
        intptr resultscan0 = resultdata.scan0;
        int kernelwidth = kernel.getlength(1);
        int kernelheight = kernel.getlength(0);
        int kerneloffset = kernelwidth / 2;

        unsafe
        {
            byte* srcptr = (byte*)srcscan0.topointer();
            byte* resultptr = (byte*)resultscan0.topointer();

            for (int y = kerneloffset; y < height - kerneloffset; y++)
            {
                for (int x = kerneloffset; x < width - kerneloffset; x++)
                {
                    float blue = 0.0f;
                    float green = 0.0f;
                    float red = 0.0f;

                    for (int ky = -kerneloffset; ky <= kerneloffset; ky++)
                    {
                        for (int kx = -kerneloffset; kx <= kerneloffset; kx++)
                        {
                            int pixelpos = ((y + ky) * stride) + ((x + kx) * bytesperpixel);
                            blue += srcptr[pixelpos] * kernel[ky + kerneloffset, kx + kerneloffset];
                            green += srcptr[pixelpos + 1] * kernel[ky + kerneloffset, kx + kerneloffset];
                            red += srcptr[pixelpos + 2] * kernel[ky + kerneloffset, kx + kerneloffset];
                        }
                    }

                    int resultpos = (y * stride) + (x * bytesperpixel);
                    resultptr[resultpos] = (byte)math.min(math.max(blue, 0), 255);
                    resultptr[resultpos + 1] = (byte)math.min(math.max(green, 0), 255);
                    resultptr[resultpos + 2] = (byte)math.min(math.max(red, 0), 255);
                    resultptr[resultpos + 3] = 255; // alpha channel
                }
            }
        }

        sourceimage.unlockbits(srcdata);
        resultimage.unlockbits(resultdata);

        return resultimage;
    }
}
图像对比
  • 原图:
    在这里插入图片描述
  • 处理后:
    在这里插入图片描述
注意事项
  • 确保路径 path_to_your_image.jpg 和 path_to_save_filtered_image.jpg 是正确的。
  • 调整高斯核的大小和权重以获得所需的模糊效果。
  • system.drawing。
(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com