C#绘制灰度直方图

灰度直方图是灰度的函数,描述的是图像中具有该灰度级的像素的个数。如果用直角坐标系来表示,则它的横坐标是灰度级,纵坐标是该灰度出现的概率(像素的个数)。

灰度直方图的分布函数:

其中,K是指第k个灰度级,

如果是8位灰度图像,k=0、1、……、255。

界面设计如下:

C#绘制灰度直方图_第1张图片

图像输出界面如下:C#绘制灰度直方图_第2张图片

在设计时先定义对象:

#endregion

        private System.Windows.Forms.PictureBox pictureBox1;
        private System.Windows.Forms.Button button1;
        private System.Windows.Forms.OpenFileDialog openFileDialog1;
        private System.Windows.Forms.Button button2;

具体的如下

 partial class Form1
    {
        ///


        /// 必需的设计器变量。
        ///

        private System.ComponentModel.IContainer components = null;

        ///


        /// 清理所有正在使用的资源。
        ///

        /// 如果应释放托管资源,为 true;否则为 false。
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows 窗体设计器生成的代码

        ///


        /// 设计器支持所需的方法 - 不要
        /// 使用代码编辑器修改此方法的内容。
        ///

        private void InitializeComponent()
        {
            this.pictureBox1 = new System.Windows.Forms.PictureBox();
            this.button1 = new System.Windows.Forms.Button();
            this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog();
            this.button2 = new System.Windows.Forms.Button();
            ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
            this.SuspendLayout();
            //
            // pictureBox1
            //
            this.pictureBox1.Location = new System.Drawing.Point(93, 12);
            this.pictureBox1.Name = "pictureBox1";
            this.pictureBox1.Size = new System.Drawing.Size(494, 384);
            this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
            this.pictureBox1.TabIndex = 0;
            this.pictureBox1.TabStop = false;
            //
            // button1
            //
            this.button1.Location = new System.Drawing.Point(12, 12);
            this.button1.Name = "button1";
            this.button1.Size = new System.Drawing.Size(75, 23);
            this.button1.TabIndex = 1;
            this.button1.Text = "打开";
            this.button1.UseVisualStyleBackColor = true;
            this.button1.Click += new System.EventHandler(this.button1_Click);
            //
            // openFileDialog1
            //
            this.openFileDialog1.Filter = "JPG文件|*.jpg|PNG文件|*.png|BMP文件|*.bmp";
            //
            // button2
            //
            this.button2.Location = new System.Drawing.Point(12, 41);
            this.button2.Name = "button2";
            this.button2.Size = new System.Drawing.Size(75, 23);
            this.button2.TabIndex = 2;
            this.button2.Text = "直方图";
            this.button2.UseVisualStyleBackColor = true;
            this.button2.Click += new System.EventHandler(this.button2_Click);
            //
            // Form1
            //
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(599, 408);
            this.Controls.Add(this.button2);
            this.Controls.Add(this.button1);
            this.Controls.Add(this.pictureBox1);
            this.Name = "Form1";
            this.Text = "灰度直方图";
            ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
            this.ResumeLayout(false);

        }

        #endregion

        private System.Windows.Forms.PictureBox pictureBox1;
        private System.Windows.Forms.Button button1;
        private System.Windows.Forms.OpenFileDialog openFileDialog1;
        private System.Windows.Forms.Button button2;
    }

窗口设计如下

 public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        Bitmap bitmap;

        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;
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (bitmap != null)
            {
                Grey_ScaleMapForm fr = new Grey_ScaleMapForm(bitmap);
                fr.ShowDialog();
            }
        }
    }

类定义如下

 public partial class Grey_ScaleMapForm : Form
    {
        private System.Drawing.Bitmap bmpHist;//用bitmap做图像处理,可以获取灰度
        private int[] countPixel;//将点记录
        private int maxPixel;//记录最大的点

        public Grey_ScaleMapForm(Bitmap bmp)
        {
            InitializeComponent();

            bmpHist = bmp;

            countPixel = new int[256];
        }

        private void button1_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void Grey_ScaleMapForm_Paint(object sender, PaintEventArgs e)
        {
            //画出坐标系
            Graphics g = e.Graphics;

            Pen curPen = new Pen(Brushes.Black, 1);

            g.DrawLine(curPen, 50, 240, 320, 240);//X轴
            g.DrawLine(curPen, 50, 240, 50, 30);//Y轴
               //绘制并标识坐标刻度
            g.DrawLine(curPen, 100, 240, 100, 242);//同上,画长度为2的线
            g.DrawLine(curPen, 150, 240, 150, 242);
            g.DrawLine(curPen, 200, 240, 200, 242);
            g.DrawLine(curPen, 250, 240, 250, 242);
            g.DrawLine(curPen, 300, 240, 300, 242);
            //在x轴上为刻度标出刻度值
            g.DrawString("0", new Font("New Timer", 8), Brushes.Black, new PointF(46, 242));
            g.DrawString("50", new Font("New Timer", 8), Brushes.Black, new PointF(92, 242));
            g.DrawString("100", new Font("New Timer", 8), Brushes.Black, new PointF(139, 242));
            g.DrawString("150", new Font("New Timer", 8), Brushes.Black, new PointF(189, 242));
            g.DrawString("200", new Font("New Timer", 8), Brushes.Black, new PointF(239, 242));
            g.DrawString("250", new Font("New Timer", 8), Brushes.Black, new PointF(289, 242));
            //在y轴上为标刻度及刻度值
            g.DrawLine(curPen, 48, 40, 50, 40);
            g.DrawString("0", new Font("New Timer", 8), Brushes.Black, new PointF(34, 234));
            g.DrawString(maxPixel.ToString(), new Font("New Timer", 8), Brushes.Black, new PointF(18, 34));
            //绘制直方图
            double temp = 0;
            for (int i = 0; i < 256; i++)
            {
                //纵坐标长度
                temp = 200.0 * countPixel[i] / maxPixel;
                g.DrawLine(curPen, 50 + i, 240, 50 + i, 240 - (int)temp);
            }
            //释放对象
            curPen.Dispose();
        }

        private void Grey_ScaleMapForm_Load(object sender, EventArgs e)
        {
            //将图像数据复制到byte中,锁定8位灰度位图
            Rectangle rect = new Rectangle(0, 0, bmpHist.Width, bmpHist.Height);
            //以可读写的方式锁定全部位图像素
            System.Drawing.Imaging.BitmapData bmpdata = bmpHist.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, bmpHist.PixelFormat);
            //得到首地址
            IntPtr ptr = bmpdata.Scan0;
            //定义被锁定的数组大小,由位图数据与未用空间组成
            int bytes = bmpHist.Width * bmpHist.Height * 3;
            byte[] grayValues = new byte[bytes];
            //复制被锁定的位图像素值到该数组中
            System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);

            //统计直方图信息
            byte temp = 0;
            maxPixel = 0;
            //灰度等级数组清零
            Array.Clear(countPixel, 0, 256);
            //计算各个灰度级的像素个数
            for (int i = 0; i < bytes; i++)
            {
                temp = grayValues[i]; //灰度级
                countPixel[temp]++;
                if (countPixel[temp] > maxPixel)
                {
                    maxPixel = countPixel[temp];//找到灰度频率最大的像素数,用于绘制直方图
                }
            }
            //解锁
            System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes);

            bmpHist.UnlockBits(bmpdata);

        }
    }

 

你可能感兴趣的:(c#,开发语言,后端,图像处理)