wordpress左邊欄網(wǎng)頁(yè)seo優(yōu)化
????????由于圖像的直方圖表示圖像像素灰度值的統(tǒng)計(jì)特性,因此可以通過兩幅圖像的直方圖特性比較 兩幅圖像的相似程度。從一定程度上來講,雖然兩幅圖像的直方圖分布相似不代表兩幅圖像相似,但是兩幅圖像相似則兩幅圖像的直方圖分布一定相似。例如,在通過插值對(duì)圖像進(jìn)行縮放后,雖然圖像的直方圖不會(huì)與之前完全一致,但是兩者之間一定具有很高的相似性,因而可以通過比較兩幅圖像的直方圖分布相似性對(duì)圖像進(jìn)行初步的篩選與識(shí)別。
????????OpenCV 4 中提供了用于比較兩個(gè)圖像直方圖相似性的 compareHist() 函數(shù)。
1.??compareHist()函數(shù)原型
double cv::compareHist(InputArray H1,
InputArray H2,
int method
)
- H1:第一幅圖像直方圖。
- H2:第二幅圖像直方圖,與 H1 具有相同的尺寸。
- method:比較方法標(biāo)志。?
????????該函數(shù)前兩個(gè)參數(shù)為需要比較相似性的圖像直方圖,由于不同尺寸的圖像中像素?cái)?shù)目可能不相同,為了能夠得到兩個(gè)圖像直方圖正確的相似性,需要輸入同一種方式歸一化后的圖像直方圖,并且要求兩個(gè)圖像直方圖具有相同的尺寸。該函數(shù)中第三個(gè)參數(shù)為比較相似性的方法,選擇不同的方法會(huì)得到不同的相似性系數(shù),會(huì)將計(jì)算得到的相似性系數(shù)以 double 類型返回。由于不同計(jì)算方法的規(guī)則不一,因此相似性系數(shù)代表的含義也不相同。接下來介紹每種方法比較相似性的原理。
compareHist()函數(shù)比較直方圖方法的可選擇標(biāo)志參數(shù)
1.1?HISTCMP_CORREL?
????????該方法名為相關(guān)法, 在該方法中,如果兩個(gè)圖像直方圖完全一致,那么計(jì)算數(shù)值為 1 ;如果兩個(gè)圖像直方圖完全不相關(guān),那么計(jì)算值為 0 。
????????其中,N 是直方圖的灰度值個(gè)數(shù)。?
1.2?HISTCMP_CHISQR
????????該方法名為卡方法,在該方法中,如果兩個(gè)圖像直方圖完全一致,那么計(jì)算數(shù)值為 0;兩個(gè)圖像的相似性越小,計(jì)算數(shù)值越大。
1.3?HISTCMP_INTERSECT?
????????該方法名為直方圖相交法, 該方法不會(huì)將計(jì)算結(jié)果歸一化,因此,即使是兩個(gè)完全一致的圖像直方圖,來自于不同圖像,也會(huì)有不同的數(shù)值。例如,由A 圖像縮放后得到的兩個(gè)完全一樣的直方圖相似性結(jié)果與由 B 圖像縮放后得到的兩個(gè)完全一樣的直方圖相似性結(jié)果可能不相同。但是,當(dāng)任意圖像的直方圖與 A 圖像的直方圖比較時(shí),數(shù)值越大, 相似性越高,數(shù)值越小,相似性越低。
1.4?HISTCMP_BHATTACHARYYA ?
????????該方法名為巴塔恰里雅距離(巴氏距離)法, 在該方法中,如果兩個(gè)圖像直方圖完全一致,那么計(jì)算數(shù)值為 0 ;兩個(gè)圖像的相似性越小,計(jì)算數(shù)值越大。
1.5?HISTCMP_CHISQR_ALT?
????????該方法稱為替代卡方法,其判斷兩個(gè)直方圖是否相似的方法與巴氏距離法相同,常用于替代巴氏距離法用于紋理比較。
1.6?HISTCMP_KL_DIV?
????????該方法名為相對(duì)熵法,又名 Kullback-Leibler 散度法, 在該方法中,如果兩個(gè)圖像直方圖完全一致,那么計(jì)算數(shù)值為 0 ;兩個(gè)圖像的相似性越小,計(jì)算數(shù)值越大。
2. 示例代碼
#include <opencv2/opencv.hpp>
#include <iostream> using namespace cv;
using namespace std; void drawHist(Mat &hist, int type, string name) //歸一化并繪制直方圖函數(shù)
{ int hist_w = 512; int hist_h = 400; int width = 2; Mat histImage = Mat::zeros(hist_h, hist_w, CV_8UC3); normalize(hist, hist, 1, 0, type, -1, Mat()); for (int i = 1; i <= hist.rows; i++) { rectangle(histImage, Point(width*(i - 1), hist_h - 1), Point(width*i - 1, hist_h - cvRound(hist_h*hist.at<float>(i - 1)) - 1), Scalar(255, 255, 255), -1); } imshow(name, histImage);
}
//主函數(shù)
int main()
{ //system("color F0"); //更改輸出界面顏色Mat img = imread("../pic/gril_1.jpg"); if (img.empty()) { cout << "請(qǐng)確認(rèn)圖像文件名稱是否正確" << endl; return -1; } Mat gray, hist, gray2, hist2, gray3, hist3; cvtColor(img, gray, COLOR_BGR2GRAY); resize(gray, gray2, Size(), 0.5, 0.5); gray3 = imread("../pic/hand.jpg", IMREAD_GRAYSCALE); const int channels[1] = { 0 }; float inRanges[2] = { 0,255 }; const float* ranges[1] = { inRanges }; const int bins[1] = { 256 }; calcHist(&gray, 1, channels, Mat(), hist, 1, bins, ranges); calcHist(&gray2, 1, channels, Mat(), hist2, 1, bins, ranges); calcHist(&gray3, 1, channels, Mat(), hist3, 1, bins, ranges); drawHist(hist, NORM_INF, "hist"); drawHist(hist2, NORM_INF, "hist2"); drawHist(hist3, NORM_INF, "hist3"); //原圖直方圖與原圖直方圖的相關(guān)系數(shù)double hist_hist = compareHist(hist, hist, HISTCMP_CORREL); cout << "apple_apple=" << hist_hist << endl; //原圖直方圖與縮小原圖后的直方圖的相關(guān)系數(shù)double hist_hist2 = compareHist(hist, hist2, HISTCMP_CORREL); cout << "apple_apple256=" << hist_hist2 << endl; //兩幅不同圖像直方圖相關(guān)系數(shù)double hist_hist3 = compareHist(hist, hist3, HISTCMP_CORREL); cout << "apple_lena=" << hist_hist3 << endl; waitKey(0); return 0;
}
3. 測(cè)試結(jié)果?
?