直方图与匹配
灰度直方圖是灰度級的函數,描述的是圖像中具有該灰度級的像素的個數:其橫坐標是灰度級,縱坐標是該灰度出現的頻率(像素的個數)。
在opencv中可以通過cvCreateHist()來生成直方圖
?
CvHistogram* cvCreateHist(int dims,????? ?int* sizes,? ?int type,?? ?float** ranges=NULL, int uniform=1 ?)dims? ?//直方圖包含的維數sizes //數組的長度等于dims,數組中每個整數表示分配給對應維數的的bin的個數type ?//表示存儲類型,CV_HIST_ARRAy表示用密集多維矩陣結構存儲直方圖,CV_HIST_SPARSE表示數據已稀疏矩陣方式存儲ranges=NULL, //浮點數對的構成的數組,每個浮點數對表示對應維數的bin的區間的上下界uniform=1 ?//非0表示均勻直方圖,為NULL表示未知,即在后面可以設置。CvHistogram* cvCreateHist(使用cvCalcHist()函數來計算直方圖
?
?
void cvCalcHist(IplImage** image,CvHistogram* hist,int accmulate=0,const CvArr* mask=NULL)image //是一個指向數組的IplImage*類型的指針,著允許利用多個圖像通道hist //要計算的直方圖accmulate //非0時,表示直方圖hist在讀入圖像之前沒有被清零mask //如果為非NULL,則只有與mask非零元素對應的像素點會被包含在計算直方圖中。?
?
1.單通道圖像的直方圖
?
#include "stdafx.h" #include <highgui.h> #include <math.h> #include <cv.h> int main() {IplImage* sourceImage=0;//以單通道讀入圖像if(!(sourceImage=cvLoadImage("YAYA.jpg",0)))return -1;int hdims=51; //分配給對應維數的bin的個數float rangesArray[]={0,255};float* ranges[]={rangesArray};float maxValue;CvHistogram* histogram=0;histogram=cvCreateHist(1,&hdims,CV_HIST_ARRAY,ranges,1);IplImage* histImage; //用來顯示直方圖histImage=cvCreateImage(cvGetSize(sourceImage),8,3);cvZero(histImage);//計算直方圖cvCalcHist(&sourceImage,histogram,0,0);//獲取最大值cvGetMinMaxHistValue(histogram,0,&maxValue,0,0);cvConvertScale(histogram->bins,histogram->bins,maxValue?255./maxValue:0,0);float binsWidth;binsWidth=histImage->width/hdims;CvScalar color=CV_RGB(255,255,255);for(int i=0;i<hdims;i++){double value=(cvGetReal1D(histogram->bins,i)*histImage->height/255);cvRectangle(histImage,cvPoint(i*binsWidth,histImage->height),cvPoint((i+1)*binsWidth,(int)(histImage->height-value)),color,1,8,0);}//顯示 cvNamedWindow("sourceImage",0);cvNamedWindow("histImage",0);cvShowImage("sourceImage",sourceImage);cvShowImage("histImage",histImage);//釋放資源cvDestroyAllWindows();cvReleaseImage(&sourceImage);cvReleaseImage(&histImage);cvReleaseHist(&histogram);cvWaitKey(-1);return 0; }運行結果:
?
多通道圖像的直方圖
因為ccCalHist()只接受單通道圖像,所以在調用cvCalcHist()之前,首先用cvSplit()將多通道圖像分解為單通道圖像。
?
#include "stdafx.h" #include <highgui.h> #include <math.h> #include <cv.h> int main() {IplImage* sourceImage=0;if(!(sourceImage=cvLoadImage("YAYA.jpg",1)))return -1;IplImage* hsvImage=cvCreateImage(cvGetSize(sourceImage),8,3);cvCvtColor(sourceImage,hsvImage,CV_BGR2HSV);IplImage* h_plane=cvCreateImage(cvGetSize(sourceImage),8,1);IplImage* s_plane=cvCreateImage(cvGetSize(sourceImage),8,1);IplImage* v_plane=cvCreateImage(cvGetSize(sourceImage),8,1);cvSplit(hsvImage,h_plane,s_plane,v_plane,0);int h_bins=30,s_bins=32;CvHistogram* histogram;{int hist_size[]={h_bins,s_bins};float h_ranges[]={0,180};float s_ranges[]={0,255};float* ranges[]={h_ranges,s_ranges};histogram=cvCreateHist(2,hist_size,CV_HIST_ARRAY,ranges,1);}IplImage* planes[]={h_plane,s_plane};cvCalcHist(planes,histogram,0,0);cvNormalizeHist(histogram,1.0);int scale=10;IplImage* histImage=cvCreateImage(cvSize(h_bins*scale,s_bins*scale),8,3);cvZero(histImage);float maxValue;cvGetMinMaxHistValue(histogram,0,&maxValue,0,0);for(int h=0;h<h_bins;h++)for(int s=0;s<s_bins;s++){float binValue=cvQueryHistValue_2D(histogram,h,s);int intensity=cvRound(binValue*255./maxValue);cvRectangle(histImage,cvPoint(h*scale,s*scale),cvPoint((h+1)*scale-1,(s+1)*scale-1),CV_RGB(intensity,intensity,intensity),CV_FILLED);}cvNamedWindow("hsvImage",1);cvNamedWindow("histImage",1);cvShowImage("hsvImage",hsvImage);cvShowImage("histImage",histImage);cvWaitKey(-1);cvDestroyAllWindows();cvReleaseImage(&sourceImage);cvReleaseImage(&histImage);cvReleaseHist(&histogram);return 0; }運行結果:
直方圖的相似度
計算直方圖相似度的函數如下:
?
double cvCompareHist(const CvHistogram* hist1,const CvHistogram* hist2,int method; //距離標準 )method的取值有:
?
CV_COMP_CORREL???? 完全匹配為1,完全不匹配為-1,數值越大越匹配
CV_COMP_CHISQR????? 低分比高分匹配的程度高,完全匹配的值為0,完全不匹配為無限值
CV_COMP_INTERSECT?? 高分表示好匹配,低分表示壞匹配
CV_COMP_BHATTACHARYYA???? 低分表示好匹配,高分表示換匹配。完全匹配為0,完全不匹配為0.
?
?
#include "stdafx.h" #include <highgui.h> #include <math.h> #include <cv.h> using namespace std; //對比兩個直方圖的相似度 int main() {IplImage* templateImage=cvLoadImage("YAYA.jpg");if(!templateImage)return -1;IplImage* grayImage=cvCreateImage(cvGetSize(templateImage),8,1);cvCvtColor(templateImage,grayImage,CV_BGR2GRAY);//首先加載圖片,然后將圖片變為灰度圖int hist_size=51;float range[]={0,255};float* ranges[]={range};CvHistogram* histogram;histogram=cvCreateHist(1,&hist_size, //size 元素為對應bin的個數CV_HIST_ARRAY,ranges,1);cvCalcHist(&grayImage,histogram,0,0);IplImage* compareImage=cvLoadImage("YAYA2.jpg");if(!compareImage)return -1;IplImage* compareGrayImage=cvCreateImage(cvGetSize(compareImage),8,1);cvCvtColor(compareImage,compareGrayImage,CV_BGR2GRAY);//首先加載圖片,然后將圖片變為灰度圖CvHistogram* compareHistogram;compareHistogram=cvCreateHist(1,&hist_size,CV_HIST_ARRAY,ranges,1);cvCalcHist(&compareGrayImage,compareHistogram,0,0);//對直方圖進行歸一化操作cvNormalizeHist(histogram,1);cvNormalizeHist(compareHistogram,1);//計算匹配系數double degree=cvCompareHist(histogram,compareHistogram,CV_COMP_CHISQR);cout<<degree<<endl;cvWaitKey(10000000);cvDestroyAllWindows();cvReleaseImage(&templateImage);cvReleaseImage(&grayImage);cvReleaseImage(&compareImage);cvReleaseImage(&compareGrayImage);cvReleaseHist(&compareHistogram);cvReleaseHist(&histogram);return 0; }?
Reference
《學習opencv》
?
?
轉載于:https://www.cnblogs.com/jiangu66/p/3162971.html
總結
- 上一篇: 关于fflush、缓冲区、scanf、E
- 下一篇: 深入理解python之self