多維直方圖
typedef struct CvHistogram
{
int header_size; /* 頭尺寸 */
CvHistType type; /* 直方圖類型 */
int flags; /* 直方圖標(biāo)識(shí) */
int c_dims; /* 直方圖維數(shù) */
int dims[CV_HIST_MAX_DIM]; /* 每一維的尺寸 */
int mdims[CV_HIST_MAX_DIM]; /* 快速訪問元素的系數(shù) */
/* &m[a,b,c] = m + a*mdims[0] + b*mdims[1] + c*mdims[2] */
float* thresh[CV_HIST_MAX_DIM]; /* 每一維的直方塊邊界數(shù)組 */
float* array; /* 所有的直方圖數(shù)據(jù),擴(kuò)展為單行 */
struct CvNode* root; /* 存儲(chǔ)直方塊的平衡樹的根結(jié)點(diǎn) */
CvSet* set; /* 內(nèi)存存儲(chǔ)倉的指針 (對平衡樹而言) */
int* chdims[CV_HIST_MAX_DIM]; /* 快速計(jì)算的緩存 */
}
CvHistogram;
創(chuàng)建直方圖
CvHistogram* cvCreateHist( int dims, int* sizes, int type,
float** ranges=NULL, int uniform=1 );
函數(shù) cvCreateHist 創(chuàng)建一個(gè)指定尺寸的直方圖,并且返回創(chuàng)建的直方圖的指針。 如果數(shù)組的 ranges 是 0, 則直方塊的范圍必須由函數(shù)cvSetHistBinRanges 稍后指定。雖然 cvCalcHist 和 cvCalcBackProject 可以處理 8-比特圖像而無需設(shè)置任何直方塊的范圍,但它們都被假設(shè)等分 0..255 之間的空間。
設(shè)置直方塊的區(qū)間
void cvSetHistBinRanges( CvHistogram* hist, float** ranges, int uniform=1 );
函數(shù) cvSetHistBinRanges 是一個(gè)獨(dú)立的函數(shù),完成直方塊的區(qū)間設(shè)置。更多詳細(xì)的關(guān)于參數(shù) ranges 和 uniform 的描述,請參考函數(shù) cvCalcHist , 該函數(shù)也可以初始化區(qū)間。直方塊的區(qū)間的設(shè)置必須在計(jì)算直方圖之前,或 在計(jì)算直方圖的反射圖之前。
釋放直方圖結(jié)構(gòu)
void cvReleaseHist( CvHistogram** hist );
函數(shù) cvReleaseHist 釋放直方圖 (頭和數(shù)據(jù)). 指向直方圖的指針被函數(shù)所清空。如果 *hist 指針已經(jīng)為 NULL, 則函數(shù)不做任何事情。
清除直方圖
void cvClearHist( CvHistogram* hist );
函數(shù) cvClearHist 當(dāng)直方圖是稠密數(shù)組時(shí)將所有直方塊設(shè)置為 0,當(dāng)直方圖是稀疏數(shù)組時(shí),除去所有的直方塊。
從數(shù)組中創(chuàng)建直方圖
CvHistogram* cvMakeHistHeaderForArray( int dims, int* sizes,
CvHistogram* float* data, float** ranges=NULL, niform=1 );
dims
直方圖維數(shù).
函數(shù) cvMakeHistHeaderForArray 初始化直方圖,其中頭和直方塊為用戶所分配。以后不需要調(diào)用 cvReleaseHist 只有稠密直方圖可以采用這種方法,函數(shù)返回 hist
.
查詢直方塊的值
#define cvQueryHistValue_1D( hist, idx0 ) / cvGetReal1D( (hist)->bins, (idx0) )
#define cvQueryHistValue_2D( hist, idx0, idx1 ) / cvGetReal2D( (hist)->bins, (idx0), (idx1) )
#define cvQueryHistValue_3D( hist, idx0, idx1, idx2 ) / cvGetReal3D( (hist)->bins, (idx0), (idx1), (idx2) )
#define cvQueryHistValue_nD( hist, idx ) / cvGetRealND( (hist)->bins, (idx) )
宏 cvQueryHistValue_*D 返回 1D, 2D, 3D 或 N-D 直方圖的指定直方塊的值。對稀疏直方圖,如果方塊在直方圖中不存在,函數(shù)返回 0, 而且不創(chuàng)建新的直方塊。
返回直方塊的指針
#define cvGetHistValue_1D( hist, idx0 ) / ((float*)(cvPtr1D( (hist)->bins, (idx0), 0 ))
#define cvGetHistValue_2D( hist, idx0, idx1 ) / ((float*)(cvPtr2D( (hist)->bins, (idx0), (idx1), 0 ))
#define cvGetHistValue_3D( hist, idx0, idx1, idx2 ) / ((float*)(cvPtr3D( (hist)->bins, (idx0), (idx1), (idx2), 0 ))
#define cvGetHistValue_nD( hist, idx ) / ((float*)(cvPtrND( (hist)->bins, (idx), 0 ))
宏 cvGetHistValue_*D 返回 1D, 2D, 3D 或 N-D 直方圖的指定直方塊的指針。對稀疏直方圖,函數(shù)創(chuàng)建一個(gè)新的直方塊,且設(shè)置其為 0,除非它已經(jīng)存在。
發(fā)現(xiàn)最大和最小直方塊
void cvGetMinMaxHistValue( const CvHistogram* hist, float* min_value, float* max_value, int* min_idx=NULL, int* max_idx=NULL );
函數(shù) cvGetMinMaxHistValue 發(fā)現(xiàn)最大和最小直方塊以及它們的位置。任何輸出變量都是可選的。在具有同樣值幾個(gè)極值中,返回具有最小下標(biāo)索引(以字母排列順序定)的那一個(gè)。
歸一化直方圖
void cvNormalizeHist( CvHistogram* hist, double factor );
函數(shù) cvNormalizeHist 通過縮放來歸一化直方塊,使得所有塊的和等于 factor
.
對直方圖取閾值
void cvThreshHist( CvHistogram* hist, double threshold );
函數(shù) cvThreshHist 清除那些小于指定閾值得直方塊
比較兩個(gè)稠密直方圖
double cvCompareHist( const CvHistogram* hist1, const CvHistogram* hist2, int method );
函數(shù) cvCompareHist 采用下面指定的方法比較兩個(gè)稠密直方圖(H1 表示第一個(gè), H2 - 第二個(gè)):
相關(guān) (method=CV_COMP_CORREL): d(H1, H2)=sumI(H'1(I)?H'2(I))/sqrt(sumI[H'1(I)2]?sumI[H'2(I)2])
其中 H'k(I)=Hk(I)-1/N?sumJHk(J)
(N=number of histogram bins) Chi-square(method=CV_COMP_CHISQR): d(H1,H2)=sumI[(H1(I)-H2(I))/(H1(I)+H2(I))] 交叉 (method=CV_COMP_INTERSECT): d(H1,H2)=sumImax(H1(I),H2(I))函數(shù)返回
d(H1,H2) 的值。
為了比較稀疏直方圖或更一般的加權(quán)稀疏點(diǎn)集(譯者注:直方圖匹配是圖像檢索中的常用方法),考慮使用函數(shù) cvCalcEMD 。
拷貝直方圖
void cvCopyHist( const CvHistogram* src, CvHistogram** dst );
函數(shù) cvCopyHist 對直方圖作拷貝。如果第二個(gè)直方圖指針
*dst 是 NULL, 則創(chuàng)建一個(gè)與 src 同樣大小的直方圖。否則,兩個(gè)直方圖必須大小和類型一致。然后函數(shù)將輸入的直方塊的值復(fù)制到輸出的直方圖中,并且設(shè)置取值范圍與 src 的一致。
計(jì)算圖像image(s) 的直方圖
void cvCalcHist( IplImage** image, CvHistogram* hist, int accumulate=0, const CvArr* mask=NULL );
函數(shù) cvCalcHist 計(jì)算單通道或多通道圖像的直方圖。 用來增加直方塊的數(shù)組元素可從相應(yīng)輸入圖像的同樣位置提取。
#include <cv.h> #include <highgui.h> int main( int argc, char** argv )
{
IplImage* src;
if( argc == 2 && (src="http://archive.cnblogs.com/a/2344604/cvLoadImage(argv[1]," rel="nofollow"/>
計(jì)算反向投影
void cvCalcBackProject( IplImage** image, CvArr* back_project, const CvHistogram* hist );
函數(shù) cvCalcBackProject 直方圖的反向投影. 對于所有輸入的單通道圖像同一位置的象素?cái)?shù)組,該函數(shù)根據(jù)相應(yīng)的象素?cái)?shù)組(RGB),放置其對應(yīng)的直方塊的值到輸出圖像中。用統(tǒng)計(jì)學(xué)術(shù)語,輸出圖像象素點(diǎn)的值是觀測數(shù)組在某個(gè)分布(直方圖)下的的概率。 例如,為了發(fā)現(xiàn)圖像中的紅色目標(biāo),可以這么做:
這是 Camshift 彩色目標(biāo)跟蹤器中的一個(gè)逼進(jìn)算法,除了第三步,CAMSHIFT 算法使用了上一次目標(biāo)位置來定位反向投影中的目標(biāo)。
用直方圖比較來定位圖像中的模板
void cvCalcBackProjectPatch( IplImage** image, CvArr* dst, CvSize patch_size, CvHistogram* hist, int method, float factor );
函數(shù) cvCalcBackProjectPatch 通過輸入圖像補(bǔ)丁的直方圖和給定直方圖的比較,來計(jì)算反向投影。提取圖像在 ROI 中每一個(gè)位置的某種測量結(jié)果產(chǎn)生了數(shù)組 image. 這些結(jié)果可以是色調(diào), x 差分, y 差分, Laplacian 濾波器, 有方向 Gabor 濾波器等中 的一個(gè)或多個(gè)。每種測量輸出都被劃歸為它自己的單獨(dú)圖像。
image
圖像數(shù)組是這些測量圖像的集合。一個(gè)多維直方圖
hist
從這些圖像數(shù)組中被采樣創(chuàng)建。最后直方圖被歸一化。直方圖
hist
的維數(shù)通常很大等于圖像數(shù)組
image
的元素個(gè)數(shù)。
在選擇的 ROI 中,每一個(gè)新的圖像被測量并且轉(zhuǎn)換為一個(gè)圖像數(shù)組。在以錨點(diǎn)為“補(bǔ)丁”中心的圖像 image 區(qū)域中計(jì)算直方圖 (如下圖所示)。用參數(shù)norm_factor 來歸一化直方圖,使得它可以與 hist 互相比較。計(jì)算出的直方圖與直方圖模型互相比較,
(hist 使用函數(shù) cvCompareHist ,比較方法是 method=method). 輸出結(jié)果被放置到概率圖像 dst 補(bǔ)丁錨點(diǎn)的對應(yīng)位置上。這個(gè)過程隨著補(bǔ)丁滑過整個(gè) ROI 而重復(fù)進(jìn)行。迭代直方圖的更新可以通過在原直方圖中減除“補(bǔ)丁”已覆蓋的尾象素點(diǎn)或者加上新覆蓋的象素點(diǎn)來實(shí)現(xiàn),這種更新方式可以節(jié)省大量的操作,盡管目前在函數(shù)體中還沒有實(shí)現(xiàn)。
兩個(gè)直方圖相除
void cvCalcProbDensity( const CvHistogram* hist1, const CvHistogram* hist2, CvHistogram* dst_hist, double scale=255 );
函數(shù) cvCalcProbDensity 從兩個(gè)直方圖中計(jì)算目標(biāo)概率密度:
dist_hist(I)=0
if hist1(I)==0
scale
if hist1(I)!=0 && hist2(I)>hist1(I)
hist2(I)*scale/hist1(I) if hist1(I)!=0 && hist2(I)<=hist1(I)
所以輸出的直方塊小于尺度因子。
聯(lián)系客服