CV:利用積分圖像統(tǒng)計(jì)ROI的像素
? ?1.分析 ? ?
? ? ?直方圖的計(jì)算方法,即遍歷圖像的全部像素并累計(jì)每個(gè)強(qiáng)度值在圖像中出現(xiàn)的次數(shù)。我們也看到,有時(shí)只需要計(jì)算圖像中某個(gè)特定區(qū)域的直方圖。實(shí)際上,累計(jì)圖像某個(gè)子區(qū) 域內(nèi)的像素總數(shù)是很多計(jì)算機(jī)視覺(jué)算法中的常見(jiàn)過(guò)程。現(xiàn)在假設(shè)需要對(duì)圖像中的多個(gè)感興趣區(qū)域 計(jì)算幾個(gè)此類(lèi)直方圖,這些計(jì)算過(guò)程馬上都會(huì)變得非常耗時(shí)。這種情況下,有一個(gè)工具可以極大 地提高統(tǒng)計(jì)圖像子區(qū)域像素的效率,那就是積分圖像。 使用積分圖像統(tǒng)計(jì)圖像感興趣區(qū)域的像素是一種高效的方法。它在程序中的應(yīng)用非常廣泛, 例如用于計(jì)算基于不同大小的滑動(dòng)窗口。 本節(jié)將講解積分圖像背后的原理。這里的目標(biāo)是說(shuō)明如何只用三次算術(shù)運(yùn)算,就能累加一個(gè)矩形區(qū)域的像素。

在累加多個(gè)圖像區(qū)域的像素時(shí),積分圖像顯得非常有用。通常來(lái)說(shuō),要獲得感興趣區(qū)域全部 像素的累加和,常規(guī)的代碼如下所示:?
// 打開(kāi)圖像?
cv::Mat image= cv::imread("bike55.bmp",0);?
?// 定義圖像的 ROI(這里為騎自行車(chē)的女孩)?
int xo=97, yo=112; ?int width=25, height=30; ?
cv::Mat roi(image,cv::Rect(xo,yo,width,height)); ?
// 計(jì)算累加值 // 返回一個(gè)多通道圖像下的 Scalar 數(shù)值?
cv::Scalar sum= cv::sum(roi); ?
? ? ? cv::sum 函數(shù)只是遍歷區(qū)域內(nèi)的所有像素,并計(jì)算累加和。使用積分圖像后,只需要三次 加法運(yùn)算即可實(shí)現(xiàn)該功能。不過(guò)你得先計(jì)算積分圖像,代碼如下所示:?
// 計(jì)算積分圖像 cv::Mat integralImage; ?
cv::integral(image,integralImage,CV_32S); ?
可以在積分圖像上用簡(jiǎn)單的算術(shù)表達(dá)式獲得同樣的結(jié)果(下一節(jié)會(huì)詳細(xì)解釋?zhuān)?,代碼為:
// 用三個(gè)加/減運(yùn)算得到一個(gè)區(qū)域的累加值?
int sumInt= integralImage.at<int>(yo+height,xo+width)– ?integralImage.at<int>(yo+height,xo)– ?integralImage.at<int>(yo,xo+width)+ ?integralImage.at<int>(yo,xo); ?
? ? ? 兩種做法得到的結(jié)果是一樣的。但計(jì)算積分圖像需要遍歷全部像素,因此速度比較慢。關(guān)鍵在于,一旦這個(gè)初始計(jì)算完成,你只需要添加四個(gè)像素就能得到感興趣區(qū)域的累加和,與區(qū)域大小無(wú)關(guān)。 因此,如果需要在多個(gè)尺寸不同的區(qū)域上計(jì)算像素累加和,最好采用積分圖像。
2.解析:
? ? ?目標(biāo)就是計(jì)算出ROI區(qū)域D的面積。
我們通過(guò)ROI矩形坐標(biāo)將x0+w,y0+h劃分為ABCD四個(gè)區(qū)域,每個(gè)點(diǎn)對(duì)應(yīng)的數(shù)值就是之前圖像所有點(diǎn)的積分?jǐn)?shù)值,因此通過(guò)數(shù)學(xué)公式可以求出D的面積。

對(duì)于面積D=S(x0+w,y0+h)-S(x0,y0+h)-S(x0+w,y0)+S(x0,y0)
=(SA+SB+SC+SD)-(SA+SB+SC)-(SA+SB)+(SA)=SD
通過(guò)以上的操作,非常容易就求出了ROI的像素。
3. 總結(jié):
? ? ? ?取圖像左上方的全部像素計(jì)算累加和,并用這個(gè)累加和替換圖像中的每一個(gè)像素,用這種方式得 到的圖像稱(chēng)為積分圖像。計(jì)算積分圖像時(shí),只需對(duì)圖像掃描一次。實(shí)際上,當(dāng)前像素的積分值等 于上方像素的積分值加上當(dāng)前行的累計(jì)值。因此積分圖像就是一個(gè)包含像素累加和的新圖像。為 防止溢出,積分圖像的值通常采用 int 類(lèi)型(CV_32S)或 float 類(lèi)型(CV_32F)。
參考來(lái)源于:OpenCV計(jì)算機(jī)視覺(jué)編程攻略