OpenCV圖像處理之直方圖比較方法詳解
一、直方圖比較
直方圖比較是對輸入的兩張圖像進(jìn)行計算得到直方圖H1與H2,歸一化到相同的尺度空間,然后可以通過計算H1與H2的之間的距離得到兩個直方圖的相似程度(每張圖像都有唯一的直方圖與之對應(yīng)),進(jìn)而比較圖像本身的相似程度。Opencv提供的比較方法有四種:
Correlation 相關(guān)性比較
Chi-Square 卡方比較
Intersection 十字交叉性
Bhattacharyya distance 巴氏距離。
(1)直方圖比較方法-相關(guān)性計算(CV_COMP_CORREL)
其中:

其中N是直方圖的BIN個數(shù),
是均值。
(2)直方圖比較方法-相關(guān)性計算(CV_COMP_CORREL)

H1,H2分別表示兩個圖像的直方圖數(shù)據(jù)
(3)直方圖比較方法-十字交叉性計算(CV_COMP_INTERSECT)

H1,H2分別表示兩個圖像的直方圖數(shù)據(jù)
(4)直方圖比較方法-巴氏距離計算(CV_COMP_BHATTACHARYYA )

H1,H2分別表示兩個圖像的直方圖數(shù)據(jù),
二、圖像直方圖比較方法
加載原圖像
將圖像色彩空間由BGR三通道轉(zhuǎn)換為HSV空間(由于直方圖對亮度和灰度比較敏感,色彩空間轉(zhuǎn)換就是突出這兩個因素盡量去除其他因素)
計算直方圖進(jìn)行歸一化處理,歸一化到0到1之間,調(diào)用calcHist和normalize
直方圖比較,使用上述四種方法之一,調(diào)用compareHist
直方圖比較API函數(shù)接口
API接口
double compareHist(InputArray h1,InputArray H2,int method)
參數(shù)說明:
第一個參數(shù)InputArray類型 h1,直方圖數(shù)據(jù)
第二個參數(shù)InputArray類型 h2,直方圖數(shù)據(jù)
第三個參數(shù)int類型 method比較方法,上述四種方法之一
返回值:采用上述四中方法之一計算后的兩個直方圖相關(guān)系數(shù)
關(guān)于 int method 的取值:
enum HistCompMethods {
HISTCMP_CORREL = 0, //相關(guān)性比較
HISTCMP_CHISQR = 1, //卡方比較
HISTCMP_INTERSECT = 2, //十字交叉性
HISTCMP_BHATTACHARYYA = 3, //巴氏距離
HISTCMP_HELLINGER = HISTCMP_BHATTACHARYYA,
HISTCMP_CHISQR_ALT = 4, //替代卡方:通常用于紋理比較。
HISTCMP_KL_DIV = 5 //KL散度
};
不同直方圖相關(guān)性比較方法的特點(diǎn):
Correlation相關(guān)性比較(CV_COMP_CORREL)值越大,相關(guān)度越高,最大值為1,最小值為0,越接近1越相似
Chi-Square卡方比較(CV_COMP_CHISQR) 值越小,相關(guān)度越高,最大值無上界,最小值0,越接近0越相似
Intersection十字交叉性(CV_COMP_INTERSECT)對于相似度比較,值越大,表明相關(guān)度越高,最大值無上界;完美匹配為1,完全不匹配為0;
Bhattacharyya distance巴氏距離(CV_COMP_BHATTACHARYYA)值越小,相關(guān)度越高,最大值為1,最小值為0,越接近1越相似
三、代碼實(shí)現(xiàn)
#include"stdafx.h"
#include <opencv2/opencv.hpp>
#include <iostream>
#include <math.h>
using namespace std;
using namespace cv;
string convertToString(double d);
int main(int argc, char** argv) {
Mat base, test1, test2; //RGB圖像
Mat hsvbase, hsvtest1, hsvtest2; //HSV圖像
base = imread("F:/photo/zx.jpg");
if (!base.data) {
printf("could not load image...\n");
return -1;
}
test1 = imread("F:/photo/a.jpg");
test2 = imread("F:/photo/c.jpg");
//轉(zhuǎn)化為HSV圖像
cvtColor(base, hsvbase, COLOR_BGR2HSV);
cvtColor(test1, hsvtest1, COLOR_BGR2HSV);
cvtColor(test2, hsvtest2, COLOR_BGR2HSV);
int h_bins = 50; int s_bins = 60;
int histSize[] = { h_bins, s_bins };
// hue varies from 0 to 179, saturation from 0 to 255
float h_ranges[] = { 0, 180 };
float s_ranges[] = { 0, 256 };
const float* ranges[] = { h_ranges, s_ranges };
// Use the o-th and 1-st channels
int channels[] = { 0, 1 };
MatND hist_base;
MatND hist_test1;
MatND hist_test2;
calcHist(&hsvbase, 1, channels, Mat(), hist_base, 2, histSize, ranges, true, false);
normalize(hist_base, hist_base, 0, 1, NORM_MINMAX, -1, Mat());
calcHist(&hsvtest1, 1, channels, Mat(), hist_test1, 2, histSize, ranges, true, false);
normalize(hist_test1, hist_test1, 0, 1, NORM_MINMAX, -1, Mat());
calcHist(&hsvtest2, 1, channels, Mat(), hist_test2, 2, histSize, ranges, true, false);
normalize(hist_test2, hist_test2, 0, 1, NORM_MINMAX, -1, Mat());
double basebase = compareHist(hist_base, hist_base, 2);//zx
double basetest1 = compareHist(hist_base, hist_test1,2);//zx and a
double basetest2 = compareHist(hist_base, hist_test2, 2);//zx and c
double tes1test2 = compareHist(hist_test1, hist_test2, 2);//a and c
printf("test1 compare with test2 correlation value :%f", tes1test2);
Mat test12;
test2.copyTo(test12);
putText(base, convertToString(basebase), Point(50, 50), FONT_HERSHEY_COMPLEX, 1, Scalar(0, 0, 255), 2, LINE_AA); //zx
putText(test1, convertToString(basetest1), Point(50, 50), FONT_HERSHEY_COMPLEX, 1, Scalar(0, 0, 255), 2, LINE_AA);//zx and a
putText(test2, convertToString(basetest2), Point(50, 50), FONT_HERSHEY_COMPLEX, 1, Scalar(0, 0, 255), 2, LINE_AA);//zx and c
putText(test12, convertToString(tes1test2), Point(50, 50), FONT_HERSHEY_COMPLEX, 1, Scalar(0, 0, 255), 2, LINE_AA);//a and c
namedWindow("base", 0);
resizeWindow("base", base.cols / 2, base.rows / 2);
namedWindow("test1", 0);
resizeWindow("test1", test1.cols / 2, test1.rows / 2);
namedWindow("test2", 0);
resizeWindow("test2", test2.cols / 2, test2.rows / 2);
imshow("base", base);
imshow("test1", test1);
imshow("test2", test2);
imshow("test12", test12);
waitKey(0);
return 0;
}
string convertToString(double d) {
ostringstream os;
if (os << d)
return os.str();
return "invalid conversion";
}四、圖像處理效果
代碼中,車道線圖片base自行十字交叉性比較,basebase = 36.8538,數(shù)值越大,圖像相關(guān)性程度越高

