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