#include <opencv2\imgproc\imgproc.hpp>
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\core\core.hpp>
#include <iostream>
using namespace cv;
using namespace std;
Mat calchistcontrol(vector<Mat> rgb);
void draw(Mat hist, int histSize, Mat histImage, int bin_w, int hist_h, int rgb);
Mat getHistImg(const MatND& hist)
{
double maxVal = 0;
double minVal = 0;
//找到直方图中的最大值和最小值
minMaxLoc(hist, &minVal, &maxVal, 0, 0);
int histSize = hist.rows;
Mat histImg(histSize, histSize, CV_8U, Scalar(255));
// 设置最大峰值为图像高度的90%
int hpt = static_cast<int>(0.9*histSize);
for (int h = 0; h<histSize; h++)
{
float binVal = hist.at<float>(h);
int intensity = static_cast<int>(binVal*hpt / maxVal);
line(histImg, Point(h, histSize), Point(h, histSize - intensity), Scalar::all(0));
}
return histImg;
}
void main()
{
Mat I;
I = imread("D:\\ymrf\\enhance\\paper\\test_img\\flower.jpg");//ddd.png
namedWindow("原始图像", 0);
imshow("原始图像", I);
int height = I.rows;
int width = I.cols;
Mat I_gray;
cvtColor(I, I_gray, CV_BGR2GRAY);
const int channels[3] = { 0,1,2 };
const int channelsB[1] = { 0 };
const int channelsG[1] = { 1 };
const int channelsR[1] = { 2 };
const int histSizeI[3] = { 256,256,256};
const int histSize[1] = { 256};
float hranges[2] = { 0, 255 };
const float* ranges[3] = { hranges};
const float* rangesI[3] = { hranges, hranges, hranges };
//MatND hist;
//calcHist(&I, 1, channels, Mat(), hist, 1, histSizeI, ranges);
//imshow("caise", getHistImg(hist));
//MatND histgray;
//calcHist(&I_gray, 1, channelsB, Mat(), histgray, 1, histSize, ranges);
//imshow("gray", getHistImg(histgray));
//MatND histB;
//calcHist(&I, 1, channelsB, Mat(), histB, 1, histSize, ranges);
//imshow("B", getHistImg(histB));
//MatND histG;
//calcHist(&I, 1, channelsG, Mat(), histG, 1, histSize, ranges);
//imshow("G", getHistImg(histG));
//MatND histR;
//calcHist(&I, 1, channelsR, Mat(), histR, 1, histSize, ranges);
//imshow("R", getHistImg(histR));
/// 分割成3个单通道图像 ( R, G 和 B )
Mat dst, rgb_merge, histImage, histImage1;
vector<Mat> rgb_planes;
split(I, rgb_planes);
///直方图计算
histImage = calchistcontrol(rgb_planes);
///三个通道直方图均衡化
vector<Mat> rgb_planes1;
split(I, rgb_planes1);
equalizeHist(rgb_planes1[0], rgb_planes1[0]);
equalizeHist(rgb_planes1[1], rgb_planes1[1]);
equalizeHist(rgb_planes1[2], rgb_planes1[2]);
///三个通道直方图均衡化后直方图计算
histImage1 = calchistcontrol(rgb_planes1);
///合并三通道
merge(rgb_planes1, rgb_merge);
/// 显示直方图
namedWindow("calcHist Demo", 0);
namedWindow("calcHist Demo1", 0);
namedWindow("rgb_merge" , 0);
imshow("calcHist Demo", histImage);
imshow("calcHist Demo1", histImage1);
imshow("rgb_merge", rgb_merge);
waitKey(0);
}
Mat calchistcontrol(vector<Mat> rgb)
{
vector<Mat> rgb_planes;
rgb_planes = rgb;
/// 设定bin数目
int histSize = 255;
/// 设定取值范围 ( R,G,B) )
float range[] = { 0, 255 };
const float* histRange = { range };
bool uniform = true; bool accumulate = false;
Mat r_hist, g_hist, b_hist;
/// 计算直方图:
calcHist(&rgb_planes[0], 1, 0, Mat(), r_hist, 1, &histSize, &histRange, uniform, accumulate);
calcHist(&rgb_planes[1], 1, 0, Mat(), g_hist, 1, &histSize, &histRange, uniform, accumulate);
calcHist(&rgb_planes[2], 1, 0, Mat(), b_hist, 1, &histSize, &histRange, uniform, accumulate);
// 创建直方图画布
int hist_w = 400; int hist_h = 400;
int bin_w = cvRound((double)hist_w / histSize);
Mat histImage(hist_w, hist_h, CV_8UC3, Scalar(0, 0, 0));
/// 将直方图归一化到范围 [ 0, histImage.rows ]
normalize(r_hist, r_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat());
normalize(g_hist, g_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat());
normalize(b_hist, b_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat());
/// 在直方图画布上画出直方图
draw(r_hist, histSize, histImage, bin_w, hist_h, 1);
draw(g_hist, histSize, histImage, bin_w, hist_h, 2);
draw(b_hist, histSize, histImage, bin_w, hist_h, 3);
return histImage;
}
void draw(Mat hist, int histSize, Mat histImage, int bin_w, int hist_h, int rgb)
{
Scalar a;
switch (rgb)
{
case 1: a = Scalar(0, 0, 255); break;
case 2: a = Scalar(0, 255, 0); break;
case 3: a = Scalar(255, 0, 0); break;
}
int flag = 1, first;
for (int i = 0; i < histSize; i++)
{
if (flag == 1)
{
if (cvRound(hist.at<float>(i) != 0))
{
flag = 2;
first = i;
}
else
{
i++;
}
}
else
{
if (cvRound(hist.at<float>(i) != 0))
{
line(histImage, Point(bin_w*(first), hist_h - cvRound(hist.at<float>(first))),
Point(bin_w*(i), hist_h - cvRound(hist.at<float>(i))),
a, 2, 8, 0);
first = i;
}
else
{
i++;
}
}
}
}
直方图均衡化程序 c++
最新推荐文章于 2023-08-16 22:53:57 发布