先均衡化一下图像亮度看看情况,方法:由BGR-->YCrCb--->均衡化Y--->BGR
代码如下:
#include
#include
#include "opencv2/core.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
const char* keys =
{
"{help h usage ? | | print this message}"
"{@image | | Image to process}"
};
cv::Mat equalize_y_channel( cv::Mat &src_img )
{
cv::Mat result;
cv::Mat ycrcb;
cv::cvtColor( src_img, ycrcb, cv::COLOR_BGR2YCrCb);
std::vector
cv::split( ycrcb, channels );
//only equalize y
cv::equalizeHist( channels[0], channels[0] );
cv::merge( channels, ycrcb );
cv::cvtColor( ycrcb, result, cv::COLOR_YCrCb2BGR );
// imshow( "Equalize", result );
return result;
}
cv::Mat show_histograms( cv::Mat &src_img )
{
//split image to 3 channels
std::vector
cv::split( src_img, bgr );
//create 256 subinterval
//the number of possibles values
int numbins = 256;
//set the range for BGR(0-256)
float range[] = { 0, 256};
const float* histRange = { range };
cv::Mat b_hist, g_hist, r_hist;
cv::calcHist( &bgr[0], 1, 0, cv::Mat(), b_hist, 1, &numbins, &histRange );
cv::calcHist( &bgr[1], 1, 0, cv::Mat(), g_hist, 1, &numbins, &histRange );
cv::calcHist( &bgr[2], 1, 0, cv::Mat(), r_hist, 1, &numbins, &histRange );
//draw histogram
//draw lines for each channels
int width = 512;
int height = 300;
// Create image with gray base
cv::Mat histImage( height, width, CV_8UC3, cv::Scalar(20, 20, 20) );
// Normalize the histograms to height of image
cv::normalize(b_hist, b_hist, 0, height, cv::NORM_MINMAX );
cv::normalize(g_hist, g_hist, 0, height, cv::NORM_MINMAX );
cv::normalize(r_hist, r_hist, 0, height, cv::NORM_MINMAX );
int binStep= cvRound((float)width/(float)numbins);
for( int i=1; i< numbins; i++)
{
cv::line( histImage,
cv::Point( binStep*(i-1), height-cvRound(b_hist.at
cv::Point( binStep*(i), height-cvRound(b_hist.at
cv::Scalar(255,0,0)
);
line( histImage,
cv::Point( binStep*(i-1), height-cvRound(g_hist.at
cv::Point( binStep*(i), height-cvRound(g_hist.at
cv::Scalar(0,255,0)
);
line( histImage,
cv::Point( binStep*(i-1), height-cvRound(r_hist.at
cv::Point( binStep*(i), height-cvRound(r_hist.at
cv::Scalar(0,0,255)
);
}
// cv::imshow("Histogram", histImage);
return histImage;
}
int main( int argc, const char** argv )
{
cv::CommandLineParser parser(argc, argv, keys);
parser.about("Chapter 4. PhotoTool v1.0.0");
//If requires help show
if (parser.has("help")){
parser.printMessage();
return 0;
}
cv::String imgFile= parser.get
// Check if params are correctly parsed in his variables
if (!parser.check()){
parser.printErrors();
return 0;
}
// Load image to process
cv::Mat img= cv::imread(imgFile);
if( !img.data ){
std::cerr << "Can't read image" << std::endl;
return -1;
}
// Create window
cv::namedWindow("Input");
cv::Mat hist_img1 = show_histograms(img);
cv::Mat equa_img1 = equalize_y_channel(img);
cv::Mat hist_img2 = show_histograms(equa_img1);
// Show image
cv::imshow("Input", img);
cv::imshow("hist_img1", hist_img1);
cv::imshow("equa_img1", equa_img1);
cv::imshow("hist_img2", hist_img2);
cv::waitKey(0);
return 0;
}
结果如下:
可见只均衡化亮度对BGR图像来说没什么意义;下面分别均衡化BGR通道;
代码如下:
/*
* color_equalizehist.cpp
*
* Created on: May 20, 2018
* Author: cui
*/
#include
#include
#include
#include
using namespace cv;
using namespace std;
void histogram_calculation( const Mat &Image, Mat &histoImage )
{
// Create the histogram for 256 bins
// The number of possibles values
int histSize= 255;
/// Set the ranges ( for B,G,R) )
float range[] = { 0, 256 } ;
const float* histRange = { range };
bool uniform = true;
bool accumulate = false;
Mat b_hist, g_hist, r_hist;
vector
split( Image, bgr_planes );
calcHist( &bgr_planes[0], 1, 0, Mat(), b_hist, 1, &histSize,
&histRange, uniform, accumulate );
calcHist( &bgr_planes[1], 1, 0, Mat(), g_hist, 1, &histSize,
&histRange, uniform, accumulate );
calcHist( &bgr_planes[2], 1, 0, Mat(), r_hist, 1, &histSize,
&histRange, uniform, accumulate );
// Draw the histogram
// We go to draw lines for each channel
int hist_w= 512;
int hist_h= 400;
int bin_w= cvRound((float)hist_w/(float)histSize);
// Create image with gray base
Mat histImage( hist_h, hist_w, CV_8UC3, Scalar(0,0,0) );
// Normalize the histograms to height of image
normalize(b_hist, b_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat() );
normalize(g_hist, g_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat() );
normalize(r_hist, r_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat() );
for( int i=1; i< histSize; i++){
line( histImage,
Point( bin_w*(i-1), hist_h-cvRound(b_hist.at
Point( bin_w*(i), hist_h-cvRound(b_hist.at
Scalar(255,0,0), 2, 8, 0
);
line( histImage,
Point( bin_w*(i-1), hist_h-cvRound(g_hist.at
Point( bin_w*(i), hist_h-cvRound(g_hist.at
Scalar(0,255,0), 2, 8, 0
);
line( histImage,
Point( bin_w*(i-1), hist_h-cvRound(r_hist.at
Point( bin_w*(i), hist_h-cvRound(r_hist.at
Scalar(0,0,255), 2, 8, 0
);
}
// imshow("Histogram", histImage);
histoImage = histImage;
}
int main( int argc, char *argv[] )
{
Mat src, imageq;
Mat histImage;
//get src image
src = imread( "lena.jpg" );
if( src.empty() ){
fprintf( stderr, "Error image, can't load\n" );
exit(-1);
}
vector
split( src, bgr );
Size src_s = src.size();
cout << "fruits.jpg rows: " << src.rows << endl;
cout << "fruits.jpg cols: " << src.cols << endl;
cout << "fruits.jpg size.width: " << src_s.width << endl;
cout << "fruits.jpg size.height: " << src_s.height << endl;
imshow( "Source image", src );
cout << "Source image show end" << endl;
//calculate src channel equalize
histogram_calculation( src, histImage);
cout << "histImage rows: " << histImage.rows << endl;
cout << "histImage cols: " << histImage.cols << endl;
imshow( "Color Image Histogram", histImage );
//equalize image
equalizeHist( bgr[0], bgr[0] );
equalizeHist( bgr[1], bgr[1] );
equalizeHist( bgr[2], bgr[2] );
merge( bgr, imageq);
imshow( "Equalized image", imageq );
//calculate every channel histogram
histogram_calculation( imageq, histImage );
imshow( "Equalized color image histogram", histImage );
waitKey(0);
return 0;
}
效果如下:
图像更艳丽了。。。。。。