目錄
1、直方圖比較的概念
2、直方圖比較的主要原因
3、典型應用場景
4、基礎直方圖比較
5、多通道直方圖比較
6、實時直方圖檢測
1、直方圖比較的概念
? ? ? ?直方圖比較是通過數學方法計算兩個直方圖之間的相似度或差異度的技術。在計算機視覺中,直方圖是對圖像特征(如顏色、梯度方向等)的統計分布表示,比較兩個直方圖的相似性可以反映圖像內容的相似程度。
2、直方圖比較的主要原因
1. 圖像相似性判斷 通過比較顏色/紋理直方圖,可以快速判斷兩張圖片的內容相似性,常用于:
? ?圖像檢索
? ?重復圖片檢測
? ?視頻關鍵幀提取
2. 目標識別與匹配 當物體的顏色分布具有特征性時(如紅色消防車),直方圖比較能輔助識別。
3. 變化檢測 監控場景中比較前后幀直方圖差異。
4. 顏色校正驗證 在圖像處理流水線中,通過比較輸入輸出圖像的直方圖差異來驗證處理效果。
3、典型應用場景
醫學影像 :比較病灶區域與正常組織的灰度分布
工業檢測 :檢測產品顏色是否符合標準(如油漆顏色一致性)
自動駕駛 :通過路標顏色直方圖識別交通標志
直方圖比較的優勢在于計算高效(不受旋轉/輕微形變影響),但需注意它缺乏空間信息,常與其他特征結合使用。
4、基礎直方圖比較
#include <opencv2/opencv.hpp>
#include <iostream>using namespace cv;
using namespace std;int main() {// 讀取兩張對比圖像Mat img1 = imread("image1.jpg");Mat img2 = imread("image2.jpg");if(img1.empty() || img2.empty()) return -1;// 轉換為HSV色彩空間(比較顏色直方圖更有效)Mat hsv1, hsv2;cvtColor(img1, hsv1, COLOR_BGR2HSV);cvtColor(img2, hsv2, COLOR_BGR2HSV);// 設置直方圖參數int h_bins = 50, s_bins = 60;int histSize[] = {h_bins, s_bins};float h_range[] = {0, 180};float s_range[] = {0, 256};const float* ranges[] = {h_range, s_range};int channels[] = {0, 1}; // 使用H和S通道// 計算直方圖Mat hist1, hist2;calcHist(&hsv1, 1, channels, Mat(), hist1, 2, histSize, ranges, true, false);calcHist(&hsv2, 1, channels, Mat(), hist2, 2, histSize, ranges, true, false);// 歸一化直方圖normalize(hist1, hist1, 0, 1, NORM_MINMAX, -1, Mat());normalize(hist2, hist2, 0, 1, NORM_MINMAX, -1, Mat());// 比較直方圖(四種方法)double compare_methods[4];compare_methods[0] = compareHist(hist1, hist2, HISTCMP_CORREL);compare_methods[1] = compareHist(hist1, hist2, HISTCMP_CHISQR);compare_methods[2] = compareHist(hist1, hist2, HISTCMP_INTERSECT);compare_methods[3] = compareHist(hist1, hist2, HISTCMP_BHATTACHARYYA);// 輸出比較結果cout << "相關性比較 [越接近1越相似]: " << compare_methods[0] << endl;cout << "卡方比較 [越接近0越相似]: " << compare_methods[1] << endl;cout << "直方圖交集 [越大越相似]: " << compare_methods[2] << endl;cout << "巴氏距離 [越接近0越相似]: " << compare_methods[3] << endl;return 0;
}
比較算法說明
OpenCV提供四種直方圖比較方法:
相關性比較
HISTCMP_CORREL
值范圍[-1,1],1表示完全匹配
卡方檢驗
HISTCMP_CHISQR
值范圍[0,∞),0表示完全匹配
直方圖相交
HISTCMP_INTERSECT
值越大相似度越高
巴氏距離
HISTCMP_BHATTACHARYYA
值范圍[0,1],0表示完全匹配
5、多通道直方圖比較
// ... 圖像讀取和轉換代碼同上 ...// 擴展為3通道直方圖(H,S,V)
int channels[] = {0, 1, 2};
int histSize[] = {30, 32, 32}; // HS通道精度更高
float h_range[] = {0, 180};
float s_range[] = {0, 256};
float v_range[] = {0, 256};
const float* ranges[] = {h_range, s_range, v_range};// 計算直方圖
calcHist(&hsv1, 1, channels, Mat(), hist1, 3, histSize, ranges, true, false);
calcHist(&hsv2, 1, channels, Mat(), hist2, 3, histSize, ranges, true, false);// 添加EMD(Earth Mover's Distance)比較
Mat sig1, sig2;
// 將直方圖轉換為特征向量格式
// ... (需要實現直方圖到特征向量的轉換) ...double emd = EMD(sig1, sig2, DIST_L2);
cout << "推土機距離: " << emd << endl;
6、實時直方圖檢測
VideoCapture cap(0);
Mat frame, last_frame;
bool first_frame = true;while(true) {cap >> frame;if(frame.empty()) break;Mat hsv;cvtColor(frame, hsv, COLOR_BGR2HSV);// 計算當前幀直方圖Mat current_hist;calcHist(&hsv, 1, channels, Mat(), current_hist, 2, histSize, ranges);normalize(current_hist, current_hist, 0, 1, NORM_MINMAX);if(!first_frame) {double similarity = compareHist(last_hist, current_hist, HISTCMP_CORREL);putText(frame, format("相似度: %.2f", similarity), Point(20,50), FONT_HERSHEY_SIMPLEX, 1, Scalar(0,255,0), 2);}first_frame = false;current_hist.copyTo(last_hist);imshow("Live", frame);if(waitKey(30) >= 0) break;
}