【計(jì)算機(jī)視覺】OpenCV中直方圖處理函數(shù)簡(jiǎn)述

計(jì)算直方圖calcHist

直方圖是對(duì)數(shù)據(jù)集合的統(tǒng)計(jì) ,并將統(tǒng)計(jì)結(jié)果分布于一系列預(yù)定義的bins中。這里的數(shù)據(jù)不僅僅指的是灰度值 ,統(tǒng)計(jì)數(shù)據(jù)可能是任何能有效描述圖像的特征。
假設(shè)有一個(gè)矩陣包含一張圖像的信息 (灰度值 0-255):


gray
gray

既然已知數(shù)字的范圍包含256個(gè)值, 我們可以將這個(gè)范圍分割成子區(qū)域(稱作 bins),如:


bins
bins

然后再統(tǒng)計(jì)掉入每一個(gè)bin_{i}的像素?cái)?shù)目。采用這一方法來統(tǒng)計(jì)上面的數(shù)字矩陣,我們可以得到下圖( x軸表示 bin, y軸表示各個(gè)bin中的像素個(gè)數(shù))。
hist1
hist1

直方圖可以統(tǒng)計(jì)的不僅僅是顏色灰度,它可以統(tǒng)計(jì)任何圖像特征(如梯度,方向等等)。

直方圖具體細(xì)節(jié)

dims: 需要統(tǒng)計(jì)的特征的數(shù)目,在上例中,dims = 1因?yàn)槲覀儍H僅統(tǒng)計(jì)了灰度值(灰度圖像)
bins: 每個(gè)特征空間子區(qū)段的數(shù)目,在上例中,bins = 16
range: 每個(gè)特征空間的取值范圍,在上例中,range = [0,255]

OpenCV的直方圖計(jì)算

OpenCV提供了一個(gè)簡(jiǎn)單的計(jì)算數(shù)組集(通常是圖像或分割后的通道)的直方圖函數(shù)calcHist。支持高達(dá)32維的直方圖。

void calcHist(
const Mat* arrays,          // 圖像源數(shù)組,同樣深度(CV_8U or CV_32F),同樣大小
int narrays,                // 圖片個(gè)數(shù)
const int* channels,        // 通道
InputArray mask,            // 掩碼圖像
OutputArray hist,           // 返回的直方圖
int dims,                   // 直方圖的維數(shù)
const int* histSize,        // 每一維上直方圖的個(gè)數(shù)
const float** ranges,       // 像素值的范圍
bool uniform=true, 
bool accumulate=false );

說明:

channels - 用來計(jì)算直方圖的channels的數(shù)組
mask - 掩碼。如果mask不為空,那么它必須是一個(gè)8位(CV_8U)的數(shù)組,并且它的大小的和arrays[i]的大小相同,值為1的點(diǎn)將用來計(jì)算
dim - 直方圖的維數(shù)。必須為正,并且不大于CV_MAX_DIMS(當(dāng)前的OpenCV版本中為32,即最大可以統(tǒng)計(jì)32維的直方圖)
histSize - 在每一維上直方圖的個(gè)數(shù)。簡(jiǎn)單把直方圖看作一個(gè)一個(gè)的豎條的話,就是每一維上豎條的個(gè)數(shù)
ranges - 用來進(jìn)行統(tǒng)計(jì)的范圍

反投影直方圖

反向投影是一種記錄給定圖像中的像素點(diǎn)如何適應(yīng)直方圖模型像素分布的方式。
簡(jiǎn)單的講,所謂反向投影就是首先計(jì)算某一特征的直方圖模型,然后使用模型去尋找圖像中存在的該特征。

void calcBackProject(
const Mat* arrays, 
int narrays, 
const int* channels, 
InputArray hist, 
OutputArray backProject, 
const float** ranges, 
double scale=1, bool uniform=true );

hist - 輸入直方圖
backProject - 反投影向量,這是一個(gè)單通道的向量,和arrays[0]具有相同的大小和深度

下面使用膚色直方圖為例來解釋反向投影的工作原理:
使用模型直方圖(代表手掌的皮膚色調(diào))來檢測(cè)測(cè)試圖像中的皮膚區(qū)域,

  • 對(duì)測(cè)試圖像中的每個(gè)像素 ( p(i,j) ),獲取色調(diào)數(shù)據(jù)并找到該色調(diào)( h(i,j), s(i,j) )在直方圖中的bin的位置
  • 查詢 模型直方圖 中對(duì)應(yīng)的bin( h(i,j), s(i,j) )并讀取該bin的數(shù)值
  • 將此數(shù)值儲(chǔ)存在新的圖像中(BackProjection)。 你也可以先歸一化 模型直方圖 ,這樣測(cè)試圖像的輸出就可以在屏幕顯示了
  • 通過對(duì)測(cè)試圖像中的每個(gè)像素采用以上步驟, 得到 BackProjection 結(jié)果圖


    backProjection
    backProjection
  • 使用統(tǒng)計(jì)學(xué)的語言, BackProjection 中儲(chǔ)存的數(shù)值代表了測(cè)試圖像中該像素屬于皮膚區(qū)域的概率。比如以上圖為例, 亮起的區(qū)域是皮膚區(qū)域的概率更大(事實(shí)確實(shí)如此),而更暗的區(qū)域則表示更低的概率

