• OpenCV学习(24) 直方图(1)


    •       直方图是对数据的统计,并将统计结果分布于一系列预定义的槽中。这里的数据不仅仅指的是灰度值,它可以是任何能有效描述图像特征的数据,比如图像梯度等等。

    •       假设有一个矩阵包含一张图像的信息 (灰度值 0-255),我们已经知道灰度值范围是0-255,假设有16个槽(bin),则有下面的划分:

    • c73157b35da93244fa5489fc51b92217c199bea7

      我们可以统计落入每个槽中像素的数目,并用直方图的形式显示出来。

      Histogram_Calculation_Theory_Hist1

    • 让我们再来了解一下直方图的一些具体细节:

      1. dims: 需要统计的特征的数目, 在上例中, dims = 1 因为我们仅仅统计了灰度值(灰度图像)。
      2. bins: 每个特征空间 子区段 的数目,在上例中, bins = 16
      3. range: 每个特征空间的取值范围,在上例中, range = [0,255]
    •       怎样去统计两个特征呢? 在这种情况下, 直方图就是3维的了,x轴和y轴分别代表一个特征, z轴是掉入 ea59e605b1924251214a4cd4eb6eb4465ffa3565 组合中的样本数目, 同样的方法适用于更高维的情形 (超过2维的很难用可视化的方式显示出来)。

    下面是读取一副图像的灰度图,然后显示它的灰度值统计直方图的代码:

    int main( int argc, char** argv )
    {
    Mat src, dst;

    /// 以单通道方式打开图像
    src = imread( "../lenna.jpg", 0);

    if( !src.data )
    { return -1; }


    /// 设定bin数目
    int histSize[1] = {255};

    /// 设定取值范围 ( R,G,B) )
    float range[] = { 0, 255 } ;
    const float* histRange = { range };

    bool uniform = true; bool accumulate = false;

    //结果直方图
    Mat hist;

    calcHist( &src, 1, 0, Mat(), hist, 1, histSize, &histRange, uniform, accumulate );

    // 创建直方图画布
    int hist_w = 512;
    int hist_h = 512;
    //计算每个bin的像素宽度
    int bin_w = cvRound( (double) hist_w/histSize[0] );

    Mat histImage( hist_w, hist_h, CV_8UC3, Scalar( 0,0,0) );

    /// 将直方图归一化到范围 [ 0, histImage.rows ]
    normalize(hist, hist, 0, histImage.rows, NORM_MINMAX, -1, Mat() );


    /// 在直方图画布上画出直方图,线宽为bin_w
    for( int i = 0; i < histSize[0]; i++ )
    {
    line( histImage, Point( bin_w*(i), hist_h - cvRound(hist.at<float>(i)) ) ,
    Point( bin_w*(i), hist_h),
    Scalar( 0, 0, 255), bin_w, 8, 0 );
    }

    /// 显示直方图
    namedWindow("calcHist Demo", CV_WINDOW_AUTOSIZE );
    imshow("calcHist Demo", histImage );

    waitKey(0);

    return 0;

    }

          OpenCV中的直方图计算函数,参数比较多,第一个参数是指向图像矩阵的指针,之所以是指针,是因为OpenCV中,可以统计多个图像的直方图,并把结果累加起来,我们的代码中只有一副图像,所以取&src。第二个参数就是指统计图像的数量,本程序中为1。第三个参数表示对某个通道进行直方图统计,我们读入的是灰度图,只有一个通道,所以值为0 。第四个参数是掩码。第五个参数是输出的直方图结果矩阵。第六个参数是直方图的维数。第七个参数是每个维度的取值范围,我们是单通道图像灰度值直方图,所以取值范围是[0 ,255],通常这个参数是个二维指针。

    //计算直方图
    //第二个参数1表示只对一副图像进行直方图处理
    //第三个参数表示只处理channel 0,对多个channel的图像,可以选1,2等等。
    //第四个参数Mat(),表示不使用掩码
    //hist是直方图结果
    //第六个参数1表示是1维直方图
    //第七个参数,直方图bin的数目
    //第八个参数是像素取值范围,第九个参数是各维取值范围相同,第十个参数是是否累加多副图像的统计结果,如果处理多个图像,需要这个参数
    calcHist( &src, 1, 0, Mat(), hist, 1, histSize, &histRange, uniform, accumulate );

    程序执行后效果如下:

    image

    程序源代码:工程文件FirstOpenCV18

  • 相关阅读:
    机器学习十大算法之EM算法
    如何利用OpenSSL生成证书
    2018中国云原生用户大会:网易云爆料完整微服务的研发过程
    漫话中文分词
    10分钟快速构建汽车零售看板
    聊一聊整车厂的那些事——售后配件业务
    网易有数的“正确”使用方式——洞察数据中隐藏的故事
    深入浅出“跨视图粒度计算”--3、EXCLUDE表达式
    深入浅出“跨视图粒度计算”--2、INCLUDE表达式
    深入浅出“跨视图数据粒度计算”--1、理解数据的粒度
  • 原文地址:https://www.cnblogs.com/mikewolf2002/p/3403700.html
Copyright © 2020-2023  润新知