天天看點

OpenCV學習(25) 直方圖(2)

      在OpenCV中,也可以對三通道的圖像,比如BGR,HSV等計算直方圖。方法和計算單通道圖像直方圖相似,下面的代碼描述了如何計算一個BGR三通道圖像的直方圖,需要注意的是,因為是三通道,每個通道取值都是[0,255],是以bin的數目達到了256*256*256,這時如果使用普通三維矩陣輸出直方圖結果,需要很大的空間,是以我們通常使用稀疏矩陣來儲存輸出結果。因為稀疏矩陣隻儲存非零值,這樣可以節省存儲空間。

int main( int argc, char** argv )

    {

    Mat src, dst;

    /// 打開圖像

    src = imread( "../lenna.jpg");

    if( !src.data )

        { return -1; }

    /// 設定bin數目

    int histSize[3];

    float hranges[2];

    const float* ranges[3];

    int channels[3];

    // BGR彩色直方圖

    // 準備一個color直方圖資料, BGR格式

    histSize[0]= histSize[1]= histSize[2]= 256;

    hranges[0]= 0.0;    // BGR分量的範圍

    hranges[1]= 255.0;

    ranges[0]= hranges; // BGR三個通道都是0-255範圍

    ranges[1]= hranges;

    ranges[2]= hranges;

    channels[0]= 0;       // 三通道

    channels[1]= 1;

    channels[2]= 2;

    //結果直方圖

    cv::SparseMat histo(3,histSize,CV_32F);

    // 計算直方圖

    cv::calcHist(&src,

        1,            // 僅一副圖像的直方圖

        channels,    // 使用的channel

        cv::Mat(),    // 沒有使用mask

        histo,        // 計算的結果

        3,           // 3D直方圖

        histSize,    // bin的數量

        ranges       // BGR像素的範圍

        );

    SparseMatConstIterator_<float>     it = histo.begin<float>(), it_end = histo.end<float>();

    double s = 0;

    int dims = histo.dims();

    int count=0;

    for(; it != it_end; ++it)

        {

       // 列印出稀疏矩陣的值

        const SparseMat::Node* n = it.node();

        printf("(");

        for(int i = 0; i < dims; i++)

            printf("%d%s", n->idx[i], i < dims-1 ? ", " : ")");

        printf(": %g\n", it.value<float>());

        s += *it;

        count++;

        }

    printf("Element sum is %g\n", s);

    printf("element num is %d\n", count);

    while(1)

        waitKey(0);

    return 0;

    }

程式運作效果如下,可以看到實際上稀疏矩陣中隻存儲了69579項,也就是圖像隻有69579種顔色。

OpenCV學習(25) 直方圖(2)

程式代碼:工程FirstOpenCV19

繼續閱讀