【问题标题】:Histogram Equalization without OpenCV没有 OpenCV 的直方图均衡
【发布时间】:2015-12-07 04:07:39
【问题描述】:

我正在写一个直方图均衡函数,我不能使用 OpenCV。我的目标是获取灰度图像的直方图并对其进行均衡以使其更清晰。我正在使用 Visual Studio 2015。

这是我目前的代码:

void equalizeHistogram(int *pix, int nc, int nr)
{
    int cumhistogram[256];
    cumhistogram[0] = pix[0];
    for (int i = 1; i < 256; i++)
    {
        cout << pix[i];
        cumhistogram[i] = pix[i] + cumhistogram[i - 1];
    }

    int b[256];
    for (int i = 0; i < 256; i++)
    {
        b[i] = (double)pix[i] / (nc*nr);
    }
    int c[256];
    for (int i = 0; i < 256; i++)
    {
        c[i] = 0;
    }
    int d[256];

    for (int i = 0; i < 256; i++)
    {
        d[i] = round((double)cumhistogram[i] * (255 / (nr*nc)));
    }

    for (int i = 0; i < 256; i++)
    {
        c[d[i]] += b[i];
    }
    int finl[256];
    for (int i = 0; i < 256; i++)
        finl[i] = round(c[i] * 255);
}

我还发布了this question。我发布了一个新问题,删除了不必要的信息和代码。

【问题讨论】:

  • OpenCV 是开源的,您可以下载它的源代码并从中获得灵感
  • 因为在我看来您的previous question 问题几乎 没问题(只需要稍作编辑以删除不必要的部分),我将您代码的相关部分编辑为这个问题,否则看起来像gimme teh codez 问题。对于未来,请在发布新问题之前阅读How to Ask
  • 为什么这个问题的分数是-3(我投票后是-2)?这不是一个坏问题,而且它被认为是重复的问题甚至不再存在。鼓励新用户的方式,SO 社区。 :V

标签: c++ visual-studio image-processing histogram


【解决方案1】:

下面的函数将均衡输入图像的直方图。改编自OpenCV implementation

由于您使用int* 作为图像,因此我保留了这种格式(通常您会使用unsigned char*unsigned short*)。您也可以传递 max_val,因为对于 PGM 图像,范围可以在 [0,255][0,65535] 中,具体取决于图像值。

如果图像有这样的直方图:

均衡后的直方图如下:

void equalizeHistogram(int* pdata, int width, int height, int max_val = 255)
{
    int total = width*height;
    int n_bins = max_val + 1;

    // Compute histogram
    vector<int> hist(n_bins, 0);
    for (int i = 0; i < total; ++i) {
        hist[pdata[i]]++;
    }

    // Build LUT from cumulative histrogram

    // Find first non-zero bin
    int i = 0;
    while (!hist[i]) ++i;

    if (hist[i] == total) {
        for (int j = 0; j < total; ++j) { 
            pdata[j] = i; 
        }
        return;
    }

    // Compute scale
    float scale = (n_bins - 1.f) / (total - hist[i]);

    // Initialize lut
    vector<int> lut(n_bins, 0);
    i++;

    int sum = 0;
    for (; i < hist.size(); ++i) {
        sum += hist[i];
        // the value is saturated in range [0, max_val]
        lut[i] = max(0, min(int(round(sum * scale)), max_val));
    }

    // Apply equalization
    for (int i = 0; i < total; ++i) {
        pdata[i] = lut[pdata[i]];
    }
}

【讨论】:

  • 最佳答案!尽管您可以通过使用指针而不是向量来极大地提高速度。例如。 int *hist = new int[hist_sz] {};
  • @SyaifulNizamYahya 谢谢。关于“你可以通过使用指针来极大地提高速度......”这不是真的,它们的表现基本相同。
  • 受您的实现启发,我在这里做了一个 16 位灰度直方图均衡化,github.com/syaifulnizamyahya/HistogramEqualization16Bit
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-03-16
  • 1970-01-01
  • 2010-12-23
  • 1970-01-01
  • 2014-03-11
  • 2017-05-17
  • 1970-01-01
相关资源
最近更新 更多