我有一些价值观及其可能性,实际上是图像的直方图。 我的目标是使用以下公式来均衡直方图: alt text http://upload.wikimedia.org/math/1/a/d/1ad81c5bfdd01016c7019a33dd1faea1.png
为了使用这个公式,我按照图像像素的数量划分了直方图。所以我得到了一个标准化的直方图(概率值)。 然后,对于图像的每个像素,我使用上面的公式计算了一个新值,所以我只是对归一化直方图的元素进行求和。 例如,具有值23的像素获得新值,其被计算为从0到23的归一化直方图的元素的总和。 hist [0] + ... + hist [23]。 然后将总和乘以255得到0到255之间的值(不在0和1之间)
该方法给出了很好的结果,我在书中看到了一些结果,但在我的情况下,我的实现没有给出好的结果,实际上是错的,有人看到我的方法中的错误吗?
答案 0 :(得分:1)
您似乎在描述正确的算法;有关直方图均衡的另一个指针,请参见此处:
http://en.wikipedia.org/wiki/Histogram_equalization#Implementation
我怀疑错误不是在算法中,而是在你的实现中。您是否检查过直方图看起来合理?代码是否合理地短,以便您可以发布它?
答案 1 :(得分:1)
这是C#中的一个实现。在我的情况下,当我完成计算时,我将直方图标准化。它可能会帮助你
public void Histogram(double[] histogram, Rectangle roi)
{
BitmapData data = Util.SetImageToProcess(image, roi);
if (image.PixelFormat != PixelFormat.Format8bppIndexed)
return;
if (histogram.Length < Util.GrayLevels)
return;
histogram.Initialize();
int width = data.Width;
int height = data.Height;
int offset = data.Stride - width;
unsafe
{
byte* ptr = (byte*)data.Scan0;
for (int y = 0; y < height; ++y)
{
for (int x = 0; x < width; ++x, ++ptr)
histogram[ptr[0]]++;
ptr += offset;
}
}
image.UnlockBits(data);
NormalizeHistogram(histogram, height * width);
}
public void NormalizeHistogram(double[] histogram, int imageArea)
{
for (int i = 0; i < histogram.Length; ++i)
histogram[i] = (double)histogram[i] / imageArea;
}
public void HistogramEqualization(double[] histogram)
{
double[] cdf = new double[Util.GrayLevels];
double sum = 0;
for (int i = 0; i < Util.GrayLevels; i++)
{
sum += histogram[i];
cdf[i] = sum;
}
BitmapData data = Util.SetImageToProcess(image);
unsafe
{
byte* ptr = (byte*)data.Scan0;
int offset = data.Stride - data.Width;
int width = data.Width;
int height = data.Height;
for(int y = 0; y < height; y++)
{
for (int x = 0; x < width; ++x, ++ptr)
ptr[0] = (byte)(cdf[ptr[0]] * ((byte)Util.MaxGrayLevel));
}
ptr += offset;
}
image.UnlockBits(data);
}
static public BitmapData SetImageToProcess(Bitmap image, Rectangle roi)
{
if (image != null)
return image.LockBits(
roi,
ImageLockMode.ReadWrite,
image.PixelFormat);
return null;
}