首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > C# >

c# 数字图像处理直方图作图

2012-12-15 
c# 数字图像处理直方图绘制照着赵春江那本书写的代码~ 代码和下面从网上copy来的一致~但是我的显示为什么

c# 数字图像处理直方图绘制
照着赵春江那本书写的代码~ 代码和下面从网上copy来的一致~但是我的显示为什么是这样的哇?恳请各位高手解决~


双击“histogram”控件,并在其中添加如下代码:
       private void histogram_Click(object sender, EventArgs e)
        {
            if (curBitmap != null)
            {
                //定义并实例化新窗体,并把图像数据传递给它;
                histForm histoGram = new histForm(curBitmap);
                //打开从窗体;
                histoGram.ShowDialog();
            }
            else
            {
                //没有打开图像时,弹出对应的提示框;
                MessageBox.Show("请先打开图像!");
            }
        }
 
然后在打开的histForm窗体中先定义以下3个数据成员:
        //图像数据
        private System.Drawing.Bitmap bmpHist;
        //为了标识横纵坐标的标识;
        private int[] countPixel;
        
        private int maxPixel=1000;//记录最大的灰度级个数
为了实现两个窗体之间的数据传递,需要改写histForm窗体的构造函数,其代码如下:
       public histForm(Bitmap bmp)
        {
            InitializeComponent();
            //把主窗体的图像数据传递给从窗体
            bmpHist = bmp;
            //灰度级计数
            countPixel=new int[256];
        }
 
分别为histForm窗体添加Paint和Load事件,Paint事件用于绘制直方图,Load事件用于计算各个灰度级所具有的像素个数,其代码如下:
                                                              
1——————————————————————Paint事件;
        private void histForm_Paint(object sender, PaintEventArgs e)
        {
            //获取Graphics对象
            Graphics g = e.Graphics;

            //创建一个宽度为1的黑色钢笔
            Pen curPen = new Pen(Brushes.Black, 1);


            //绘制坐标轴
            //(y,x)=(50,240)原点;
            g.DrawLine(curPen,50,240,320,240);//横坐标
            g.DrawLine(curPen,50,240,50,30);//纵坐标
            //绘制并标识坐标刻度
            g.DrawLine(curPen, 100, 240, 100, 242);
            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);
            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));
            g.DrawLine(curPen,48,40,50,40);
            g.DrawString(maxPixel.ToString(), new Font("New Timer", 8), Brushes.Black, new PointF(18, 38));
            //开始绘制直方图
            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();
        }
2————————————————Load事件:

        /// <summary>
        /// 直方图的绘制;


        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void histForm_Load(object sender, EventArgs e)
        {
            //锁定8位灰度位图
            Rectangle rect = new Rectangle(0, 0, bmpHist.Width, bmpHist.Height);
            System.Drawing.Imaging.BitmapData bmpData = bmpHist.LockBits(rect,
                System.Drawing.Imaging.ImageLockMode.ReadOnly,
                bmpHist.PixelFormat);
            IntPtr ptr = bmpData.Scan0;
            int bytes = bmpHist.Width * bmpHist.Height*3;
            byte[] graybValues = new byte[bytes];
            System.Runtime.InteropServices.Marshal.Copy(ptr, graybValues, 0, bytes);
            byte temp = 0;
            maxPixel = 0;
            //灰度等级数组清零
            Array.Clear(countPixel,0,256);
            //计算各个灰度级的像素个数
            for (int i = 0; i < bytes;i++ )
            {
                //灰度级
                temp=graybValues[i];
                //计数加1
                countPixel[temp]++;
                if(countPixel[temp]>maxPixel)
                {
                    //找到灰度频率最大的像素数,用于绘制直方图
                    maxPixel=countPixel[temp];
                }
            }
            //解锁
            System.Runtime.InteropServices.Marshal.Copy(graybValues,0,ptr,bytes);
            bmpHist.UnlockBits(bmpData);
        }
------最佳解决方案--------------------


 for (int i = 0; i < bytes;i++ )
             {
                 //灰度级
                 temp=graybValues[i];
                 //计数加1
                 countPixel[temp]++;
                 if(countPixel[temp]>maxPixel)
                 {
                     //找到灰度频率最大的像素数,用于绘制直方图
                     maxPixel=countPixel[temp];
                 }
             }这个地方写错了,这本书有很多错误,你需要修改的,你前面得到的bytes是整个图的信息,包括了R,G,B信息,但是你的直方图计算的是灰度直方图,所以你应该这么改:
 for (int i = 0; i < bytes-3;i+=3 )
             {
                 //灰度级
                 temp=(int)(graybValues[i]*0.114+grayValues[i+1]*0.587+grayValues[i+2]*0.219);
                 //计数加1
                 countPixel[temp]++;
                 if(countPixel[temp]>maxPixel)
                 {
                     //找到灰度频率最大的像素数,用于绘制直方图
                     maxPixel=countPixel[temp];
                 }
             }
[其他解释]
该回复于2012-12-05 08:47:06被管理员删除
[其他解释]


脑壳都看混了   学习。。
[其他解释]

引用:
for (int i = 0; i < bytes;i++ )
             {
                 //灰度级
                 temp=graybValues[i];
                 //计数加1
                 countPixel[temp]++;
           ……


soga。。。。我试试~谢谢~!

热点排行