1. 程式人生 > >Opencv中integral計算積分圖

Opencv中integral計算積分圖

Paul Viola和Michael Jones在2001年首次將積分圖應用在影象特徵提取上,在他們的論文“Rapid Object Detection using a Boosted Cascade of Simple Features”中,積分圖被當作一種新的影象特徵表徵方式,可以把檢測的Haar特徵非常高效的計算出來,用於實時人臉檢測系統。

積分圖是一種能夠描述全域性資訊的矩陣表示方法,其構造方式是積分影象上位置(i,j)處的值ii(i,j)是原影象(i,j)左上角方向所有畫素的和。

利用積分圖可以可以快速的計算影象上某一區域內的畫素和,如下圖:

要計算區域D內的畫素和,只需要獲取到積分圖上1、2、3/4點各自的畫素值,分別表述為ii(1)、ii(2)、ii(3)、ii(4),則區域D的畫素和=ii(4)+ii(1)-ii(2)-ii(3)。

傳統的計算畫素和的方式需要遍歷區域D內所有的畫素,再執行累加,計算量隨著區域D面積的增大而增大,而對積分圖方式來說,只需要在計算積分圖之後,通過簡單幾次加減運算就可以得到某一區域內“畫素和”這一特徵,計算速度非常快,並且這種速度的提升效果隨著區域面積的增大和計算次數的增多表現的更為明顯。

Opencv中使用integral函式計算積分圖。


void integral( InputArray src, OutputArray sum, int sdepth=-1 );

第一個引數src,可以使灰度圖或RGB彩色圖,單通道和三通道均可作為輸入,但每個通道的精度必須是8位int或32位、64位浮點型;
第二個引數sum,積分圖,若輸入src是灰度圖,則積分圖也是灰度圖,若輸入src是RGB三通道圖,則積分圖sum也是RGB三通道彩色。sum的影象深度是32位整型或32位、64位浮點型,這取決於第三個引數sdepth的定義;

第三個引數sdepth,定義積分圖的深度(depth),32位整型或者32位、64位浮點型。注意影象的深度跟影象的通道數是無關的,相關概念可以參看這裡:Opencv Mat矩陣中data、size、depth、elemSize、step等屬性的理解 ;

所以在使用sum之前,宣告即可,可以不事先定義Mat矩陣的大小和資料型別。


#include "highgui/highgui.hpp"
#include "imgproc/imgproc.hpp"
 
using namespace cv;
 
int main(int argc,char *argv[])
{
    Mat image=imread(argv[1]);    
    //cvtColor(image,image,CV_RGB2GRAY); //原影象是三通道,積分圖也是三通道
    Mat imageIntegral;
    integral(image,imageIntegral,CV_32F); //計算積分圖
    normalize(imageIntegral,imageIntegral,0,255,CV_MINMAX);  //歸一化,方便顯示
    Mat imageIntegralNorm;
    convertScaleAbs(imageIntegral,imageIntegralNorm); //精度轉換為8位int整型
    imshow("Source Image",image);
    imshow("Integral Image",imageIntegralNorm);
    waitKey();
}


原圖:

積分圖:

顯示的積分圖是經過歸一化後的。可以看到從左上角到右下角,影象是越來越亮的,也就是說積分圖上畫素值是越來越大的。

積分圖的影象通道數跟原始影象儲存一致,當計算積分圖的原始影象是彩色影象時,積分圖也是彩色影象,這時候積分圖計算的不是灰度,而是顏色:


--------------------- 
作者:-牧野- 
來源:CSDN 
原文:https://blog.csdn.net/dcrmg/article/details/52589749 
版權宣告:本文為博主原創文章,轉載請附上博文連結!