###### 计算灰度图的像素直方图，并显示（c++）

#include"stdafx.h"
#include<iostream>
#include<highgui.hpp>
#include<cv.hpp>
#include<imgproc.hpp>

using namespace std;
using namespace cv;

Mat getHistImage(const MatND& hist)
{
double maxValue = 0;
double minValue = 0;
int a = 0;
for (int i = 0; i < hist.rows; i++)
{
for (int j = 0; j < hist.cols; j++)
{
float b = hist.at<float>(i, j);
a += 1;
cout << b << endl;
}
}
minMaxLoc(hist, &minValue, &maxValue, 0, 0);//找到全局最小、最大的像素值数目
cout << "max: " << maxValue << "min: " << minValue << endl;
int histSize = hist.rows;
Mat histImage(histSize, histSize, CV_8UC3, Scalar(255,255,255));

int hpt = static_cast<int>(0.9*histSize);
int total = 0;
Scalar color(172, 172, 150);//BGR
for (int h = 0; h < histSize; h++)
{
float binVal = hist.at<float>(h);//读取对应灰度级的像素个数,一共1000000个
cout << h<<": "<<binVal << endl;
total += binVal;
int intensity = static_cast<int>(binVal*hpt /maxValue);//按比例运算，当前数目*230/最大数目,与除以总数只是比例不同
line(histImage, Point(h, histSize), Point(h, histSize - intensity),color);
//rectangle(histImage, Point(h, histSize), Point(h + 1, histSize - intensity), color);
}
cout << total << endl;//total = 1000000
return histImage;
}

int main(int argc, _TCHAR* argv[])
{
int a = src.channels();//a = 3通道
imshow("b", src);
if (!src.data)
{
cout << "no picture!\n";
exit(1);
}
cvtColor(src, src, CV_BGR2GRAY, 0);
a = src.channels();//a = 1通道
imshow("d", src);
int image_count = 1;//要计算直方图的图像的个数
int channels[1] = { 0};//图像的通道'

Mat out;//计算所得直方图
int dims = 1;//得到直方图的维数
int histsize[1] = { 256 };//直方图横坐标的子区间数
float hrange[2] = { 0, 255 };//区间的总范围
const float *ranges[1] = { hrange };//指针数组

calcHist(&src, image_count,channels, Mat(), out, dims, histsize, ranges);

Mat last = getHistImage(out);
imshow("ddd", last);
waitKey();
return 0;
}

void calcHist(const Mat* images, int nimages, const int* channels, InputArray mask, OutputArray hist, int dims, const int* histSize, const float** ranges, booluniform=true, bool accumulate=false )

const Mat* images：

int nimages：

const int* channels：

OutArray hist：

int dims：

const int* histSize：

const float** ranges：

void minMaxLoc(InputArray src, double* minVal, double* maxVal=0, Point* minLoc=0, Point* maxLoc=0, InputArray mask=noArray())

src – Source single-channel array.

minVal – Pointer to the returned minimum value. NULL is used if not required.

maxVal – Pointer to the returned maximum value. NULL is used if not required.

minLoc – Pointer to the returned minimum location (in 2D case). NULL is used if not required.

maxLoc – Pointer to the returned maximum location (in 2D case). NULL is used if not required.

Mat(int rows, int cols, int type, const Scalar& s)
Mat的构造函数，行，列，类型，每一元素值

void cvLine( CvArr* img,CvPoint pt1, CvPoint pt2, CvScalar color,int thickness=1, int line_type=8, int shift=0 );

8 (or 0) - 8-connected line（8邻接)连接 线。
4 - 4-connected line(4邻接)连接线。
CV_AA - antialiased 线条。

static_cast

c++中Mat类的rows和cols与c中image的height和width一样
dim表示维度，一般都是2为，channels为维度，c++中是通过Mat::channels()函数来查看。

for (int i = 0; i < hist.rows; i++)
{
for (int j = 0; j < hist.cols; j++)
{
float b = hist.at<float>(i, j);//这里at函数里的必须是float类型，如果是int的话，就相当于(int&)float,输出的数没有意义，数值很大
a += 1;
cout << b << endl;
}
}