base圖片與test1圖片進(jìn)行十字交叉性比較,test1base = 9.55181,數(shù)值較小,圖像相識度較低

下面圖像是test1圖像與test2圖像直方圖對比,test2base = 7.98399,相識度較小

到此這篇關(guān)于OpenCV圖像處理之直方圖比較方法詳解的文章就介紹到這了,更多相關(guān)OpenCV直方圖比較內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Matlab實(shí)現(xiàn)繪制高階版本韋恩圖(upset圖)
韋恩圖隨著階數(shù)升高會越來越復(fù)雜,當(dāng)階數(shù)達(dá)到7或者以上時幾乎沒辦法繪制,但是使用upset圖卻可以比較輕易的繪制。本文就來用Matlab實(shí)現(xiàn)繪制upset圖,需要的可以參考一下2023-01-01
C語言編程中實(shí)現(xiàn)二分查找的簡單入門實(shí)例
這篇文章主要介紹了C語言編程中實(shí)現(xiàn)二分查找的簡單入門實(shí)例,需要的朋友可以參考下2015-12-12
C語言 90后懷舊游戲超級瑪麗的實(shí)現(xiàn)流程
90后最風(fēng)靡的游戲是什么?第一個聯(lián)想到的肯定是插卡游戲機(jī)或者VCD加光盤運(yùn)行在電視機(jī)上的超級瑪麗了,它的經(jīng)典絕對可以排在第一位,長大后的我們今天來用C語言重溫一下2021-11-11

