《OpenCV3编程入门》学习笔记9 直方图与匹配(一二) 图像直方图概述直方图的计算与绘制
第9章 直方圖與匹配
9.1 圖像直方圖(Histogram)概述
1.作用:
??在每個興趣點設置一個有相近特征的直方圖所構成的標簽,通過標記幀與幀之間顯著的邊緣、顏色、角度等特征的統計變化,來檢測視頻中場景的變化。
2.概念:
??圖像直方圖是圖像中像素強度分布的圖形表達方式,統計了每一個強度值所具有的像素個數,并將統計結果分布于一系列預定義的bins中。直方圖中,橫坐標的左側為純黑較暗區域,右側為純白較亮區域。
3.術語:
(1)dims:需要統計的特征數目
(2)bins:每個特征空間子區段的數目,稱為“直條”或“組距”
(3)Range:每個特征空間的取值范圍
4.例如:
??假設一個矩陣包含一張圖像的信息(灰度值0-255),已知數字范圍包含256個值,將范圍分成子區域(bins),然后統計每個bin的像素數目,如:
????????????????
9.2 直方圖的計算與繪制
9.2.1 計算直方圖:calcHist()函數
1.作用:
??計算一個或多個陣列的直方圖
2.函數原型:
void calcHist(const Mat* image, int nimages, const int* channels, InputArray mask, OutputArray hist, int dims, const int* histSize, const float** ranges, bool uniform=true, bool accumulate=false)
3.參數說明:
(1)輸入數組(集)
(2)輸入數組個數
(3)需要統計的通道(dim)索引,第一個數組通道從0到images[0].channels()-1,第二個數組通道從images[0].channels()計算到images[0].channels()+images[1].channels()-1。
(4)可選的操作掩碼,為空或與images[i]同樣大小的8位數組,非零掩碼元素用于標記出統計直方圖的數組元素數據。
(5)輸出的目標直方圖,二維數組
(6)需要計算的直方圖維度,必須是正數且不大于CV_MAX_DIMS
(7)存放每個維度的直方圖尺寸的數組
(8)表示每一個維度數組的每一維的邊界陣列,即每一位數組的取值范圍
(9)指示直方圖是否均勻的標識符,默認true
(10)累計標識符,默認值false,為true時直方圖在配置階段不會被清零,主要是允許從多個陣列中計算單個直方圖,或用于在特定時間更新直方圖。
9.2.2 尋找最值:minMaxLoc()函數
1.作用:
??在數組中找到全局最小/大值
2.函數原型:
void minMaxLoc(InputArray src, double* minVal, double* maxVal=0, Point* minLoc=0, Point* maxLoc=0, InputArray mask=noArray())
3.參數說明:
(1)輸入的單通道陣列
(2)返回最小值的指針,若無需返回則置為NULL
(3)返回最大值的指針,若無需返回則置為NULL
(4)返回最小位置的指針,若無需返回則置為NULL
(5)返回最大位置的指針,若無需返回則置為NULL
(6)用于選擇子陣列的可選掩模
9.2.3 示例程序
1.繪制H-S二維直方圖
/*
程序說明:計算彩色圖像的色調(Hue)-飽和度(Saturation)二維直方圖
*/
#include<opencv2/opencv.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
using namespace cv;
using namespace std;int main()
{//【1】載入原圖,轉化為HSV顏色模型Mat srcImage, hsvImage;srcImage = imread("1.jpg");cvtColor(srcImage, hsvImage, COLOR_RGB2HSV);//【2】參數準備//定義存儲直方圖的數據結構(單通道陣列)MatND dstHist;//將色調量化為30個等級,將飽和度量化為32個等級int hueBinNum = 30;//色調直方圖直條數量int saturationBinNum = 32;//飽和度直方圖直條數量int histSize[] = { hueBinNum,saturationBinNum };//定義變化范圍float hueRanges[] = { 0,180 };//定義色調的變化范圍為0-179float saturationRanges[] = { 0,256 };//定義飽和度的變化范圍為0-255const float* ranges[] = { hueRanges,saturationRanges };//calcHist函數中將計算第0通道和第1通道的直方圖int channels[] = { 0,1 };//【3】正式調用calcHist,進行直方圖計算//輸入數組,數組個數為1,通道索引,不使用掩模,輸出目標直方圖,需要計算的直方圖維度為2,存放每個維度的直方圖尺寸的數組,每一維數組的取值范圍數組,指示直方圖均勻,直方圖在配置階段會被清零calcHist(&hsvImage, 1, channels, Mat(), dstHist, 2, histSize, ranges, true, false);//【4】繪制直方圖準備參數double maxValue = 0;//最大值minMaxLoc(dstHist, 0, &maxValue, 0, 0);//查找數組和子數組的全局最大值存入maxValue中int scale = 10;Mat histImage = Mat::zeros(saturationBinNum*scale, hueBinNum * 10, CV_8UC3);//【5】雙層循環,進行直方圖繪制for (int hue = 0; hue < hueBinNum; hue++){for (int saturation = 0; saturation < saturationBinNum; saturation++){float binValue = dstHist.at<float>(hue, saturation);//直方圖直條的值int intensity = cvRound(binValue * 255 / maxValue);//強度//正式繪制rectangle(histImage, Point(hue*scale, saturation*scale), Point((hue + 1)*scale - 1, (saturation+1)*scale - 1), Scalar::all(intensity), FILLED);} }//【6】顯示效果圖imshow("素材圖", srcImage);imshow("H-S直方圖", histImage);waitKey(0);return 0;
}
運行效果:
2.計算并繪制圖像一維直方圖
#include<opencv2/opencv.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
using namespace cv;
using namespace std;int main()
{//【1】載入原灰度圖并顯示Mat srcImage = imread("1.jpg", 0);if (!srcImage.data){printf("載入原圖失敗~!\n");return false;}imshow("【原始圖】", srcImage);//【2】定義變量MatND dstHist;int dims = 1;float hranges[] = { 0,255 };const float *ranges[] = { hranges };int size = 256;int channels = 0;//【3】計算圖像的直方圖calcHist(&srcImage, 1, &channels, Mat(), dstHist, dims, &size, ranges, true, false);int scale = 1;Mat dstImage(size*scale, size, CV_8U, Scalar(0));//【4】獲取最大值和最小值double minValue = 0;double maxValue = 0;minMaxLoc(dstHist, &minValue, &maxValue, 0, 0);//【5】繪制出直方圖int hpt = saturate_cast<int>(0.9*size);for (int i = 0; i < 256; i++){float binValue = dstHist.at<float>(i);int realValue = saturate_cast<int>(binValue*hpt / maxValue);rectangle(dstImage, Point(i*scale, size - 1), Point((i + 1)*scale - 1, size - realValue), Scalar(255));}imshow("一維直方圖", dstImage);waitKey(0);return 0;
}
運行效果:
3.繪制RGB三色直方圖
#include<opencv2/opencv.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
using namespace cv;
using namespace std;int main()
{//【1】載入原圖并顯示Mat srcImage = imread("love.jpg");imshow("【原始圖】", srcImage);//【2】初始化直方圖計算參數int bins = 256;int hist_size[] = { bins };float range[] = { 0,256 };const float* ranges[] = { range };MatND redHist, grayHist, blueHist;//【3】進行直方圖計算(紅色分量部分)int channels_r[] = { 0 };calcHist(&srcImage, 1, channels_r, Mat(), redHist, 1, hist_size, ranges, true, false);//【4】進行直方圖計算(綠色分量部分)int channels_g[] = { 1 };calcHist(&srcImage, 1, channels_g, Mat(), grayHist, 1, hist_size, ranges, true, false);//【5】進行直方圖計算(藍色分量部分)int channels_b[] = { 2 };calcHist(&srcImage, 1, channels_b, Mat(), blueHist, 1, hist_size, ranges, true, false);//繪制三色直方圖//參數準備double maxValue_red, maxValue_green, maxValue_blue;minMaxLoc(redHist, 0, &maxValue_red, 0, 0);minMaxLoc(grayHist, 0, &maxValue_green, 0, 0);minMaxLoc(blueHist, 0, &maxValue_blue, 0, 0);int scale = 1;int histHeight = 256;Mat histImage = Mat::zeros(histHeight, bins * 3, CV_8UC3);//正式繪制for (int i = 0; i < bins; i++){//參數準備float binValue_red = redHist.at<float>(i);float binValue_green = grayHist.at<float>(i);float binValue_blue = blueHist.at<float>(i);int intensity_red = cvRound(binValue_red*histHeight / maxValue_red);//要繪制的高度int intensity_green = cvRound(binValue_green*histHeight / maxValue_green);//要繪制的高度int intensity_blue = cvRound(binValue_blue*histHeight / maxValue_blue);//要繪制的高度//繪制紅色分量的直方圖rectangle(histImage, Point(i*scale, histHeight - 1), Point((i + 1)*scale - 1, histHeight - intensity_red), Scalar(255, 0, 0));//繪制綠色分量的直方圖rectangle(histImage, Point((i + bins)*scale, histHeight - 1), Point((i + bins + 1)*scale - 1, histHeight - intensity_green), Scalar(0, 255, 0));//繪制藍色分量的直方圖rectangle(histImage, Point((i + bins * 2)*scale, histHeight - 1), Point((i + bins * 2 + 1)*scale - 1, histHeight - intensity_blue), Scalar(0, 0, 255));}//顯示直方圖imshow("圖像的RGB直方圖", histImage);waitKey(0);return 0;
}
運行效果:
總結
以上是生活随笔為你收集整理的《OpenCV3编程入门》学习笔记9 直方图与匹配(一二) 图像直方图概述直方图的计算与绘制的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 漯河乾隆宴御品叫花鸡加盟费多少钱?
- 下一篇: 韩国botulax瘦脸针多少钱