图像的直方图是像素强度分布的图形表示。它提供了像素值集中位置以及是否存在异常偏差的估计值。
使用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;
}