1:直方图绘制:
图像直方阁就是统计图像中每个灰度值的个数,之后将图像灰度值作为横轴,以灰度值个数或者灰度值所占比率作为纵轴绘制的统计图.通过直方图
看出图像中哪些灰度值数
目较多,哪些较少,可以通过一定的方法将灰度值较为集中的区域映射到较为稀疏的区域,从而使图像在像素灰度值上的分布更加符合期望状态.在通常情况下 像素灰度值代表亮暗程度,因此通过图像直方图 可以分析图像亮暗对比度
并调整图像的亮暗程度.
直方图计算函数见代码,示例为绘制一个三通道图像的直方图,并将纵轴进行了归一化显示。
void visionagin::Histdrawing(Mat& img)
{
vector<Mat>temp;
split(img, temp);
Mat b_hist, g_hist, r_hist;//每个通道直方图计算后的结果
const int channels[] = { 0 };//图像通道序号index
const int histsize[] = { 256 };//
float wranges[] = { 0,255 };
const float* ranges[] = { wranges };
/*
void calcHist(const Mat* images, int nimages, const int* channels, InputArray mask, OutputArray hist, int dims,
const int* histSize, const float** ranges, bool uniform=true, bool accumulate=false )
const Mat* images:输入图像
int nimages:输入图像的个数
const int* channels:需要统计直方图的第几通道
InputArray mask:掩膜,,计算掩膜内的直方图 ...Mat()
OutputArray hist:输出的直方图数组
int dims:需要统计直方图通道的个数
const int* histSize:指的是直方图分成多少个区间,就是 bin的个数
const float** ranges: 统计像素值得区间
bool uniform=true::是否对得到的直方图数组进行归一化处理
bool accumulate=false:在多个图像时,是否累计计算像素值得个
*/
calcHist(&temp[0], 1, channels,Mat(), b_hist, 1, histsize, ranges, true, false);
calcHist(&temp[1], 1, channels, Mat(), g_hist, 1, histsize, ranges, true, false);
calcHist(&temp[2], 1, channels, Mat(), r_hist, 1, histsize, ranges, true, false);
int width = 512;
int height = 360;
Mat showimage = Mat::zeros(Size(width, height), CV_8UC3);
int bins =cvRound(width / histsize[0]);//计算绘制的横坐标的间隔
//normalize()原型 : rc 输入数组;dst 输出数组,数组的大小和原数组一致;alpha 1, 用来规范值,2.规范范围,并且是下限;
// beta 只用来规范范围并且是上限;为0时则为值归一化,否则为范围归一化
//norm_type 归一化选择的数学公式类型;dtype 当为负,输出在大小深度通道数都等于输入,当为正,输出只在深度与输如不同,不同的地方游dtype决定;
//mark 掩码。选择感兴趣区域,选定后只能对该区域进行操作。
normalize(b_hist, b_hist, 0, showimage.rows, NORM_MINMAX,-1,Mat());
normalize(g_hist, g_hist, 0, showimage.rows, NORM_MINMAX, -1, Mat());
normalize(r_hist, r_hist, 0, showimage.rows, NORM_MINMAX, -1, Mat());
for (int i = 1; i < histsize[0]; ++i)
{
line(showimage, Point(bins * (i - 1), height - cvRound(b_hist.at<float>(i - 1))), Point(bins * i, height - cvRound(b_hist.at<float>(i))),
Scalar(255, 0, 0), 1, LINE_AA, 0);//y坐标为 图像高度减hist结果在x处的值的结果
line(showimage, Point(bins * (i - 1), height - cvRound(g_hist.at<float>(i - 1))), Point(bins * i, height - cvRound(g_hist.at<float>(i))),
Scalar( 0,255, 0), 1, LINE_AA, 0);
line(showimage, Point(bins * (i - 1), height - cvRound(r_hist.at<float>(i - 1))), Point(bins * i, height - cvRound(r_hist.at<float>(i))),
Scalar( 0, 0,255), 1, LINE_AA, 0);
}
imshow("直方图", showimage);
}
2:直方图比较:
由于图像的直方图表示图像像素灰度值的统计特性,
因此可以通过两幅图像的直方图特性比较
两幅图像的相似程度.从一定程度上来讲,虽然两幅图像的直方图分布相似不代表两幅图像相似,
但是两幅图像相似则两幅图像的直方图分布一定相似.例如
在通过插值对图像进行缩放后,虽然
图像的直方图不会与之前完全一致,但是两者之间一定具有很高的相似性,因而可以通过比较两幅
图像的直方图分布相似性对图像进行初步的筛选与识别.
![](https://i-blog.csdnimg.cn/blog_migrate/7fc68ef1b21e460988c5cd47554afcab.png)
在上述代码下,将原图像缩小一半尺寸后再计算其直方图,以及和另外一副完全无关的图的直方图进行比较:根据选取比较的方法不同,结果的值的大小代表相似性或大或小。
原图image:
缩小后的image1
第三幅无相关的图: