本文檔嘗試解答如下問題:
- 如何使用OpenCV函數 compareHist 產生一個表達兩個直方圖的相似度的數值。
- 如何使用不同的對比標准來對直方圖進行比較。
原理
-
要比較兩個直方圖(
and
), 首先必須要選擇一個衡量直方圖相似度的 對比標准 (
) 。
-
OpenCV 函數 compareHist 執行了具體的直方圖對比的任務。該函數提供了4種對比標准來計算相似度:
-
Correlation ( CV_COMP_CORREL )
其中
是直方圖中bin的數目。
-
Chi-Square ( CV_COMP_CHISQR )
-
Intersection ( CV_COMP_INTERSECT )
-
Bhattacharyya 距離( CV_COMP_BHATTACHARYYA )
-
源碼
-
本程序做什么?
- 裝載一張 基准圖像 和 兩張 測試圖像 進行對比。
- 產生一張取自 基准圖像 下半部的圖像。
- 將圖像轉換到HSV格式。
- 計算所有圖像的H-S直方圖,並歸一化以便對比。
- 將 基准圖像 直方圖與 兩張測試圖像直方圖,基准圖像半身像直方圖,以及基准圖像本身的直方圖分別作對比。
- 顯示計算所得的直方圖相似度數值。
-
下載代碼: 點擊 這里
-
代碼一瞥:
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp" #include <iostream> #include <stdio.h> using namespace std; using namespace cv; /** @函數 main */ int main( int argc, char** argv ) { Mat src_base, hsv_base; Mat src_test1, hsv_test1; Mat src_test2, hsv_test2; Mat hsv_half_down; /// 裝載三張背景環境不同的圖像 if( argc < 4 ) { printf("** Error. Usage: ./compareHist_Demo <image_settings0> <image_setting1> <image_settings2>\n"); return -1; } src_base = imread( argv[1], 1 ); src_test1 = imread( argv[2], 1 ); src_test2 = imread( argv[3], 1 ); /// 轉換到 HSV cvtColor( src_base, hsv_base, CV_BGR2HSV ); cvtColor( src_test1, hsv_test1, CV_BGR2HSV ); cvtColor( src_test2, hsv_test2, CV_BGR2HSV ); hsv_half_down = hsv_base( Range( hsv_base.rows/2, hsv_base.rows - 1 ), Range( 0, hsv_base.cols - 1 ) ); /// 對hue通道使用30個bin,對saturatoin通道使用32個bin int h_bins = 50; int s_bins = 60; int histSize[] = { h_bins, s_bins }; // hue的取值范圍從0到256, saturation取值范圍從0到180 float h_ranges[] = { 0, 256 }; float s_ranges[] = { 0, 180 }; const float* ranges[] = { h_ranges, s_ranges }; // 使用第0和第1通道 int channels[] = { 0, 1 }; /// 直方圖 MatND hist_base; MatND hist_half_down; MatND hist_test1; MatND hist_test2; /// 計算HSV圖像的直方圖 calcHist( &hsv_base, 1, channels, Mat(), hist_base, 2, histSize, ranges, true, false ); normalize( hist_base