calcHist()函数 OPENCV

在opencv中提供了calcHist()函数计算图像的直方图,计算完成后可以采用前面提到的opencv中的绘图函数如rectangle、line()等绘制显示出来.calcHist()函数原型如下:
void cv::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
  • 11

参数解释
. images: 输入的图像或数组,它们的深度必须为CV_8U, CV_16U或CV_32F中的一类,尺寸必须相同。
. nimages: 输入数组个数,也就是第一个参数中存放了几张图像,有几个原数组。
. channels: 需要统计的通道dim,第一个数组通道从0到image[0].channels()-1,第二个数组从image[0].channels()到images[0].channels()+images[1].channels()-1,以后的数组以此类推
. mask: 可选的操作掩码。如果此掩码不为空,那么它必须为8位并且尺寸要和输入图像images[i]一致。非零掩码用于标记出统计直方图的数组元素数据。
. hist: 输出的目标直方图,一个二维数组
. dims: 需要计算直方图的维度,必须是正数且并不大于CV_MAX_DIMS(在opencv中等于32)
. histSize: 每个维度的直方图尺寸的数组
. ranges: 每个维度中bin的取值范围
. uniform: 直方图是否均匀的标识符,有默认值true
. accumulate: 累积标识符,有默认值false,若为true,直方图再分配阶段不会清零。此功能主要是允许从多个阵列中计算单个直方图或者用于再特定的时间更新直方图.

此外calcHist()还有另外两种定义形式,可查询其classIndex进行查看。

在计算图像直方图的时候一般配合minMaxLoc()和normalize()函数,minMaxLoc()函数是用于寻找最值的函数,其定义如下:

void cv::minMaxLoc  (   InputArray      src,
        double *    minVal,
        double *    maxVal = 0,
        Point *     minLoc = 0,
        Point *     maxLoc = 0,
        InputArray      mask = noArray() 
    )   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

参数解释
. src: 输入的单通道数组
. minVal: double类型指针,用于返回最小值的指针,如果不需要返回则设置为NULL
. maxVal: double类型的指针,用于返回最大值指针,如果不需要返回则设置为NULL
. minLoc: 返回最小值位置指针(2D的情况下),如果不需要则设置为NULL
. maxLoc: 返回最大位置指针(2D情况下),如果不需要则设置为NULL
. mask: 可选掩模板。

normalize()函数的作用是将一个数组的值归一化到指定的范围

void cv::normalize  (   InputArray      src,
        InputOutputArray    dst,
        double      alpha = 1,
        double      beta = 0,
        int     norm_type = NORM_L2,
        int     dtype = -1,
        InputArray      mask = noArray() 
    )   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

参数解释
. src: 输入数组
. dst: 输出数组,与src有相同的尺寸
. alpha: 将数组归一化范围的最大值,有默认值1
. beta: 归一化的最小值,有默认值0
. norm_type: 归一化方式,可以查看NormTypes()函数查看详细信息,有默认值NORM_L2
. dtype: 当该值取负数时,输出数组与src有相同类型,否则,与src有相同的通道并且深度为CV_MAT_DEPTH(dtype)
. mask: 可选的掩膜版

示例代码

#include <iostream>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>

using namespace std;
using namespace cv;

int main()
{
    Mat srcImage;
    srcImage = imread("lena.jpg");

    //判断图像是否读取成功
    if(srcImage.empty())
    {
        cout << "图像加载失败!" << endl;
        return -1;
    }
    else
        cout << "图像加载成功!" << endl << endl;

    //分割成三通道图像
    vector<Mat> channels;
    split(srcImage, channels);

    //设定bin数目
    int histBinNum = 255;

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

    bool uniform = true;
    bool accumulate = false;

    //声明三个通道的hist数组
    Mat red_hist, green_hist, blue_hist;

    //计算直方图
    calcHist(&channels[0], 1, 0, Mat(), red_hist, 1, &histBinNum, &histRange, uniform, accumulate);
    calcHist(&channels[1], 1, 0, Mat(), green_hist, 1, &histBinNum, &histRange, uniform, accumulate);
    calcHist(&channels[2], 1, 0, Mat(), blue_hist, 1, &histBinNum, &histRange, uniform, accumulate);

    //创建直方图窗口
    int hist_w = 400;
    int hist_h = 400;
    int bin_w = cvRound((double)srcImage.cols/histBinNum);

    Mat histImage(srcImage.cols, srcImage.rows, CV_8UC3, Scalar(0, 0, 0));

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

    //循环绘制直方图
    for(int i = 1; i < histBinNum; i++)
    {
        line(histImage, Point(bin_w*(i-1), srcImage.rows - cvRound(red_hist.at<float>(i-1))),
            Point(bin_w*(i), srcImage.rows - cvRound(red_hist.at<float>(i))), Scalar(0, 0, 255), 2, 8, 0);
        line(histImage, Point(bin_w*(i-1), srcImage.rows - cvRound(green_hist.at<float>(i-1))),
            Point(bin_w*(i), srcImage.rows - cvRound(green_hist.at<float>(i))), Scalar(0, 255, 0), 2, 8, 0);
        line(histImage, Point(bin_w*(i-1), srcImage.rows - cvRound(blue_hist.at<float>(i-1))),
            Point(bin_w*(i), srcImage.rows - cvRound(blue_hist.at<float>(i))), Scalar(255, 0, 0), 2, 8, 0);
    }

    namedWindow("原图像", WINDOW_AUTOSIZE);
    imshow("原图像", srcImage);

    namedWindow("图像直方图", WINDOW_AUTOSIZE);
    imshow("图像直方图", histImage);

    waitKey(0);

    return 0;
}
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值