c# 数字图像处理直方图绘制

eibhlin 2012-12-04 03:52:27
照着赵春江那本书写的代码~ 代码和下面从网上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);
}
...全文
1342 5 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
哈哈,写得不错,正在学习中ing...
Trent1985 2012-12-05
  • 打赏
  • 举报
回复
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]; } }
eibhlin 2012-12-05
  • 打赏
  • 举报
回复
引用 3 楼 Trent1985 的回复:
for (int i = 0; i < bytes;i++ ) { //灰度级 temp=graybValues[i]; //计数加1 countPixel[temp]++; ……
soga。。。。我试试~谢谢~!
Kerry_Sole_8888 2012-12-04
  • 打赏
  • 举报
回复
脑壳都看混了 学习。。

111,097

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