/* 直方图均衡化 */ #include<opencv2\opencv.hpp> #include<iostream> using namespace cv; using namespace std; void histogramcalculation(const Mat &img, Mat &histoImage); //得到直方图 int main() { Mat img_org, img_tem; Mat histImage,histImage2; img_org = imread("D://图片//5.jpg"); if (img_org.empty()) { cout << "图片加载失败!" << endl; return -1; } imshow("show_org", img_org); //显示原始图片 vector<Mat> bgr_channels; split(img_org, bgr_channels); //把每个通道的信息分离出来 histogramcalculation(img_org, histImage); //调用函数得到直方图 imshow("histImage_show", histImage); equalizeHist(bgr_channels[0], bgr_channels[0]); equalizeHist(bgr_channels[1], bgr_channels[1]); equalizeHist(bgr_channels[2], bgr_channels[2]); //直方图均衡化,每个通道分别均衡 merge(bgr_channels, img_tem); //把处理完的通道信息合并到新的图像中去 imshow("result_show", img_tem); //显示均衡化后的图像 histogramcalculation(img_tem, histImage2); //再次调用画直方图函数,显示均衡处理后的图像的直方图 imshow("histImage_result", histImage2); waitKey(0); return 0; } void histogramcalculation(const Mat & img, Mat & histoImage) //画直方图,后者为输出图像,引用改变其值 { int histSize = 255; float range[] = { 0,256 }; //每个像素值在0~255间 const float* histRange = { range }; bool uniform = true; bool accumulate = false; Mat b_hist, g_hist, r_hist; vector<Mat> bgr_channels; split(img, bgr_channels); //得到每个通道的信息 calcHist(&bgr_channels[0], 1, 0, Mat(), b_hist, 1, &histSize, &histRange, uniform, accumulate); //计算各直方图 calcHist(&bgr_channels[1], 1, 0, Mat(), g_hist, 1, &histSize, &histRange, uniform, accumulate); calcHist(&bgr_channels[2], 1, 0, Mat(), r_hist, 1, &histSize, &histRange, uniform, accumulate); int hist_w = 600, hist_h = 400; //直方图的整体大小 int bin_w = cvRound((double)hist_w / histSize); //根据图的宽度均分得到每个bin的宽度 Mat histImage(hist_h, hist_w, CV_8UC3, Scalar(120, 55, 133)); //组合整合所有的直方图显示的最后结果图片 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<float>(i - 1))), Point(bin_w*i, hist_h - cvRound(b_hist.at<float>(i))), Scalar(255, 0, 0), 2); line(histImage, Point(bin_w*(i - 1), hist_h - cvRound(g_hist.at<float>(i - 1))), Point(bin_w*i, hist_h - cvRound(g_hist.at<float>(i))), Scalar(0, 255, 0), 2); line(histImage, Point(bin_w*(i - 1), hist_h - cvRound(r_hist.at<float>(i - 1))), Point(bin_w*i, hist_h - cvRound(r_hist.at<float>(i))), Scalar(0, 0, 255), 2); } histoImage = histImage; //赋值 }
运行结果:
也可以分开显示:
/* 分开显示直方图 */ #include<opencv2\opencv.hpp> #include<iostream> using namespace cv; using namespace std; int main() { Mat img_org = imread("D://图片//5.jpg"); Mat b_hist, g_hist, r_hist; int histSize = 255; float range[] = { 0,256 }; const float* histRange = { range }; if (img_org.empty()) { cout << "图片加载失败!" << endl; return -1; } vector<Mat> bgr_channels; split(img_org, bgr_channels); int hist_w = 600, hist_h = 400; int bin_w = cvRound((double)hist_w / histSize); Mat B_hist(hist_h, hist_w, CV_8UC3, Scalar(33, 0, 122)); Mat G_hist(hist_h, hist_w, CV_8UC3, Scalar(33, 0, 122)); Mat R_hist(hist_h, hist_w, CV_8UC3, Scalar(33, 0, 122)); calcHist(&bgr_channels[0], 1, 0, Mat(), b_hist, 1, &histSize, &histRange); calcHist(&bgr_channels[1], 1, 0, Mat(), g_hist, 1, &histSize, &histRange); calcHist(&bgr_channels[2], 1, 0, Mat(), r_hist, 1, &histSize, &histRange); normalize(b_hist, b_hist, 0, B_hist.rows, NORM_MINMAX, -1, Mat()); normalize(g_hist, g_hist, 0, G_hist.rows, NORM_MINMAX, -1, Mat()); normalize(r_hist, r_hist, 0, R_hist.rows, NORM_MINMAX, -1, Mat()); for (int i = 1; i < histSize; i++) { line(B_hist, Point(bin_w*(i - 1), hist_h - cvRound(b_hist.at<float>(i - 1))), Point(bin_w*i, hist_h - cvRound(b_hist.at<float>(i))), Scalar(255, 0, 0), 2); line(G_hist, Point(bin_w*(i - 1), hist_h - cvRound(g_hist.at<float>(i - 1))), Point(bin_w*(i), hist_h - cvRound(g_hist.at<float>(i))), Scalar(0, 255, 0), 2); line(R_hist, Point(bin_w*(i - 1), hist_h - cvRound(r_hist.at<float>(i - 1))), Point(bin_w*(i), hist_h - cvRound(r_hist.at<float>(i))), Scalar(0, 0, 255), 2); } imshow("b_hist", B_hist); imshow("g_hist", G_hist); imshow("r_hist", R_hist); waitKey(0); destroyAllWindows; return 0; }