数字图像处理对比度拉伸直方图

问题描述

在这里我附上我用来绘制对比图像的直方图以及将灰度图像转换为对比图像的代码。这里我使用低品脱为 122,最高点为 244。在输出直方图中,它降低了直方图的高度。

我在我的代码中找不到错误

#include "opencv2/opencv.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/core.hpp"

using namespace cv;
using namespace std;

int main(int argc,char* argv[]) {
    Mat img = imread(argv[1],1);

    if (!img.data) { 
        cout << "Could not find the image!" << endl;
        return -1;
    }

    int height = img.rows;
    int width = img.cols;
    int widthstep = img.step;
    int ch = img.channels();

    printf("Height : %d\n",height);
    printf("Width : %d\n",width);
    printf("Widthstep : %d\n",widthstep);
    printf("No of channels : %d\n",ch);

    Mat gray_image(height,width,CV_8UC1,Scalar(0));
    cvtColor(img,gray_image,COLOR_BGR2GRAY);

    Mat new_image = gray_image.clone();
    int v;
    int output{};

    for (int y = 0; y < height; y++) {
        for (int x = 0; x < width; x++) {
            int v = (int)gray_image.at<uchar>(y,x);
            if (v >= 0 && v <= 122) {
                output = int((6 / 122) * v);
            }
            else if (v > 100 && v <= 244) {
                output = int(((244) / (122)) * (v - 122) + 6);
            }
            else if (v > 244 && v <= 255) {
                output = int(((5) / (11)) * (v - 244) + 250);
            }
            new_image.at<uchar>(y,x) = (uchar)output;
        }
    }

    int histn[256];
    for (int i = 0; i < 256; i++) {
        histn[i] = 0;
    }

    for (int y = 0; y < height; y++) {
        for (int x = 0; x < width; x++) {
            histn[(int)new_image.at<uchar>(y,x)] = histn[(int)new_image.at<uchar>(y,x)] + 1;
        }
    }

    for (int i = 0; i < 256; i++) {
        cout << i << ":" << histn[i] << endl;
    }

    int hist_wn = 512;
    int hist_hn = 400;
    int bin_wn = cvRound((double)hist_wn / 256);

    Mat new_histogramImage(hist_hn,hist_wn,Scalar(255));

    int maxn = histn[0];
    for (int i = 0; i < 256; i++) {
        if (maxn < histn[i]) {
            maxn = histn[i];
        }
    }

    for (int i = 0; i < 256; i++) {
        histn[i] = ((double)histn[i] / maxn) * new_histogramImage.rows;
    }

    for (int i = 0; i < 256; i++) {
        line(new_histogramImage,Point(bin_wn * (i),hist_hn),hist_hn - histn[i]),Scalar(0),1,8,0);
    }

    imwrite("Gray_Image.png",gray_image);
    imwrite("newcontrast_Image.png",new_image);
    imwrite("Histogram.png",new_histogramImage);

    namedWindow("Image");
    imshow("Image",img);
    namedWindow("Gray_Image");
    imshow("Gray_Image",gray_image);
    namedWindow("newcontrast_Image");
    imshow("newcontrast_Image",new_image);
    namedWindow("New_Histogram");
    imshow("New_Histogram",new_histogramImage);
    namedWindow("Old_Histogram");
    imshow("Old_Histogram",histimage);

    waitKey(0);
    return 0;
}

这是我作为输出得到的新旧直方图

enter image description here

解决方法

我找到了问题的解决方案。在这里,我将最低和最高点值更改为 100 和 240,并在使用这些值时将它们设置为小数值。

for (int y = 0; y < height; y++) {
        for (int x = 0; x < width; x++) {
            int v = (int)gray_image.at<uchar>(y,x);
            if (v >= 0 && v <= 100) {
                output = int((5.0/ 100.0) * v);
            }
            else if (v > 100 && v <= 240) {
                output = int(((245.0) / (140.0)) * (v - 100.0) + 5.0);
            }
            else if (v > 240 && v <= 255) {
                output = int(((5.0) / (15.0)) * (v - 240.0) + 250.0);
            }
            new_image.at<uchar>(y,x) = (uchar)output;
        }
    }