在图像处理过程中绘制灰度直方图的问题

wowo05 2008-05-17 12:00:29
在图像处理过程中绘制灰度直方图


从pictureBox2读入图像,输出到pictureBox3.



int[,] h = new int[10000, 10000];
int[] t = new int[5000];
Color c = Color.FromArgb(128);

// Color cc = new Color();
int i, j;
int r;
int max = 0;

Bitmap pic = new Bitmap(pictureBox2.Image);
for (i = 1; i < pictureBox2.Image.Width; i++)
{
for (j = 1; j < pictureBox2.Image.Height; j++)
{
c = pic.GetPixel(i, j);
r = c.R;
h[i, j] = r;


}
}

for (i = 1; i < pictureBox2.Image.Width; i++)
{
for (j = 1; j < pictureBox2.Image.Height; j++)
{
for (r = 0; r < 255; r++)
{
if (h[i, j] == r)
{
t[r] = t[r] + 1;
}
}
}
}
//获得直方图的高度
max = t[0];
for (i = 0; i < t.Length - 1; i++)
{

if (t[i] > max)
{
max = t[i];
}
}
max = max / 2 + 1;
Bitmap currentBitmap = new Bitmap(500, max);
// Bitmap currentBitmap = new Bitmap(pictureBox3.Image);
for (r = 0; r < 500; r++)
{
for (j = 1; j < t[r]; j++)
{
currentBitmap.SetPixel(r, max - j / 2 - 1, c);
}
pictureBox3.Refresh();
pictureBox3.Image = currentBitmap;


}


结果只出现一条线,而且偶尔还报出错误,怎么解决?
...全文
504 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
yifansport 2009-11-09
  • 打赏
  • 举报
回复
谢谢楼主提出这么好的问题,我也正需要,写各位仁兄的精彩解答
Ki1381 2008-05-17
  • 打赏
  • 举报
回复
图片旋转90的整数倍是很容易的,RotateFlip方法即可。关键是参数。

顺时针旋转90度 RotateFlipType.Rotate90FlipNone
逆时针旋转90度 RotateFlipType.Rotate270FlipNone
水平翻转 RotateFlipType.Rotate180FlipY
垂直翻转 RotateFlipType.Rotate180FlipX
wowo05 2008-05-17
  • 打赏
  • 举报
回复
显示是反的 就是xy轴 倒了!
wowo05 2008-05-17
  • 打赏
  • 举报
回复
谢谢gomoku 帮助
不过显示是反的,如何把它画正呢?
还有原理是什么呢?


------
解决立马给分,并再次谢谢你的帮助!!
Ki1381 2008-05-17
  • 打赏
  • 举报
回复
在2楼的启发下试写了一个优化版的。正好也要做,苦于没算法,呵呵。多谢。

        public Bitmap GetGrayScale(Bitmap bmp)
{

if (bmp == null) return null;

int[] scales = new int[256];
int maxScale = 1;
int grayscale = 0;

int h = bmp.Height;
int w = bmp.Width;

BitmapData src = bmp.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);

unsafe
{

byte* p = (byte*)src.Scan0.ToPointer();
int stride = src.Stride;

for (int y = 0; y < h; y++)
{
for (int x = 0; x < w; x++)
{

grayscale = (p[2] + p[1] + p[0]) / 3; //换RGB到灰度(亮度)
scales[grayscale]++; //该亮度的统计增一

if (scales[grayscale] > maxScale)
{
maxScale = scales[grayscale]; //记住最大的数值
}

p += 3;
}

p += stride - w * 3;
}

}

bmp.UnlockBits(src);

for (int i = 0; i < scales.Length; i++)
{
scales[i] = scales[i] * 255 / maxScale; //把亮度数组缩小到0~255区间,以便用图像直观表示出来
}

Bitmap result = new Bitmap(256, 256); //准备一个直方图
using (Graphics g = Graphics.FromImage(result))
{
for (int y = 0; y < result.Height; y++)
{
g.DrawLine(Pens.Yellow, 0, y, scales[y], y); //每个色阶画一条线,长度依据该色阶的统计数值
}
}

return result;
}
wenbin 2008-05-17
  • 打赏
  • 举报
回复
gomoku已经给出了
直方图的算法,
然后使用BitmapData类,取代GetPixel操作
就可以
yagebu1983 2008-05-17
  • 打赏
  • 举报
回复
什么是灰度直方图 ??
gomoku 2008-05-17
  • 打赏
  • 举报
回复
以下代码供你参考吧,不过GetPixel是个很慢的操作,你有机会自己优化:


private void button1_Click(object sender, EventArgs e)
{
int[] scales = new int[256]; //保存各阶亮度的统计
Bitmap bmp = new Bitmap( pictureBox1.Image );

int maxScale = 1;
for (int y = 0; y < bmp.Height; y++)
{
for (int x = 0; x < bmp.Width; x++)
{
Color c = bmp.GetPixel(x, y);
int grayscale = (c.R + c.G + c.B) / 3; //换RGB到灰度(亮度)
scales[grayscale]++; //该亮度的统计增一

if (scales[grayscale] > maxScale)
{
maxScale = scales[grayscale]; //记住最大的数值
}
}
}
for (int i = 0; i < scales.Length; i++)
{
scales[i] = scales[i] * 255 / maxScale; //把亮度数组缩小到0~255区间,以便用图像直观表示出来
}

Bitmap result = new Bitmap(256, 256); //准备一个直方图
using (Graphics g = Graphics.FromImage(result))
{
for(int y=0; y<result.Height; y++)
{
g.DrawLine(Pens.Yellow, 0, y, scales[y], y); //每个色阶画一条线,长度依据该色阶的统计数值
}
}
pictureBox2.Image = result;
pictureBox2.Refresh();

}

110,580

社区成员

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

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

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