OpenCV基础04---直方图均衡

2023-09-17 20:58:41 浏览数 (2)

图像的直方图是像素强度分布的图形表示。它提供了像素值集中位置以及是否存在异常偏差的估计值。

使用OpenCV对灰度图像进行直方图均衡

代码语言:javascript复制
//Uncomment the following line if you are compiling this code in Visual Studio
//#include "stdafx.h"

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main(int argc, char** argv)
{
    // Read the image file
    Mat image = imread("C:/Users/Gerry/Desktop/fly-agaric.jpg");

    // Check for failure
    if (image.empty())
    {
        cout << "Could not open or find the image" << endl;
        cin.get(); //wait for any key press
        return -1;
    }

    //change the color image to grayscale image
    cvtColor(image, image, COLOR_BGR2GRAY); 

    //equalize the histogram
    Mat hist_equalized_image;
    equalizeHist(image, hist_equalized_image); 
                                               
    //Define names of windows
    String windowNameOfOriginalImage = "Original Image"; 
    String windowNameOfHistogramEqualized = "Histogram Equalized Image";

    // Create windows with the above names
    namedWindow(windowNameOfOriginalImage, WINDOW_NORMAL);
    namedWindow(windowNameOfHistogramEqualized, WINDOW_NORMAL);

    // Show images inside created windows.
    imshow(windowNameOfOriginalImage, image);
    imshow(windowNameOfHistogramEqualized, hist_equalized_image);

    waitKey(0); // Wait for any keystroke in one of the windows

    destroyAllWindows(); //Destroy all open windows

    return 0;
}

灰度图像的直方图均衡

代码语言:javascript复制
/ Read the image file
Mat image = imread("D:/My OpenCV Website/fly-agaric.jpg");

// Check for failure
if (image.empty())
{
    cout << "Could not open or find the image" << endl;
    cin.get(); //wait for any key press
    return -1;
}

上面的代码段将从指定的文件加载图像。如果图像加载失败,程序将退出。

代码语言:javascript复制
//change the color image to grayscale image
cvtColor(image, image, COLOR_BGR2GRAY); 
//equalize the histogram
Mat hist_equalized_image;
equalizeHist(image, hist_equalized_image); 
//Define names of windows
String windowNameOfOriginalImage = "Original Image"; 
String windowNameOfHistogramEqualized = "Histogram Equalized Image";

// Create windows with the above names
namedWindow(windowNameOfOriginalImage, WINDOW_NORMAL);
namedWindow(windowNameOfHistogramEqualized, WINDOW_NORMAL);

// Show images inside the created windows.
imshow(windowNameOfOriginalImage, image);
imshow(windowNameOfHistogramEqualized, hist_equalized_image);
waitKey(0); // Wait for any keystroke in the window

destroyAllWindows(); //destroy all open windows

return 0;

上述函数将BGR色彩空间中的图像转换为灰度色彩空间。

