计算图像直方图(OpenCV内置实现)

记录生活,分享技术!

图像直方图:图像由像素构成,每个有不同数值。对于每个灰度,都有不同数量的像素分布在图像内,具体取决于图片内容。

C++代码如下:

1、头文件

#pragma once
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/video/background_segm.hpp"
#include"opencv2/opencv.hpp"

#include <iostream>

using namespace std;
using namespace cv;

class Histogram1D
{
public:
    Histogram1D();
    ~Histogram1D();

     static Mat getHistogram(const Mat &image);  // 得到梯度直方图的数值
     static Mat getHistogramImage(const cv::Mat &image, int zoom);  // 得到数值,并显示成图像的类型
     static Mat getImageOfHistogram(const Mat &hist, int zoom);  // 画图,上面方法调用


private:
    int histSize[1]; // 直方图中的箱子的数量
    float hranges[2]; // 值范围
    const float* ranges[1];  // 值范围的指针
    int channels[1];  // 要检查的通道数量

};

2、cpp主文件

#include "Histogram1D.h"

Histogram1D::Histogram1D(){
    // 准备一维直方图的默认参数
    histSize[0] = 256;
    hranges[0] = 0.0;
    hranges[1] = 256.0;
    ranges[0] = hranges;
    channels[0] = 0;
}


Histogram1D::~Histogram1D()
{
}

cv::Mat Histogram1D::getHistogram(const cv::Mat &image){
    cv::Mat hist;
    Histogram1D h1;

    // 计算直方图
    cv::calcHist(&image, 1, h1.channels, cv::Mat(), hist, 1, h1.histSize, h1.ranges);

    return hist;
}

cv::Mat Histogram1D::getHistogramImage(const cv::Mat &image, int zoom = 1){  // 得到数值,并显示成图像的类型
    // 首先计算直方图
    Mat hist = getHistogram(image);

    // 创建图像
    return getImageOfHistogram(hist, zoom);
}

cv::Mat Histogram1D::getImageOfHistogram(const Mat &hist, int zoom){  // 画图,上面方法调用, 直方图图像
    // 取得箱子值得最大值和最小值
    double maxVal = 0;
    double minVal = 0;
    cv::minMaxLoc(hist, &minVal, &maxVal, 0, 0);

    // 取得直方图的大小
    int histSize = hist.rows;

    // 用于显示直方图的方形图像
    cv::Mat histImg(histSize*zoom, histSize*zoom, CV_8U, cv::Scalar(255));
    // 设置最高点为90%(即图像高度)的箱子个数
    int hpt = static_cast<int>(0.9*histSize);
    // 为每个箱子画垂直线
    for (int h = 0; h < histSize; h++){
        float binVal = hist.at<float>(h);
        if (binVal>0)
        {
            int intensity = static_cast<int>(binVal*hpt / maxVal);
            cv::line(histImg, cv::Point(h*zoom, histSize*zoom),
                cv::Point(h*zoom, (histSize - intensity)*zoom),
                cv::Scalar(0), zoom);
        }
    }
    return histImg;

}

3、main函数调用函数

// 直方图对象
    Histogram1D h;
    // 计算并显示直方图
    cv::namedWindow("Histogram");
    cv::imshow("Histogram", h.getHistogramImage(image, 1));

    waitKey(0);
    //system("pause");
    return 0;

4、运行结果

参考:OpenCV计算机视觉编程攻略 (第2版)

猜你喜欢

转载自my.oschina.net/u/3702502/blog/1636170