数字图像处理基础实验(二):直方图均衡化

一、实验内容及原理

1、计算灰度图像的归一化直方图

具体内容:利用 OpenCV 对图像像素进行操作,计算归一化直方图.并在 窗口中以图形的方式显示出来

步骤:
(1)初始化一个256大小的数组,存放图像中每级灰度值的像素点的个数
(2)遍历整张图像
(3)归一化数组

2、灰度图像直方图均衡处理

具体内容:通过计算归一化直方图,设计算法实现直方图均衡化处理。

步骤:
(1)读取该像素点的灰度值
(2)计算其在归一化直方图中的累加概率
(3)累加概率乘以255,并四舍五入

3、彩色图像直方图均衡处理

具体内容: 在灰度图像直方图均衡处理的基础上实现彩色直方图均衡处理

步骤:
(1)读取该像素点的三通道灰度值
(2)计算其在归一化直方图中的累加概率
(3)累加概率乘以255,并四舍五入

二、实验代码

实验环境:
(1)OpenCV3.4.3
(2)Ubuntu16.04
(3)VS Code
(4)C++

#include 
#include 
#include 
#include 
#include 

class Experiment2 {
public:
    Experiment2(std::vector path){
        for(int i = 0; i < path.size(); i++){
            original_color_image.push_back(cv::imread(path[i]));
            original_gray_image.push_back(color2Gray(original_color_image[i]));
        }
    }
    // 0.1、彩色图像转灰度图像
    cv::Mat color2Gray(cv::Mat src_image){
        //创建与原图同类型和同大小的矩阵
	    cv::Mat gray_image(src_image.rows, src_image.cols, CV_8UC1);
        if(src_image.channels()!=1){
            for(int i = 0; i < src_image.rows; i++)
                for(int j = 0; j < src_image.cols; j++)
                    gray_image.at(i, j) = (src_image.at(i, j)[0] + src_image.at(i, j)[1] + src_image.at(i, j)[2]) / 3;
        }
        else
            gray_image = src_image.clone();
        return gray_image;
    }
    // 2.1、计算灰度图像的归一化直方图
    void computerGrayHistogram(int pic_id, int opt=1){
        std::vector hist(256,0);
        cv::Mat image = (opt > 0) ? original_gray_image[pic_id] : gray_image_equalization[pic_id];
        float nums = image.rows * image.cols;
        float max = 0;
        for(int i = 0; i < image.rows; i++)
            for(int j = 0; j < image.cols; j++)
                hist[image.at(i, j)]++;
        for(int i=0; i < 256; i++){
            hist[i] = hist[i] / nums;
            if(hist[i] > max)
                max = hist[i];
        }
        if(opt)
            gray_hist.push_back(hist);
        else
            gray_hist_equalization.push_back(hist);
        drawGrayHist(max, pic_id, opt);
    }
    // 2.2、绘制归一化直方图 
    void drawGrayHist(float maxValue, int pic_id, int opt=1){
        int scale = 20000;
        int hist_h = scale * maxValue, hist_w = 257;
        std::vector hist = (opt > 0) ? gray_hist[pic_id] : gray_hist_equalization[pic_id];
        // 画图底色
        cv::Mat image_hist = cv::Mat::zeros(hist_h, hist_w, CV_8U);
        // 画出直方图
        for (int i = 0; i < 256; i++){
            float binValue = hist[i];
            int realValue  = cv::saturate_cast(binValue * scale);
            cv::rectangle(image_hist,
                          cv::Point(i, hist_h - realValue),
                          cv::Point(i + 1, hist_h),
                          cv::Scalar(255));
        }
        if(opt)
            gray_image_hist.push_back(image_hist);
        else
            gray_image_hist_equalization.push_back(image_hist);
    }
    // 3、灰度图像直方图均衡处理
    void grayEqualization(int pic_id){
        cv::Mat image_equalization = cv::Mat::zeros(original_gray_image[pic_id].size(), original_gray_image[pic_id].type());
        for(int i = 0; i < original_gray_image[pic_id].rows; i++)
            for(int j = 0; j < original_gray_image[pic_id].cols; j++){
                int k = original_gray_image[pic_id].at(i, j);
                float sum = 0;
                for(int m = 0; m <= k; m++)
                    sum += gray_hist[pic_id][m];
                image_equalization.at(i, j) = sum * 255 + 0.5;
            }
        gray_image_equalization.push_back(image_equalization);
    }
    // 4.1、彩色图像直方图均衡处理
    void colorEqualization(int pic_id){
        cv::Mat image_equalization = cv::Mat::zeros(original_color_image[pic_id].size(), original_color_image[pic_id].type());
        for(int i = 0; i < original_color_image[pic_id].rows; i++)
            for(int j = 0; j < original_color_image[pic_id].cols; j++)
                for(int n = 0; n < 3; n++){
                    int k = original_color_image[pic_id].at(i, j)[n];
                    float sum = 0;
                    for(int m = 0; m <= k; m++)
                        sum += color_hist[pic_id][n][m];
                    image_equalization.at(i, j)[n] = sum * 255 + 0.5;
                }
        color_image_equalization.push_back(image_equalization);
    }
    // 4.2、计算彩色图像的归一化直方图
    void computerColorHistogram(int pic_id){
        std::vector > hist(3, std::vector(256)); 
        int nums = original_color_image[pic_id].rows * original_color_image[pic_id].cols;
        for(int i = 0; i < original_color_image[pic_id].rows; i++)
            for(int j = 0; j < original_color_image[pic_id].cols; j++){
                hist[0][original_color_image[pic_id].at(i, j)[0]]++;
                hist[1][original_color_image[pic_id].at(i, j)[1]]++;
                hist[2][original_color_image[pic_id].at(i, j)[2]]++;
            }
        for(int i=0; i < 256; i++){
            hist[0][i] = hist[0][i] / nums;
            hist[1][i] = hist[1][i] / nums;
            hist[2][i] = hist[2][i] / nums;
        }
        color_hist.push_back(hist);
    }
    // 5 显示 灰度均衡化 与 灰度直方图
    void test_GrayEqualizationAndHistogram(){
        for(int i = 0; i < original_gray_image.size(); i++){
            computerGrayHistogram(i);
            grayEqualization(i);
            std::cout<< "灰度图像: 当前已经均衡化第" << i + 1 << "张图像\n";
        }
        // 显示结果
        cv::imshow(" 原始灰度图像", original_gray_image[0]);
        cv::waitKey(0);
        for(int i = 0; i < original_gray_image.size(); i++){
            cv::imshow("原始图像的灰度直方图:", gray_image_hist[i]);
            cv::waitKey(0);
            cv::imshow("均衡化后的灰度图像:", gray_image_equalization[i]);
            cv::waitKey(0);
        }
        std::cout<< "\n";
    }
    // 6 显示 彩色均衡化 
    void test_ColorEqualizationAndHistogram(){
        for(int i = 0; i < original_color_image.size(); i++){
            computerColorHistogram(i);
            colorEqualization(i);
            std::cout<< "彩色图像: 当前已经均衡化第" << i + 1 << "张图像\n";
        }
        // 显示结果
        cv::imshow("原始图像", original_color_image[0]);
        cv::waitKey(0);
        for(int i = 0; i < original_color_image.size(); i++){
            cv::imshow("均衡化后---彩色图像:", color_image_equalization[i]);
            cv::waitKey(0);
        }
    }

private:
    std::vector color_info;
    std::vector gray_info;
    // 原始图像
    std::vector original_color_image;
    std::vector original_gray_image;
    // 均衡化后的图像
    std::vector  color_image_equalization;
    std::vector  gray_image_equalization;
    // 画出来的灰度直方图
    std::vector gray_image_hist;
    std::vector > color_image_hist;
    std::vector gray_image_hist_equalization;
    std::vector > color_image_hist_equalization;
    // 灰度图像的灰度分布 (图像名,每级灰度的个数)
    std::vector > gray_hist;
    std::vector > gray_hist_equalization;
    // 彩色图像的灰度分布(图像名,通道,每级灰度的个数)
    std::vector > > color_hist;
    std::vector > > color_hist_equalization;
};

int main(){
    std::vector path;
    path.push_back("/home/lyd/image_process/pic/lena.jpg");
    Experiment2 a(path);

    a.test_GrayEqualizationAndHistogram();
    a.test_ColorEqualizationAndHistogram();

    return 1;
}

三、实验结果

数字图像处理基础实验(二):直方图均衡化_第1张图片

你可能感兴趣的:(图像处理)