閾值化

閾值是最簡(jiǎn)單的圖像分割的方法。
應(yīng)用舉例:從一副圖像中利用閾值分割出我們需要的物體部分(當(dāng)然這里的物體可以是一部分或者整體)。這樣的圖像分割方法是基于圖像中物體與背景之間的灰度差異,而且此分割屬于像素級(jí)的分割。
為了從一副圖像中提取出我們需要的部分,應(yīng)該用圖像中的每一個(gè)像素點(diǎn)的灰度值與選取的閾值進(jìn)行比較,并作出相應(yīng)的判斷。(注意:閾值的選取依賴于具體的問題。即:物體在不同的圖像中有可能會(huì)有不同的灰度值。)
一旦找到了需要分割的物體的像素點(diǎn),我們可以對(duì)這些像素點(diǎn)設(shè)定一些特定的值來表示。(例如:可以將該物體的像素點(diǎn)的灰度值設(shè)定為:‘0’(黑色),其他的像素點(diǎn)的灰度值為:‘255’(白色);當(dāng)然像素點(diǎn)的灰度值可以任意,但最好設(shè)定的兩種顏色對(duì)比度較強(qiáng),方便觀察結(jié)果)。


Threshold_Example
Threshold_Example

閾值類型

Threshold Type 1
Threshold Type 1

Threshold Type 2
Threshold Type 2

Threshold Type 3
Threshold Type 3

Threshold Type 4
Threshold Type 4

Threshold Type 5
Threshold Type 5

閾值A(chǔ)PI

double threshold(
InputArray src, 
OutputArray dst, 
double thresh, 
double maxVal, 
int thresholdType);

均值漂移(Mean Shift)算法函數(shù)

該函數(shù)利用了迭代物體搜索算法,它要以一個(gè)物體的反射直方圖(back projection)和初始位置作為輸入。
搜索窗口的重心向反射直方圖的質(zhì)心(mass center)移動(dòng),該過程不斷的重復(fù),直到達(dá)到了迭代的次數(shù)(criteria.maxCount),或者窗口中心小于一個(gè)閾值(criteria.epsilon)。

int meanShift(
InputArray probImage,       // Back projection of the object histogram
Rect& window,               // Initial search window
TermCriteria criteria       // Stop criteria for the iterative search algorithm.
);

Camshift算法函數(shù)

該函數(shù)首先利用meanShift()函數(shù)找到物體的中心,然后調(diào)整窗口的大小并找到最優(yōu)的旋轉(zhuǎn)角度。該函數(shù)返回一個(gè)rotated rectangle數(shù)據(jù)結(jié)構(gòu)(包含物體的位置,大小和旋轉(zhuǎn)角度)。下一次搜索窗口的位置可以通過RotatedRect::boundingRect()得到。

RotatedRect CamShift(
InputArray probImage,       // Back projection of the object histogram
Rect& window,               // Initial search window
TermCriteria criteria       // Stop criteria for the underlying meanShift()
);

TermCriteria模板類

該類是作為迭代算法的終止條件使用的,其構(gòu)造函數(shù)需要三個(gè)參數(shù):一個(gè)是類型,第二個(gè)參數(shù)為迭代的最大次數(shù),最后一個(gè)是特定的閾值。

TermCriteria(int type, int maxCount, double epsilon);

類型有CV_TERMCRIT_ITER、CV_TERMCRIT_EPS、CV_TERMCRIT_ITER+CV_TERMCRIT_EPS,分別代表著迭代終止條件為達(dá)到最大迭代次數(shù)終止,迭代到閾值終止,或者兩者都作為迭代終止條件。

參考資料

OpenCV Histograms API文檔
直方圖之calcHist使用
直方圖之calcHist使用(補(bǔ))
OpenCV 教程 imgproc模塊
反向投影
閾值操作

轉(zhuǎn)載請(qǐng)注明作者Jason Ding及其出處
Github主頁(http://jasonding1354.github.io/)
CSDN博客(http://blog.csdn.net/jasonding1354)
簡(jiǎn)書主頁(http://www.itdecent.cn/users/2bd9b48f6ea8/latest_articles)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容