Opencv开发笔记(二):计算图像的直方图

图像是由像素组成的,在一个单通道的灰度图像中,每个像素的值是在0~255(白色-黑色)之间。直方图是一个简单的图表,它统计出了一幅图像或一组图像中拥有给定数值的像素量。所以一个灰度图像的直方图有256有条目,0条目的给出的值为0的像素个数,1条目给出的值为1的像素个数,以此类推。也可以对直方图所有条目进行求和,则得到像素的总和,也可以归一化,归一化以后所有项之和为1。在Opencv中计算直方图可以使用cv::calcHist函数来统计,为了使用简单,一下我们进行封装一下,先封装一个类来处理单通道的灰度图像:

#ifndef HISTOGRAM_H
#define HISTOGRAM_H
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv.hpp>
using namespace cv;

class HistogramGray {
private:
    int histSize[1];//项的数量
    float hranges[2];//像素的最小及最大值
    const float *ranges[1];
    int channels[1];//一个通道
public:
    HistogramGray(){
        //准备单通道的直方图参数
        histSize[0]=256;
        hranges[0]=0.0;
        hranges[1]=255.0;
        ranges[0]=hranges;
        channels[0]=0;
    }
    //计算灰度图单通道的直方图
    cv::MatND getHistogram(const cv::Mat &image){
        cv::MatND hist;
        //计算直方图
        cv::calcHist(&image,//输入图像
                     1,//计算单张图像的直方图
                     channels,//通道数量
                     cv::Mat(),//不使用图像作为掩码。如果要统计整幅图像的直方图就把它设为None。但是如果你想统计图像某一部分的直方图的话,你就需要制作一个掩模图像,并使用它。
                     hist,//返回的直方图
                     1,//灰度图的直方图
                     histSize,//项的数量
                     ranges);//像素值范围
        return hist;
    }
    //计算单通道直方图,并返回直方图统计图像
    cv::Mat getHistogramGrayImage(const cv::Mat &image){
        //首先计算直方图
        cv::MatND hist = getHistogram(image);

        //获取最大值和最小值
        double maxVal=0;
        double minVal=0;
        cv::minMaxLoc(hist,&minVal,&maxVal,0,0);

        //显示直方图图像
        cv::Mat histImg(histSize[0],histSize[0],CV_8U,cv::Scalar(255));//显示为黑色
        //设置最高点nbins的90%
        int hpt = static_cast<int>(0.9*histSize[0]);
        //每条条目都绘制一条垂直的线
        for(int h = 0 ; h<histSize[0];h++){
            float binVal = hist.at<float>(h);
            int intensity = static_cast<int>(binVal*hpt/maxVal);
            //两点之间绘制一条线
            cv::line(histImg,cv::Point(h,histSize[0]),cv::Point(h,histSize[0]-intensity),cv::Scalar::all(0));
        }
        return histImg;
    }
};

#endif // HISTOGRAM_H

dims:需要统计的特征数目。(如果仅统计了灰度值,则dims=1,如果统计了BGR三色,则dims=3)
bins:每个特征空间子区段的数目。(直方图中,每一竖条表示某一值或一区间,则该直方图的bins=16)
range:要统计特征的取值范围。(我们将[0,255]区间分成了16个子区间,其中range=[0,255])
接下来我们测试一下,测试代码如下:

    Mat image = imread("gray.jpg");
    if(image.empty())
    {
        namedWindow("can not find image ");
        waitKey(5000);
        return -1;
    }
    HistogramGray h;
    namedWindow("Histogram");
    imshow("MyImage",h.getHistogramGrayImage(image));
    while(1)
        waitKey(5000);

计算并以图像形式输出。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LCS-312

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值