opencv 繪制直方圖
一、話說直方圖
說到直方圖,同學們一定會想到統計學里的直方圖(沒有想起來的抓緊去翻下中學數學課本)。所謂直方圖啊,就是把一大坨東西分成好幾部分(橫坐標),然后看看每一部分有多少(縱坐標)。比如說康娜醬的班里要做個人愛好的統計,喜歡跳繩的有5人,喜歡唱歌的有8人,喜歡讀書的有6人,超喜歡康娜醬的有1人(才川同學了解一下)。那么圖像中的直方圖又是個啥子呢?喜歡攝影的同學一定見過。圖像中常見的直方圖是亮度直方圖(在CV中還有一種H-S直方圖,即在HSV空間中計算,若沒有特殊說明,將會默認介紹亮度直方圖),橫坐標表示像素值的分布(通常0~255),縱坐標為像素個數,那么圖像直方圖的含義就是數數看每個像素值對應的像素個數,進一步講,橫坐標的左側為暗的區域,右側為亮的區域,所以圖像的亮度分布情況就可以反應在亮度直方圖中。
在OpenCV中,我們使用函數calcHist來計算直方圖(僅僅是計算),如果使用python,則可借助matplotlib繪制出直方圖(python的話當然也可以用OpenCV中的繪圖函數,但有matplotlib這么好的工具為什么不用呢)。
API:
hist=cv2.calcHist(images, channels, mask, histSize, ranges[, hist[, accumulate]])
- hist:直方圖的數據,是一個二維數組
- image:數組集合,這里就是圖像集合,可以是一幅或多幅圖像,需要有相同的深度(CV_8U或CV_32F)和尺寸
- channels:要統計哪個通道的像素,彩色圖像的話就有3個通道
- mask:掩膜,當我們想要對圖像中某一區域做直方圖時就要在圖像上加一層掩膜
- histSize:步長,要把橫軸分成多少份,有些教程中叫做bin的長度
- ranges:統計量的取值范圍,注意不是縱軸的取值范圍,比如統計量是像素,那么通常就是像素值的取值范圍
注意
- 參數images、channels、histSize和ranges參數都要寫成列表的形式,因為這個函數允許處理多幅圖像或多個通道
- 當要處理多幅圖像或多個通道時,histSize和ranges中參數的順序是與待處理的矩陣一一對應,比如channels寫成[0,1],那么ranges寫成[0,180,0,256],即通道0的ranges是[0,180],通道2的ranges是[0,256],這個數值組合其實是分析HSV時用到的。
好的,我們來看一個Demo,要做下面幾個事,素材取自番劇《比宇宙更遠的地方》第13話:
- 計算并繪制灰度圖像的直方圖
- 計算并繪制彩色圖像的直方圖
- 使用掩膜來繪制直方圖,掩膜是通過確定ROI并進行邏輯運算得到的
Mat srcImage = imread("D:\\cv_study\\隨機練\\2.jpg");
MatND dstHist;//得到的直方圖
int dims = 1;//得到的直方圖的維數 灰度圖的維數為1
float hranges[2] = { 0, 255 };
const float *ranges[1] = { hranges }; // 這里需要為const類型,二維數組用來指出每個區間的范圍
int size = 256;//直方圖橫坐標的區間數 即橫坐標被分成256份
int channels = 0;//圖像得通道 灰度圖的通道數為0
//計算圖像的直方圖
calcHist(&srcImage, 1, &channels, Mat(), dstHist, dims, &size, ranges);
int scale = 1;
Mat dstImage(size * scale, size, CV_8U, Scalar(0));
//獲取最大值和最小值
double minValue = 0;
double maxValue = 0;
minMaxLoc(dstHist, &minValue, &maxValue, 0, 0); //找到直方圖中的最大值和最小值
//繪制出直方圖
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);
line(dstImage, Point(i*scale, size - 1), Point((i + 1)*scale - 1, size - realValue), Scalar(255));
}
imshow("一維直方圖", dstImage);
waitKey();
return 0;
實驗結果如圖:
三、直方圖均衡化
dst=cv2.equalizeHist(src[, dst])
- src:需要進行均衡化處理的圖像
- dist:均衡化后的圖像
cvtColor(srcImage, srcImage, CV_BGR2GRAY);
equalizeHist(srcImage, m0);
waitKey();
四、直方圖比較
亮度直方圖反應了一幅圖像的亮度分布,這一特性可以用來比較兩幅圖像的相似性,也可以研究不同光照對同一幅圖像的影響。
要用到函數compareHist,函數原型:
retval=cv2.compareHist(H1, H2, method)
- retval:兩個直方圖的相似度
- H1和H2:需要比較的兩個直方圖
- method:比較方法,這里介紹三種,其他的方法可以查閱API
Correlation ( CV_COMP_CORREL )
其中
是直方圖中bin的數目。
Chi-Square ( CV_COMP_CHISQR )
Intersection ( CV_COMP_INTERSECT )
Bhattacharyya 距離( CV_COMP_BHATTACHARYYA )
實驗代碼:
int main()
{
Mat srcImage = imread("D:\\cv_study\\隨機練\\1.jpg");
Mat compareImage = imread("D:\\cv_study\\隨機練\\2.jpg");
imshow("【原圖】", srcImage);
imshow("【需要比較的圖像】", compareImage);
//在比較直方圖時,最佳操作是在HSV空間中操作,所以需要將BGR空間轉換為HSV空間
Mat srcHsvImage;
Mat compareHsvImage;
cvtColor(srcImage, srcHsvImage, CV_BGR2HSV);
cvtColor(compareImage, compareHsvImage, CV_BGR2HSV);
//采用H-S直方圖進行處理
//首先得配置直方圖的參數
MatND srcHist, compHist;
//H、S通道
int channels[] = { 0, 1 };
int histSize[] = { 30, 32 };
float HRanges[] = { 0, 180 };
float SRanges[] = { 0, 256 };
const float *ranges[] = { HRanges, SRanges };
//進行原圖直方圖的計算
calcHist(&srcHsvImage, 1, channels, Mat(), srcHist, 2, histSize, ranges, true, false);
//對需要比較的圖進行直方圖的計算
calcHist(&compareHsvImage, 1, channels, Mat(), compHist, 2, histSize, ranges, true, false);
//注意:這里需要對兩個直方圖進行歸一化操作
normalize(srcHist, srcHist, 0, 1, NORM_MINMAX);
normalize(compHist, compHist, 0, 1, NORM_MINMAX);
//對得到的直方圖對比
double g_dCompareRecult = compareHist(srcHist, compHist, 0);
cout << "方法一:兩幅圖像比較的結果為:" << g_dCompareRecult << endl;
g_dCompareRecult = compareHist(srcHist, compHist, 1);
cout << "方法二:兩幅圖像比較的結果為:" << g_dCompareRecult << endl;
g_dCompareRecult = compareHist(srcHist, compHist, 2);
cout << "方法三:兩幅圖像比較的結果為:" << g_dCompareRecult << endl;
g_dCompareRecult = compareHist(srcHist, compHist, 3);
cout << "方法四:兩幅圖像比較的結果為:" << g_dCompareRecult << endl;
waitKey();
return 0;
}
好了,這就是今天要講的直方圖。
智能推薦
使用Opencv繪制灰度直方圖/對比
一.所需結構體 結構體原型: 二.所需函數 1.cvCalcHist: 函數功能:用于計算圖像直方圖 函數原型: 參數介紹: 返回值:無 2.CvCreateHist: 函數功能:用于創建直方圖 函數原型: 參數介紹: 返回值:成功返回一個指向堆中CvHistogram結構體的CvHistogram指針 3.cvGetMinMaxHistValue: 函數功能:用于統計直方圖中最小值和最大值 函數...
opencv(18)---直方圖計算以及繪制
基本概念 直方圖是對數據進行統計的一種方法, 可以直觀表現圖像某屬性的數值(頻率)分布情況, 包括灰度直方圖、RGB直方圖等 數字直方圖 圖像直方圖 相關概念 函數原型 1.dims: 需要統計得特征的數目, 只統計灰度值—dims=1 統計RGB值—dims=3 2.bins: 每個特征空間子區域段的數目,也 可稱為組距(簡單理解為直方圖分 成幾個柱子組成) 3.rang...
猜你喜歡
freemarker + ItextRender 根據模板生成PDF文件
1. 制作模板 2. 獲取模板,并將所獲取的數據加載生成html文件 2. 生成PDF文件 其中由兩個地方需要注意,都是關于獲取文件路徑的問題,由于項目部署的時候是打包成jar包形式,所以在開發過程中時直接安照傳統的獲取方法沒有一點文件,但是當打包后部署,總是出錯。于是參考網上文章,先將文件讀出來到項目的臨時目錄下,然后再按正常方式加載該臨時文件; 還有一個問題至今沒有解決,就是關于生成PDF文件...
電腦空間不夠了?教你一個小秒招快速清理 Docker 占用的磁盤空間!
Docker 很占用空間,每當我們運行容器、拉取鏡像、部署應用、構建自己的鏡像時,我們的磁盤空間會被大量占用。 如果你也被這個問題所困擾,咱們就一起看一下 Docker 是如何使用磁盤空間的,以及如何回收。 docker 占用的空間可以通過下面的命令查看: TYPE 列出了docker 使用磁盤的 4 種類型: Images:所有鏡像占用的空間,包括拉取下來的鏡像,和本地構建的。 Con...
requests實現全自動PPT模板
http://www.1ppt.com/moban/ 可以免費的下載PPT模板,當然如果要人工一個個下,還是挺麻煩的,我們可以利用requests輕松下載 訪問這個主頁,我們可以看到下面的樣式 點每一個PPT模板的圖片,我們可以進入到詳細的信息頁面,翻到下面,我們可以看到對應的下載地址 點擊這個下載的按鈕,我們便可以下載對應的PPT壓縮包 那我們就開始做吧 首先,查看網頁的源代碼,我們可以看到每一...