您的位置:首页 > 编程语言 > C语言/C++

【Opencv】【C++】 Opencv之calcHist() 计算直方图

2017-09-28 20:10 369 查看
OpenCV 2.4.13

calcHist 通过图像计算直方图

函数声明如下:

[cpp] view
plain copy

void calcHist( const Mat* images, int nimages,  

               const int* channels, InputArray mask,  

               OutputArray hist, int dims, const int* histSize,  

               const float** ranges, bool uniform=true, bool accumulate=false );  

//1.输入的图像数组   2.输入数组的个数             3.通道数              4.掩码                5.直方图           

//6.直方图维度       7.直方图每个维度的尺寸数组   8.每一维数组的范围    9.直方图是否是均匀   10.配置阶段不清零  

1.图像数组 

2.图像数组个数

3.图像的通道数

4.图像掩码

5.计算得到的直方图

6.直方图的维度(灰度直方图为1维)

7.直方图每一维度上的数组个数(bin 的个数)

8.每一维进行直方图统计的数组的范围  范围如 0~256 表示统计 0~255的数组 这里注意 (0,256) 包含0而不包含256 包含的是256-1

9.是否均匀的统计(个人理解为是否统计的每个bin包含相同的灰度级 可能理解有误)

10.这个还真不明白 待学习。。。 

以下做个了计算直方图的例子 并进行直方图的显示

[cpp] view
plain copy

#include <opencv2/opencv.hpp>  

  

int main()  

{  

    cv::Mat src = imread("image.jpg", cv::IMREAD_GRAYSCALE); //读取灰度图像  

    cv::Mat hist; //将要获得的直方图  

    int imgNum = 1;//图像数  

    int histDim = 1;//直方图维度  

    int histSize = 256; //直方图每一维度bin个数  

    float range[] = { 0, 256 };//每一维度的统计范围  

    const float* histRange = { range };//因为我们计算1维直方图所以 只有一个rang  

    bool uniform = true;//  

    bool accumulate = false;//  

    cv::calcHist(&src, imgNum, 0, cv::Mat(), hist, histDim, &histSize, &histRange, uniform, accumulate);  

  

    int scale = 2;//控制图像的宽大小  

    cv::Mat histImg(cv::Size(histSize*scale, histSize), CV_8UC1);//用于显示直方图  

  

    uchar* pImg = nullptr;  

    for (size_t i = 0; i < histImg.rows; i++) //初始化图像为全黑  

    {  

        pImg = histImg.ptr<uchar>(i);  

        for (size_t j = 0; j < histImg.cols; j++)  

        {  

            pImg[j] = 0;  

        }  

    }  

  

    double maxValue = 0; //直方图中最大的bin的值  

    cv::minMaxLoc(hist, 0, &maxValue, 0, 0); //minMaxLoc可以计算最大值最小值以及其对应的位置 这里求最大值  

  

    int histHeight = 256; //要绘制直方图的最大高度  

  

    float* p = hist.ptr<float>(0);  

    for (size_t i = 0; i < histSize; i++)//进行直方图的绘制  

    {  

        float bin_val = p[i];  

        int intensity = cvRound(bin_val*histHeight / maxValue);  //要绘制的高度   

        for (size_t j = 0; j < scale; j++) //绘制直线 这里用每scale条直线代表一个bin  

        {  

            cv::line(histImg, cv::Point(i*scale + j , histHeight - intensity), cv::Point(i*scale + j, histHeight - 1), 255);  

        }  

        //cv::rectangle(histImg, cv::Point(i*scale, histHeight - intensity), cv::Point((i + 1)*scale, histHeight - 1), 255); //利用矩形代表bin  

    }  

    cv::namedWindow("直方图");  

    cv::imshow("直方图", histImg);  

    cv::waitKey(0);  

    cv::destroyWindow("直方图");  

    //cv::destroyAllWindows();  

    return 0;  

}  

参考:http://blog.csdn.net/sydnash/article/details/7451039

            http://blog.csdn.net/xfortius/article/details/8829246
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: