没有OpenCV的直方图均衡

时间:2015-12-07 04:07:39

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

我正在编写直方图均衡功能,但我无法使用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。我发布了一个删除不必要信​​息和代码的新问题。

1 个答案:

答案 0 :(得分:3)

以下功能将均衡输入图像的直方图。它来自OpenCV implementation

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

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

enter image description here

均衡直方图将如下:

enter image description here

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]];
    }
}