直方圖概述
簡單來說,直方圖就是對數據進行統計的一種方法,這些數據可以是梯度、方向、色彩或任何其他特征。它的表現形式是一種二維統計表,橫縱坐標分別是統計樣本和該樣本對應的某個屬性的度量。
計算直方圖:calcHist 函數
calcHist 函數用於計算一個或多個陣列的直方圖。
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 accumul = false);
- images,輸入的數組(圖像)或數組集(圖像集),他們需為相同深度(CV_8U 或 CV_32F)和相同尺寸。
- nimages,第一個參數中存放了多少張圖象。
- channels,圖像索引,會按照索引順序依次計算圖像直方圖(注意,第一張圖片索引為 0,以此類推)。
- mask,可選的掩膜操作,非零掩碼元素用於標記待統計元素,需要與輸入圖像集有相同尺寸。
- hist,輸出的目標直方圖,一個二維數組。
- dims,輸出目標直方圖的維度。一般設為 1(線)。
- histSize,x 軸將被分成 histSize 份。
- ranges,x 的取值范圍。
- uniform,直方圖是否歸一化的標識符,默認為 true。
- accumulate,在計算直方圖時是否清空傳入的 hist。true 表示不清空,false 表示清空。默認為 false。只有在想要統計多個圖像序列中的累加直方圖時才會設置為 true。
代碼示例:
#include<opencv.hpp> #include<iostream>
using namespace std; using namespace cv; int main() { Mat src = imread("C:/Users/齊明洋/Desktop/證件照/6.jpg"); imshow("src", src); //計算 BGR 三通道各自直方圖
vector<Mat>bgr(3); int channels[] = { 0,1,2 }; int histsize[] = { 10,20,30 }; float r[] = { 0,255 }; const float* ranges[] = { r,r,r }; calcHist(&src, 3, &channels[0], Mat(), bgr[0], 1, &histsize[0], &ranges[0], true); calcHist(&src, 3, &channels[1], Mat(), bgr[1], 1, &histsize[1], &ranges[1], true); calcHist(&src, 3, &channels[2], Mat(), bgr[2], 1, &histsize[2], &ranges[2], true); //直方圖歸一化
//https://www.cnblogs.com/bjxqmy/p/12292421.html
int w = 300, h = 100; normalize(bgr[0], bgr[0], h, 0, NORM_L1); normalize(bgr[1], bgr[1], h, 0, NORM_L1); normalize(bgr[2], bgr[2], h, 0, NORM_L1); //繪制直方圖
string names[3] = { "b_img","g_img","r_img" }; Mat dst[3];//繪在三張背景上
dst[0] = Mat(h, w, src.type(), Scalar(0, 0, 0)); dst[1] = dst[0].clone(); dst[2] = dst[0].clone(); double width[] = { w / histsize[0],w / histsize[1],w / histsize[2] }; Scalar colors[] = { Scalar(255,0,0),Scalar(0,255,0) ,Scalar(0,0,255) }; for (int i = 0; i < 3; i++) { for (int j = 0; j < histsize[i]; j++) { Point pre = Point(j*width[i], h); Point next = Point(j*width[i], h - bgr[i].at<float>(j)); line(dst[i], pre, next, colors[i], 1); } imshow(names[i], dst[i]); } waitKey(0); }
效果演示:
借鑒博客:https://blog.csdn.net/zhu_hongji/article/details/81663161