直方图
reference
图像直方图
直方图处理
直方图变换
opencv直方图
直方图
- 图像直方图是反映一个图像像素分布的统计表,其实横坐标代表了图像像素的种类,可以是灰度的,也可以是彩色的。纵坐标代表了每一种颜色值在图像中的像素总数或者占所有像素个数的百分比。
- 图像是由像素构成,因为反映像素分布的直方图往往可以作为图像一个很重要的特征。在实际工程中,图像直方图在特征提取、图像匹配等方面都有很好的应用。
直方图均衡化
- 直方图均衡化是将原图像的直方图通过变换函数变为均匀的直方图,然后按均匀直方图修改原图像,从而获得一幅灰度分布均匀的新图像。
opencv计算直方图
void calcHist(const Mat* images, int nimages, const int* channels, InputArray mask, OutputArray hist, int dims, const int* histSize, const float** ranges, booluniform=true, bool accumulate=false );
/*
const Mat* images:为输入图像的指针。
int nimages:要计算直方图的图像的个数。此函数可以为多图像求直方图,我们通常情况下都只作用于单一图像,所以通常nimages=1。
const int* channels:图像的通道,它是一个数组,如果是灰度图像则channels[1]={0};如果是彩色图像则channels[3]={0,1,2};如果是只是求彩色图像第2个通道的直方图,则channels[1]={1};
IuputArray mask:是一个遮罩图像用于确定哪些点参与计算,实际应用中是个很好的参数,默认情况我们都设置为一个空图像,即:Mat()。
OutArray hist:计算得到的直方图
int dims:得到的直方图的维数,灰度图像为1维,彩色图像为3维。
const int* histSize:直方图横坐标的区间数。如果是10,则它会横坐标分为10份,然后统计每个区间的像素点总和。
const float** ranges:这是一个二维数组,用来指出每个区间的范围。
后面两个参数都有默认值
uniform参数表明直方图是否等距,
最后一个参数与多图像下直方图的显示与存储有关。
*/
demo学习
#include "opencv2/opencv.hpp"
#include "opencv2/opencv_modules.hpp"
#include "opencv2/highgui/highgui.hpp"
#include<iostream>
using namespace cv;
using namespace std;
Mat histogramCal(const Mat& image){
int histSize = 255;
float range[] = { 0, 256 };
const float *histRange = { range };
vector<Mat> bgr;
split(image, bgr);
bool uniform = true;
bool accumulate = false;
Mat b_hist, g_hist, r_hist;
calcHist(&bgr[0], 1, 0, Mat(), b_hist, 1, &histSize, &histRange, uniform, accumulate);
calcHist(&bgr[1], 1, 0, Mat(), g_hist, 1, &histSize, &histRange, uniform, accumulate);
calcHist(&bgr[2], 1, 0, Mat(), r_hist, 1, &histSize, &histRange, uniform, accumulate);
int hist_w = 512, hist_h = 400;
int bin_w = cvRound((double)hist_w / histSize);
Mat histImage(hist_h, hist_w, CV_8U, Scalar(0, 0, 0));
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));
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));
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));
}
return histImage;
}
int main(){
Mat src;
src = imread("E:\\test\\test.jpg");
src.convertTo(src, CV_8U);
cout << src.channels() << endl;
namedWindow("orgin", WINDOW_AUTOSIZE);
imshow("origin", src);
Mat histImage = histogramCal(src);
namedWindow("hist", WINDOW_AUTOSIZE);
imshow("hist", histImage);
Mat hist;
vector<Mat>bgr;
split(src, bgr);
equalizeHist(bgr[0], bgr[0]);
equalizeHist(bgr[1], bgr[1]);
equalizeHist(bgr[2], bgr[2]);
Mat dst;
merge(bgr, dst);
namedWindow("equalize", WINDOW_AUTOSIZE);
imshow("equalize", dst);
Mat equalHist = histogramCal(dst);
namedWindow("equalhist", WINDOW_AUTOSIZE);
imshow("equalhist", equalHist);
waitKey(0);
return 0;
}
函数学习
- 注: opencv中. RGB三个通道是反过来的.
void split(const Mat& src,Mat *mvBegin);
void split(InputArray m, OutputArrayOfArrays mv);
std::vector<Mat> channels;
Mat aChannels[3];
split(src, aChannels);
split(src, channels);
imshow("B",channels[0]);
imshow("G",channels[1]);
imshow("R",channels[2]);
void merge(
const vector<cv::Mat>& mv,
cv::OutputArray dst
);
void merge(const Mat* mv, size_t count, OutputArray dst);
void merge(const vector& mv, OutputArray dst );
std::vector<Mat> channels;
Mat aChannels[3];
split(src, channels);
split(src, aChannels);
merge(channels, 3, mergeImg);
merge(aChannels, mergeImg);
- 归一化: 将需要处理的数据经过处理后(通过某种算法)限定在一定范围内.
void normalize(InputArray src,OutputArraydst, double alpha = 1, double beta = 0, intnorm_type = NORM_L2, int dtype = -1, InputArray mask = noArray());
void cv::equalizeHist (
InputArray src,
OutputArray dst
);
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
#include <stdio.h>
using namespace cv;
using namespace std;
int main()
{
Mat src = imread("D:6.jpg", 1);
cvtColor(src, src, CV_BGR2GRAY);
Mat dst;
equalizeHist(src, dst);
imshow("shiyan", dst);
waitKey(0);
return 0;
}