参考:【OpenCV学习笔记】之直方图(Histogram)_点滴成海~的博客-CSDN博客_histogram
定义:
在统计学中,直方图是一种对数据分布情况的图形表示,是一种二维统计图表,他的两个坐标分别是统计样本(图像、视频帧)和样本的某种属性(亮度,像素值,梯度,方向,色彩等等任何特征)。
(一)首先学习直方图的均衡化:
C++ void equalizeHist(InputArray src, OutputArray dst)
//第一个参数,源图像,需为8位单通道图像
//第二个参数,输出图像,尺寸、类型和源图像一致
注意:直方图均衡化就是通过拉伸像素强度分布范围来增强图像对比度的一种方法。
/*
* 001 对于灰白图像的均衡化
*
这一段代码实现的是对于图像1维数读取以及
对于黑白图像的效果进行增强,即均衡化
注意:为了方便,我将本来存彩图的mat类型的东西变成了output
*/
#include
#include
#include
using namespace std;
using namespace cv;
int main()
{
int ChannelNumber;
Mat OriginImage = imread("0003.jpg");
Mat OutPutImage = Mat(OriginImage.size(), OriginImage.type());
if (!OriginImage.data)
{
cout << "ERROR" << endl;
return -1;
}
cvtColor(OriginImage, OutPutImage, COLOR_BGR2GRAY);
imshow("origin", OutPutImage);
ChannelNumber = OutPutImage.channels();
cout << "这个图像的通道数为" << ChannelNumber << endl;
equalizeHist(OutPutImage, OriginImage);
imshow("AFTER", OriginImage);
waitKey(0);
}
接下来就是实验三通道的彩色图像了:
注意:这里的三个通道使用split分别对vector构建的mat类型处理,然后令BGR分别设置为mat类型,使用浅拷贝的方式,将分离出来的三个通道拷贝(因而对于RGBMat类型的操作其实也就是对于
三个通道的数组进行修改。
/*
* 002彩色图像的均衡化
* 主要是运用split函数分离图像,存储入channels的数组里面
*/
#include
#include
using namespace std;
using namespace cv;
int main()
{
Mat Origin = imread("0003.jpg");
if (!Origin.data)
{
cout << "error" << endl;
return -1;
}
Mat Output_1 = Mat(Origin.size(), Origin.type());
Mat Course_1 = Mat(Origin.size(), Origin.type());
imshow("00000",Origin);
std::vector channels;
split(Origin, channels);
Mat G, B, R;
B = channels.at(0);
G = channels.at(1);
R = channels.at(2); //因为opencv是按照BGR存储的
equalizeHist(B, B);
equalizeHist(G, G);
equalizeHist(R, R);
merge(channels, Output_1);
imshow("output", Output_1);
waitKey(0);
}
(二)直方图的计算与绘制:
C++ Void calcHist(
const Mat* images,//输入图像指针
int images,// 图像数目
const int* channels,// 通道数
InputArray mask,// 输入mask,可选,不用
OutputArray hist,//输出的直方图数据
int dims,// 维数
const int* histsize,// 直方图级数
const float* ranges,// 值域范围
bool uniform,// true by default
bool accumulate)// false by defaut
//寻找最值函数
C++ void minMaxLoc(InputArray src, double* minVal, double* maxVal=0,
Point* minLoc=0,Point* maxLoc=0,InputArray mask=noArray())
//第一个参数:输入单通道阵列
//第二个参数:返回最小值的指针,若无需返回,此值置为NULL
//第三个参数:返回最大值的指针,若无需返回,此值置为NULL
//第四个参数:返回最小位置的指针(二维情况下),若无需返回,此值置为NULL
//第五个参数:返回最大位置的指针(二维情况下),若无需返回,此值置为NULL
//第六个参数:用于选择子阵列的可选掩膜
//#include
//#include
//#include
//
//using namespace cv;
//using namespace std;
//
//const char* output = "image";
//
//int main(int argc, char* argv)
//{
// Mat src, dst, dst1;
// src = imread("0003.jpg");
// if (!src.data)
// {
// printf("could not load image...\n");
// return -1;
// }
// char input[] = "input image";
// namedWindow(input, WINDOW_FREERATIO);
// namedWindow(output,WINDOW_FREERATIO);
// imshow(input, src);
//
// //步骤一:分通道显示
// vectorbgr_planes;
// split(src, bgr_planes);
// //split(// 把多通道图像分为多个单通道图像 const Mat &src, //输入图像 Mat* mvbegin)// 输出的通道图像数组
//
// //步骤二:计算直方图
// int histsize = 256;
// float range[] = { 0,256 };
// const float* histRanges = { range };
// Mat b_hist, g_hist, r_hist;
// calcHist(&bgr_planes[0], 1, 0, Mat(), b_hist, 1, &histsize, &histRanges, true, false);
// calcHist(&bgr_planes[1], 1, 0, Mat(), g_hist, 1, &histsize, &histRanges, true, false);
// calcHist(&bgr_planes[2], 1, 0, Mat(), r_hist, 1, &histsize, &histRanges, true, false);
//
//
// //归一化
// int hist_h = 400;//直方图的图像的高
// int hist_w = 512; //直方图的图像的宽
// int bin_w = hist_w / histsize;//直方图的等级
// Mat histImage(hist_w, hist_h, CV_8UC3, Scalar(0, 0, 0));//绘制直方图显示的图像
// normalize(b_hist, b_hist, 0, hist_h, NORM_MINMAX, -1, Mat());//归一化
// normalize(g_hist, g_hist, 0, hist_h, NORM_MINMAX, -1, Mat());
// normalize(r_hist, r_hist, 0, hist_h, NORM_MINMAX, -1, Mat());
//
// //步骤三:绘制直方图(render histogram chart)
// for (int i = 1; i < histsize; i++)
// {
// //绘制蓝色分量直方图
// line(histImage, Point((i - 1) * bin_w, hist_h - cvRound(b_hist.at(i - 1))),
// Point((i)*bin_w, hist_h - cvRound(b_hist.at(i))), Scalar(255, 0, 0), 2, LINE_AA);
// //绘制绿色分量直方图
// line(histImage, Point((i - 1) * bin_w, hist_h - cvRound(g_hist.at(i - 1))),
// Point((i)*bin_w, hist_h - cvRound(g_hist.at(i))), Scalar(0, 255, 0), 2, LINE_AA);
// //绘制红色分量直方图
// line(histImage, Point((i - 1) * bin_w, hist_h - cvRound(r_hist.at(i - 1))),
// Point((i)*bin_w, hist_h - cvRound(r_hist.at(i))), Scalar(0, 0, 255), 2, LINE_AA);
// }
// imshow(output, histImage);
// waitKey(0);
// return 0;
//}
//
//