Opencv学习笔记(8)——直方图统计
本章我将为大家介绍直方图的相关知识,相关内容分别有:直方图均衡化、直方图计算、直方图比较,直方图反向投射。
一.直方图均衡化
1.相关理论
1.什么是直方图(Histogram)?
图像直方图,是指对整个图像像在灰度范围内的像素值(0~255)统计出现频率次数,据此生成的直方图,称为图像直方图-直方图。直方图反映了图像灰度的分布情况。是图像的统计学特征。
2.直方图均衡化
是一种提高图像对比度的方法,拉伸图像灰度值范围。
如何实现,通过上一课中的remap我们知道可以将图像灰度分布从一个分布映射到另外一个分布,然后在得到映射后的像素值即可。
2.相关API应用
cv::equalizeHist
equalizeHist(
InputArray src,//输入图像,必须是8-bit的单通道图像
OutputArray dst// 输出结果
)
3.程序示例
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace cv;
using namespace std;
Mat src, dst, map_x, map_y;
const char* OUTPUT_TITLE = "equalizeHist demo";
int main(int argc, char** argv) {
src = imread("E:/photoss/dog1.jpeg");
if (!src.data) {
printf("Could not load image...\n");
return 1;
}
char input_win[] = "input image";
namedWindow(input_win, CV_WINDOW_AUTOSIZE);
namedWindow(OUTPUT_TITLE, CV_WINDOW_AUTOSIZE);
cvtColor(src, src, CV_BGR2GRAY);
imshow(input_win, src);
equalizeHist(src, dst);//直方图均衡化
imshow(OUTPUT_TITLE, dst);
waitKey(0);
return 0;
}
运行效果:
二.直方图计算
1.相关原理
1.直方图概念
上述直方图概念是基于图像像素值,其实对图像梯度、每个像素的角度、等一切图像的属性值,我们都可以建立直方图。这个才是直方图的概念真正意义,不过是基于图像像素灰度直方图是最常见的。
直方图最常见的几个属性:
- dims 表示维度,对灰度图像来说只有一个通道值dims=1
- bins 表示在维度中子区域大小划分,bins=256,划分为256个级别
- range 表示值得范围,灰度值范围为[0~255]之间
2.相关API说明
1.cv::split
split(// 把多通道图像分为多个单通道图像
const Mat &src, //输入图像
Mat* mvbegin)// 输出的通道图像数组
2.cv::calcHist
calcHist(
const Mat* images,//输入图像指针
int images,// 图像数目
const int* channels,// 通道数
InputArray mask,// 输入mask,可选,不用则输入Mat()
OutputArray hist,//输出的直方图数据
int dims,// 维数
const int* histsize,// 直方图级数
const float* ranges,// 值域范围
bool uniform,// true by default,是否归一化
bool accumulate// false by defaut,是否累计各通道值
)
3. 程序示例
#include<iostream>
#include<math.h>
using namespace cv;
using namespace std;
int main(int argc, char** argv) {
Mat src, dst, map_x, map_y;
src = imread("E:/photoss/dog1.jpeg");
if (!src.data) {
printf("Could not load image...\n");
return 1;
}
char input_win[] = "input image";
const char* OUTPUT_TITLE = "histogram demo";
namedWindow(input_win, CV_WINDOW_AUTOSIZE);
namedWindow(OUTPUT_TITLE, CV_WINDOW_AUTOSIZE);
imshow(input_win, src);
//分通道显示
vector<Mat> bgr_planes;
split(src, bgr_planes);//对src图像进行通道分离至bgr_planes图像数组中
//imshow("single channel demo",bgr_planes[0]);
//计算直方图
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);
//输入图像为bgr_planes[0],输入图像个数为1,对图像的第一通道进行直方图统计,掩膜设置为Mat()即不设置掩膜,输出图像为b_hist,需要统计直方图个数为1维数为1,划分的区间数即bins为255,统计像素区间为0-255,进行归一化处理,不累加计算像素值得个数
calcHist(&bgr_planes[