0: 0
1: 0
2: 0
3: 0
4: 0
5: 0
6: 0
7: 0
8: 0
9: 0
10: 0
11: 0
12: 0
13: 0
14: 0
15: 0
16: 0
17: 0
18: 0
19: 0
20: 0
21: 0
22: 0
23: 0
24: 0
25: 0
26: 0
27: 0
28: 0
29: 0
30: 0
31: 0
32: 0
33: 0
34: 1
35: 1
36: 0
37: 0
38: 2
39: 3
40: 3
41: 8
42: 13
43: 19
44: 18
45: 28
46: 38
47: 52
48: 58
49: 76
50: 81
51: 105
52: 132
53: 175
54: 201
55: 269
56: 257
57: 344
58: 413
59: 528
60: 598
61: 898
62: 1042
63: 1330
64: 1580
65: 2431
66: 135547
67: 2503
68: 1612
69: 1233
70: 1012
71: 688
72: 562
73: 398
74: 287
75: 240
76: 173
77: 141
78: 120
79: 76
80: 77
81: 100
82: 58
83: 59
84: 61
85: 61
86: 72
87: 96
88: 111
89: 121
90: 131
91: 163
92: 217
93: 305
94: 425
95: 574
96: 741
97: 1084
98: 1520
99: 2191
100: 2985
101: 4345
102: 6866
103: 11409
104: 25454
105: 171666
106: 10226
107: 4380
108: 2887
109: 1814
110: 1257
111: 860
112: 649
113: 437
114: 430
115: 348
116: 345
117: 341
118: 309
119: 296
120: 310
121: 273
122: 336
123: 282
124: 277
125: 285
126: 289
127: 252
128: 347
129: 285
130: 283
131: 287
132: 259
133: 280
134: 265
135: 243
136: 288
137: 294
138: 258
139: 292
140: 294
141: 285
142: 279
143: 254
144: 276
145: 274
146: 261
147: 281
148: 318
149: 268
150: 347
151: 291
152: 351
153: 382
154: 450
155: 545
156: 647
157: 825
158: 1146
159: 1506
160: 2344
161: 3881
162: 6737
163: 122569
164: 6361
165: 4283
166: 6113
167: 12657
168: 144433
169: 3991
170: 1631
171: 932
172: 566
173: 406
174: 235
175: 174
176: 191
177: 176
178: 161
179: 136
180: 130
181: 136
182: 164
183: 135
184: 137
185: 123
186: 119
187: 130
188: 160
189: 145
190: 129
191: 142
192: 149
193: 138
194: 134
195: 129
196: 159
197: 164
198: 156
199: 169
200: 195
201: 225
202: 216
203: 208
204: 245
205: 300
206: 307
207: 433
208: 485
209: 663
210: 816
211: 1117
212: 1579
213: 2227
214: 3199
215: 4209
216: 6493
217: 210867
218: 5713
219: 3937
220: 2781
221: 1980
222: 1400
223: 979
224: 702
225: 514
226: 351
227: 217
228: 260
229: 168
230: 129
231: 107
232: 80
233: 75
234: 62
235: 55
236: 37
237: 28
238: 27
239: 13
240: 13
241: 13
242: 8
243: 6
244: 1
245: 1
246: 1
247: 0
248: 1
249: 0
250: 0
251: 0
252: 0
253: 0
254: 0
255: 0
total：1000000

1000000。 用于显示直方图的高度为 256,因此要给他一个最高限制0.9 * 256 = 230.

划线显示 划矩形显示

#### 关于直方图规范化的C++编程实现_2015_7_24

2015-07-24 14:07:09

#### c++ 画图像直方图

2013-05-30 13:45:06

#### 灰度直方图 源代码 C++

2009年03月10日 120KB 下载

#### 创建灰度图像直方图（c）

2017-06-13 20:23:28

#### 【OpenCV】数字图像灰度直方图

2012-05-25 11:05:02

#### 【从零学习openCV】使用直方图统计像素

2014-11-12 10:17:32

#### 【OpenCV学习笔记 007】使用直方图统计像素

2016-09-16 12:49:16

#### 彩色直方图各通道像素值统计及可视化

2016-10-25 08:26:37

#### opencv3 绘制一维直方图-灰度直方图的绘制

2015-11-05 22:49:53

#### 图像处理大型科普——图像直方图

2016-05-07 18:16:58