没有openCV的直方图均衡,C++

Histogram Equalization without openCV, C++

我正在尝试实现直方图均衡化以提高灰度图像的对比度,但无论我做什么,我的程序似乎只会使图像整体变暗。有人能指出我正确的方向吗?这是我现在正在使用的代码,以及一些示例图像

void calcHisto(int w, int h, ifstream& input_1, ofstream& output_1) {

    int tmp = w * h;
    double size = (double)tmp;
    double grayVal[256] = { }; //count of Gray levels 0-255
     double PDF[256] = { };
    double CDF[256] = { };
    double equalized[256] = { };

    int** in_matrix_ch1 = new int* [h]; //Create matrix for grayVals
    for (int i = 0; i < h; ++i)
        in_matrix_ch1[i] = new int[w];
    for (int i_h = 0; i_h < h; i_h++) {
        for (int i_w = 0; i_w < w; i_w++) {
            char g;     //Determine a pixel's gray value
            input_1.get(g);
            in_matrix_ch1[i_h][i_w] = (int)g;

        }
    }
    for (int i_h = 0; i_h < h; i_h++) {
        for (int i_w = 0; i_w < w; i_w++) {
            for (int i = 0; i <= 255; i++) { //Increment the count value for the appropriate grayVal
                if (in_matrix_ch1[i_h][i_w] == i) { //If the grayVal at pixel = an index, increment that index
                    grayVal[i]++;  //If grayVal at pixel = i, increment grayVal[i]
                }
            }
        }
    }

    PDF[0] = grayVal[0] / size;
    CDF[0] = PDF[0];

    for (int i = 1; i <= 255; i++) {
        PDF[i] = grayVal[i] / size;
        CDF[i] = PDF[i] + PDF[i - 1];
        equalized[i] = round(255 * CDF[i]);

    }

    for (int i_h = 0; i_h < h; i_h++) {
        for (int i_w = 0; i_w < w; i_w++) {
            for (int i = 0; i < 255; i++) {
                if (in_matrix_ch1[i_h][i_w] == i) { //If the grayVal at this pixel is equal to an index,
                    in_matrix_ch1[i_h][i_w] = equalized[i]; //Set the grayVal at this pixel to the equalized value of that index
                }
            }
            output_1 << (char)in_matrix_ch1[i_h][i_w];
        }
    }
}
int main(int argc, char* argv[]) {

    ifstream input_1;
    ofstream output_1;
    string header;

    if (argc > 2) {
        // file name 
        input_1.open(argv[1], ios::in | ios::binary);
        output_1.open(argv[2], ios::out | ios::binary);

    }
    else {
        fprintf(stderr, "argv[1] for reading and argv[2] for writing");
        exit(0);
    }
    getline(input_1, header);

    //header w,h extract
    string s_w, s_h;
    s_w = header.substr(3, 3);
    s_h = header.substr(7, 3);
    int w = stoi(s_w), h = stoi(s_h);

    output_1 << header << endl;
    calcHisto(w, h, input_1, output_1);

    input_1.close();
    output_1.close();
    return 0;
}

我正在处理一些 .pgm 图像,这里是原始图像与我得到的结果的对比示例:

Before

After

根据维基百科(Histogram Equalization):

  • 我通过移除内循环改进了直方图计算性能。

  • PDF/CDF 计算被破坏(根据维基百科公式)。不需要PDF。请检查下面我的版本。

  • 我在你的代码中没有看到 cdfmin 计算。

     void calcHisto(int w, int h, ifstream& input_1, ofstream& output_1) {
     int tmp = w * h;
     double size = (double)tmp;
     double grayVal[256] = { }; //count of Gray levels 0-255
     double CDF[256] = { };
     double equalized[256] = { };
    
     int** in_matrix_ch1 = new int* [h]; //Create matrix for grayVals
     for (int i = 0; i < h; ++i)
         in_matrix_ch1[i] = new int[w];
    
     for (int i_h = 0; i_h < h; i_h++) {
         for (int i_w = 0; i_w < w; i_w++) {
             char g;     //Determine a pixel's gray value
             input_1.get(g);
             in_matrix_ch1[i_h][i_w] = (unsigned char)g;
             grayVal[(unsigned char)g]++;
         }
     }
    
     CDF[0] = grayVal[0];
     int cdfmin = CDF[0];
     for (int i = 1; i <= 255; i++) {
         CDF[i] = CDF[i - 1] + grayVal[i];
         if (cdfmin == 0)
             cdfmin = CDF[i];
     }
    
    
     for (int i = 1; i <= 255; i++)
         equalized[i] = std::round( 255 * (CDF[i] - cdfmin) / (size - cdfmin));
    
     for (int i_h = 0; i_h < h; i_h++) {
         for (int i_w = 0; i_w < w; i_w++) {
             int input_color = in_matrix_ch1[i_h][i_w];
             int output_color = equalized[input_color];
             output_1 << (char)output_color;
         }
     }
    
     //TODO: release memory or use e.g: vector
    }
    

Result