请注意,加载图像的色彩空间是 BGR,而不是 RGB。(即 - 通道按蓝色、绿色和红色排序。 上述函数均衡灰度*图像*的直方图,并将输出存储在*hist_equalized_image中。*

上面的代码段将创建窗口并在其中显示图像。当窗口是通过标志WINDOW_NORMAL创建的,因此可以自由调整它们的大小。

程序将等待,直到按下任何键。按下一个键后,所有创建的窗口将被销毁,程序将退出。

使用OpenCV对彩色图像进行直方图均衡

代码语言:javascript复制
/Uncomment the following line if you are compiling this code in Visual Studio
//#include "stdafx.h"

#include <QCoreApplication>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main()
{
    // Read the image file
    Mat image = imread("D:/Gerry/project/opencvproj/singleandslot/OpenCV-2/ImageAndVideoHandle/resources/fly-agaric1.jpg");

    // Check for failure
    if (image.empty())
    {
        cout << "Could not open or find the image" << endl;
        cin.get(); //wait for any key press
        return -1;
    }

    //把图像从BGR色彩空间转换为YCrCb色彩空间
    // 直方图均衡只能处理强度信息,不能处理带颜色的通道
    Mat hist_equalized_image;
    cvtColor(image, hist_equalized_image, COLOR_BGR2YCrCb);

    //把转换好的色彩空间对象分割处对应通道分别是Y,Cr,Cb并把结果存储到vector集合中
    vector<Mat> vec_channels;
    split(hist_equalized_image, vec_channels);

    //把拆分出来的Y通道进行直方图均衡
    equalizeHist(vec_channels[0], vec_channels[0]);

    //合并处理好的3通道数据合并到YCrCb的色彩空间中
    merge(vec_channels, hist_equalized_image);

    //把YCrCb的色彩空间图像转换到BGR颜色空间
    cvtColor(hist_equalized_image, hist_equalized_image, COLOR_YCrCb2BGR);

    //Define the names of windows
    String windowNameOfOriginalImage = "Original Image";
    String windowNameOfHistogramEqualized = "Histogram Equalized Color Image";

    // Create windows with the above names
    namedWindow(windowNameOfOriginalImage, WINDOW_NORMAL);
    namedWindow(windowNameOfHistogramEqualized, WINDOW_NORMAL);

    // Show images inside the created windows.
    imshow(windowNameOfOriginalImage, image);
    imshow(windowNameOfHistogramEqualized, hist_equalized_image);


    waitKey(0); // Wait for any keystroke in one of the windows

    destroyAllWindows(); //Destroy all open windows

    return 0;
}

彩色图像的直方图均衡彩色图像的直方图均衡

OpenCV 在 BGR 色彩空间中加载彩色图像。使用此颜色空间,不可能在不影响颜色信息的情况下均衡直方图,因为所有 3 个通道都包含颜色信息。因此,您必须将BGR图像转换为YCrCb之类的色彩空间。在 YCrCb 色彩空间中,图像的 Y 通道仅包含强度信息,而 Cr 和 Cb 通道包含图像的所有颜色信息。因此,只应处理Y通道以获得直方图均衡图像,而不改变任何颜色信息。处理完成后,在调用 imshow() 函数之前,应将 YCrCb 图像转换回 BGR 色彩空间。

代码语言:javascript复制
// Read the image file
Mat image = imread("D:/My OpenCV Website/fly-agaric.jpg");

// Check for failure
if (image.empty())
{
    cout << "Could not open or find the image" << endl;
    cin.get(); //Wait for any key press
    return -1;
}

上面的代码段从指定的文件加载图像。如果加载图像失败,程序将退出。

代码语言:javascript复制
//Convert the image from BGR to YCrCb color space
Mat hist_equalized_image;
cvtColor(image, hist_equalized_image, COLOR_BGR2YCrCb);

使用 OpenCV 对视频进行直方图均衡

代码语言:javascript复制
//Uncomment the following line if you are compiling this code in Visual Studio
//#include "stdafx.h"

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main(int argc, char* argv[])
{
    //Open the video file for reading
    VideoCapture cap("D:/My OpenCV Website/A Herd of Deer Running.mp4");

    // if not success, exit the program
    if (cap.isOpened() == false)
    {
        cout << "Cannot open the video file" << endl;
        cin.get(); //wait for any key press
        return -1;
    }

    //Define the names of windows
    String windowNameOfOriginalImage = "Original Video";
    String windowNameOfHistogramEqualized = "Histogram Equalized Video";

    // Create windows with the above names
    namedWindow(windowNameOfOriginalImage, WINDOW_NORMAL);
    namedWindow(windowNameOfHistogramEqualized, WINDOW_NORMAL);

    while (true)
    {
        Mat frame;
        bool bSuccess = cap.read(frame); // Read a new frame from the video file 

         //Breaking the while loop at the end of the video
        if (bSuccess == false)
        {
            cout << "Found the end of the video" << endl;
            break;
        }

        //Convert the frame from BGR to YCrCb color space
        Mat hist_equalized_image;
        cvtColor(frame, hist_equalized_image, COLOR_BGR2YCrCb);

        //Split the image into 3 channels; Y, Cr and Cb channels respectively and store it in a std::vector
        vector<Mat> vec_channels;
        split(hist_equalized_image, vec_channels);

        //Equalize the histogram of the Y channel 
        equalizeHist(vec_channels[0], vec_channels[0]);

        //Merge 3 channels in the std::vector to form the color image in YCrCB color space. 
        merge(vec_channels, hist_equalized_image);

        //Convert the histogram equalized image from YCrCb to BGR color space again
        cvtColor(hist_equalized_image, hist_equalized_image, COLOR_YCrCb2BGR);

        //show frames in the created windows
        imshow(windowNameOfOriginalImage, frame);
        imshow(windowNameOfHistogramEqualized, hist_equalized_image);

        //Wait for 10 ms until any key is pressed.  
        //If the 'Esc' key is pressed, break the while loop.
        //If the any other key is pressed, continue the loop 
        //If any key is not pressed within 10 ms, continue the loop
        if (waitKey(5) == 27)
        {
            cout << "Esc key is pressed by the user. Stopping the video" << endl;
            break;
        }
    }

    destroyAllWindows(); //Destroy all opened windows

    return 0;

}

0 人点赞