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

上一篇:聊聊 Web 项目二维码生成的最佳姿势


下一篇:[LeetCode] Largest Rectangle in Histogram 直方图中最大的矩形