第1个回答 2013-06-27
using System;
using System.Collections.Generic;
using
System.Text;
using System.Drawing;
using
System.Drawing.Imaging;
namespace 图像直方图及均衡化
{
///
<summary>
/// 图像直方图处理类
/// </summary>
class
Histogram
{
Bitmap sourceImg = null;
int width
= 0; //源图宽度
int height = 0; //源图高度
int bytes =
0;
int grayLevels = 0;// 图像灰度级数
int[] histogram =
null;// 直方图
float[] cumulativeHistogram = null;//
归一化的累积直方图
byte[] mapPixel = null;// 像素-灰度 映射表
int[] newHistogram = null; // 新直方图
int maxValue = 0;
//灰度最大值
/// <summary>
/// 初始化待处理图像
/// </summary>
/// <param
name="img">待处理图像</param>
/// <param
name="bitNum">源图位数</param>
public Histogram(Bitmap img, byte
bitNum)
{
if (null == img)
throw
new Exception("不能对非图像对象求取直方图!");
if (0 != (bitNum %
8))
throw new Exception("源图位数设置有误!
必须为8的整数倍.");
sourceImg = img;
width =
sourceImg.Width; //源图宽度
height = sourceImg.Height;
//源图高度
bytes = width * height;
BitmapData
bmData = sourceImg.LockBits(new Rectangle(0, 0, width,
height),
ImageLockMode.ReadOnly,
PixelFormat.Format8bppIndexed);
IntPtr ptr =
bmData.Scan0;
byte[] grayValues = new byte[bytes];
System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0,
bytes);
grayLevels = 2 << (bitNum - 1);
//图像灰度级数
histogram = new int[grayLevels];
//直方图
cumulativeHistogram = new float[grayLevels];
//累积直方图
maxValue = 0;
byte
temp;
for (int i = 0; i < bytes; i++)
//2.列出原始直方图
{
temp =
grayValues[i];
histogram[temp]++;
}
cumulativeHistogram[0] = histogram[0] * 1.0F / bytes;
//归一化
for (int i = 1; i < grayLevels; i++)
//3.求取累积直方图
{
/** 获得最大灰度值
**/
if (histogram[i] > maxValue)
{
maxValue = histogram[i];
}
cumulativeHistogram[i] = cumulativeHistogram[i - 1] +
histogram[i] * 1.0F / bytes; //累积
//cumulativeHistogram[i]
/= bytes * 1.0F;
}
System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr,
bytes);
sourceImg.UnlockBits(bmData);
}
/// <summary>
/// 直方图均衡化
///
</summary>
///
<returns>均衡化之后的图像</returns>
public Image
HistogramEqualization()
{
mapPixel = new
byte[grayLevels];
newHistogram = new
int[grayLevels];
byte temp;
for (int i = 0; i
< grayLevels; i++) //4.取整
{
temp =
(byte)((grayLevels - 1) * cumulativeHistogram[i] + 0.5F);
//重新计算并映射
mapPixel[i] = temp;
newHistogram[temp] += histogram[i];
}
BitmapData bmData = sourceImg.LockBits(new Rectangle(0, 0, width,
height),
ImageLockMode.ReadWrite,
PixelFormat.Format8bppIndexed);
IntPtr ptr =
bmData.Scan0;
byte[] grayValues = new byte[bytes];
System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0,
bytes);
for (int i = 0; i < bytes; i++)
//重新分布颜色
{
temp =
grayValues[i];
grayValues[i] = (byte)mapPixel[temp];
}
System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr,
bytes);
sourceImg.UnlockBits(bmData);
histogram = newHistogram;
return sourceImg;
}
}
}