别人的代码:
先码上,以后再研究
https://blog.csdn.net/wangjia2575525474/article/details/116304854?spm=1001.2014.3001.5501
(原作者博文)
#include <opencv2/opencv.hpp>
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <iostream>
#include <math.h>
#include <vector>
using namespace std;
using namespace cv;
int main()
{
//图像源获取及判断
cv::Mat Image, ImageGray;
Image = imread("F://download//第三章图片//Fig0314(a)(100-dollars).tif");
if (Image.empty())
return -1;
cv::imshow("Image", Image);
//转换为灰度图像
cv::cvtColor(Image, ImageGray, COLOR_RGB2GRAY);
//定义直方图参数
const int channels[1] = { 0 };
const int histSize[1] = { 256 };
float pranges[2] = { 0,255 };
const float*ranges[1] = { pranges };
cv::MatND hist;
//计算直方图
cv::calcHist(&ImageGray, 1, channels, cv::Mat(), hist, 1, histSize, ranges);
/*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,直方图再分配阶段不会清零。此功能主要是允许从多个阵列中计算单个直方图或者用于再特定的时间更新直方图.
dims: 需要统计的特征的数据,上面的例子中,dims=1因为我们仅仅统计了灰度值(灰度图像)
b. bins:每个特征空间子区段的数据,上面的例子中bins=16
c. range: 每个特征空间的取值范围,在上面的例子中range=[0,255]
*/
//初始化画布参数
int hist_w = 500;
int hist_h = 500;
int nHistSize = 255; //小方块的高
//区间
int bin_w = cvRound((double)hist_w / nHistSize); //cvRound():返回跟参数最接近的整数值,即四舍五入;用一种舍入的方法将输入浮点数转换成整数
cv::Mat histImage(hist_w, hist_h, CV_8UC3, cv::Scalar(0, 0, 0)); //histimage的矩阵
//将直方图归一化到[0,hisImage.rows]
normalize(hist, hist, 0, histImage.rows, cv::NORM_MINMAX, -1, cv::Mat());
/*src: 输入数组
dst: 输出数组,与src有相同的尺寸
.alpha : 将数组归一化范围的最大值,有默认值1
.beta : 归一化的最小值,有默认值0
.norm_type : 归一化方式,可以查看NormTypes()函数查看详细信息,有默认值NORM_L2
.dtype : 当该值取负数时,输出数组与src有相同类型,否则,与src有相同的通道并且深度为CV_MAT_DEPTH(dtype)
.mask : 可选的掩膜版*/
//在直方图画布上画出直方图
for (int i = 1; i < nHistSize; i++)
{
line(histImage, cv::Point(bin_w*(i - 1), hist_h - cvRound(hist.at<float>(i - 1))),
cv::Point(bin_w*(i), hist_h - cvRound(hist.at<float>(i))),
cv::Scalar(0, 0, 255), 2, 8, 0); // cv::Scalar的构造函数是cv::Scalar(v1, v2, v3, v4),前面的三个参数是依次设置BGR的,和RGB相反,第四个参数设置图片的透明度。
/*void line(Mat& img, Point pt1, Point pt2, const Scalar& color, int thickness=1, int lineType=8, int shift=0)
参数:
img: 要绘制线段的图像。
pt1: 线段的起点。
pt2: 线段的终点。
color: 线段的颜色,通过一个Scalar对象定义。
thickness: 线条的宽度。
lineType: 线段的类型。可以取值8, 4, 和CV_AA, 分别代表8邻接连接线,4邻接连接线和反锯齿连接线。默认值为8邻接。为了获得更好地效果可以选用CV_AA(采用了高斯滤波)。
shift: 坐标点小数点位数。*/
}
//显示直方图
cv::imshow("histImage", histImage);
waitKey(0);
return 0;
}