C#实现直方图均衡化的简单遥感图像处理Demo

前言:
这篇文章是一篇关于用c#实现直方图均衡化的简单demo。
这个是遥感老师布置的c#作业,由于最近一直在进行一个UWP的项目,大部分c#前台界面都是用xaml写的。但这个demo是一个窗体程序所以界面爆炸丑,望大家见谅。(虽然其他界面也写的丑  ( o=^•ェ•)o ┏━┓)
不多说。。。。。
先附上项目的Git地址:点击打开链接
开整:
首先简单的说一下直方图均衡化的步骤:

       1 求原图的总像数个数 ;

int size = width * height;

       2 计算各个灰度值对应的像元个数;

                for (int i = 0; i < width; ++i)
                    for (int j = 0; j < height; ++j)
                    {
                        Color pixel = newbitmap.GetPixel(i, j);
                        //计算各像元值的个数
                        gray[Convert.ToInt16(pixel.R)] += 1;
                        //由于是灰度只读取R值
                    }
        3 计算各像元值占比;
                for (int i = 0; i < 256; i++)
                {
                    graydense[i] = (gray[i] * 1.0) / size;
                    //每个灰度像素个数占比
                }
         4 计算累计频率占比;
                for (int i = 1; i < 256; i++)
                {
                    graydense[i] = graydense[i]+ graydense[i - 1];
                    //累计百分比
                }
         5 根据变换公式改变各频率对应的灰度值  公式: 新灰度值 = 累计频率占比 * 255。
                 newpixel = Convert.ToInt16(graydense[Convert.ToInt16(pixel.R)] * 255);

了解了步骤然后就开始写demo吧!

写个简单的窗体界面:

我的IDE为Visual Studio 2017

先看看demo的界面

然后就是界面里包含的控件


picturebox1和picturebox2控件分别用来显示原始图像和处理后的图像

button1和openfiledialog1是open打开文件按钮

button2和savefiledialog1是保存图片按钮

button3的click事件为均衡化操作

两个label   Original Image和New Image

然后再看看三个按钮的后台事件的带码

button1_Click:

        private void button1_Click(object sender, EventArgs e)
        {
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                string path = openFileDialog1.FileName;
                bitmap = (Bitmap)Image.FromFile(path);
                pictureBox1.Image = bitmap.Clone() as Image;
            }
        }

button2_Click:

        private void button2_Click(object sender, EventArgs e)
        {
            bool isSave = true;

            if (saveFileDialog1.ShowDialog() == DialogResult.OK)
            {
                string fileName = saveFileDialog1.FileName.ToString();

                if (fileName != "" && fileName != null)
                {
                    string fileExtName = fileName.Substring(fileName.LastIndexOf(".") + 1).ToString();

                    System.Drawing.Imaging.ImageFormat imgformat = null;

                    if (fileExtName != "")
                    {
                        switch (fileExtName)
                        {
                            case "jpg":
                                imgformat = System.Drawing.Imaging.ImageFormat.Jpeg;
                                break;
                            case "bmp":
                                imgformat = System.Drawing.Imaging.ImageFormat.Bmp;
                                break;
                            case "gif":
                                imgformat = System.Drawing.Imaging.ImageFormat.Gif;
                                break;
                            default:
                                MessageBox.Show("只能存取为: jpg,bmp,gif 格式");
                                isSave = false;
                                break;
                        }

                    }

                    //默认保存为JPG格式   
                    if (imgformat == null)
                    {
                        imgformat = System.Drawing.Imaging.ImageFormat.Jpeg;
                    }

                    if (isSave)
                    {
                        try
                        {
                            this.pictureBox2.Image.Save(fileName, imgformat);
                            //MessageBox.Show("图片已经成功保存!");   
                        }
                        catch
                        {
                            MessageBox.Show("保存失败,你还没有截取过图片或已经清空图片!");
                        }
                    }
                }
            }
        }

button3_Click:

        private void button3_Click(object sender, EventArgs e)
        {
            if (bitmap != null)
            {
                newbitmap = bitmap.Clone() as Bitmap;//clone一个副本
                int width = newbitmap.Width;
                int height = newbitmap.Height;
                int size = width * height;
                //总像数个数
                int[] gray = new int[256];
                //定义一个int数组,用来存放各像元值的个数
                double[] graydense = new double[256];
                //定义一个float数组,存放每个灰度像素个数占比
                for (int i = 0; i < width; ++i)
                    for (int j = 0; j < height; ++j)
                    {
                        Color pixel = newbitmap.GetPixel(i, j);
                        //计算各像元值的个数
                        gray[Convert.ToInt16(pixel.R)] += 1;
                        //由于是灰度只读取R值
                    }
                for (int i = 0; i < 256; i++)
                {
                    graydense[i] = (gray[i] * 1.0) / size;
                    //每个灰度像素个数占比
                }

                for (int i = 1; i < 256; i++)
                {
                    graydense[i] = graydense[i]+ graydense[i - 1];
                    //累计百分比
                }
            
                for (int i = 0; i < width; ++i)
                    for (int j = 0; j < height; ++j)
                    {
                        Color pixel = newbitmap.GetPixel(i, j);
                        int oldpixel = Convert.ToInt16(pixel.R);//原始灰度
                        int newpixel = 0;
                        if (oldpixel == 0)
                            newpixel = 0;
                            //如果原始灰度值为0则变换后也为0
                        else
                            newpixel = Convert.ToInt16(graydense[Convert.ToInt16(pixel.R)] * 255);
                            //如果原始灰度不为0,则执行变换公式为   <新像元灰度 = 原始灰度 * 累计百分比>
                        pixel = Color.FromArgb(newpixel, newpixel, newpixel);
                        newbitmap.SetPixel(i, j, pixel);//读入newbitmap
                    }
                pictureBox2.Image = newbitmap.Clone() as Image;//显示至pictureBox2
                
            }
        }

        
    }
}

处理效果:


最后:

最为关键的均衡化操作我的注释写的贼清楚,大家就自己看。

完整的代码看上面的github链接。

良心代码绝不留坑!复制粘贴既有效!复制粘贴既有效!(。・∀・)ノ

如果复制粘贴无效,你可以。。。。。。。。。。。。。。。顺着网线来砍我啊!



猜你喜欢

转载自blog.csdn.net/define_lin/article/details/80265441
今日推荐