Histogram
#include "opencv.hpp" class Histogram1D{ private: int histSize[1]; //项的数量 float hranges[2]; //像素的最小及最大值 const float *ranges[1]; int channels[1]; //仅用到一个通道 public: Histogram1D(){ //准备1D直方图的参数 histSize[0] = 256; hranges[0] = 0.0; hranges[1] = 255.0; ranges[0] = hranges; channels[0] = 0; //默认情况下,我们考察0号通道 } cv::Mat getHistogram(const cv::Mat &image); cv::Mat getHistogramImage(const cv::Mat &image); };
#include "Histogram.h" //计算1D直方图 cv::Mat Histogram1D::getHistogram(const cv::Mat &image){ cv::MatND hist; //计算直方图 计算任意像素类型的多通道图像 cv::calcHist(&image, 1, //计算单张图像的直方图 channels, //通道数量 cv::Mat(), //不使用图像作为掩码 hist, //返回的直方图 1, //这是1D的直方图 histSize, //项的数量 ranges //像素值的范围 ); return hist; } //计算1D直方图,并返回一幅图像 cv::Mat Histogram1D::getHistogramImage(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; } int ShowHist(){ //1.装载图像 cv::Mat srcImage = cv::imread("grayHorse.jpg"); if (!srcImage.data) return 0; //2.histogram对象 Histogram1D h; /* //3.计算直方图 cv::MatND histo = h.getHistogram(srcImage); //这里的histo对象是一个拥有256个条目的一维数组 //4.遍历每个条目 for (int i = 0; i < 256; i++) { cout << "Value" << i << "=" << histo.at<float>(i) << endl; } */ //5.以图形方式显示直方图 //cv::namedWindow("Histogram"); //cv::imshow("Histogram", h.getHistogramImage(srcImage)); //6.使用一个阈值来创建二值图像分离背景和前景 cv::Mat thresholded; cv::threshold(srcImage, thresholded, 60, 255, cv::THRESH_BINARY); cv::namedWindow("thresholded"); cv::imshow("thresholded", thresholded); cv::waitKey(); system("pause"); return 0; }