Calculate the pixel histogram of the grayscale image and display it (c++)

Program function, after a color image is converted into a grayscale image, the number of pixels of each grayscale value (0-255) is analyzed and displayed in the form of a histogram.

This time it is written in C++, many functions are very unfamiliar and it took me a long time.

#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);//Find the global minimum and maximum number of pixel values
	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);//Read the number of pixels corresponding to the gray level, a total of 1000000
		cout << h<<": "<<binVal << endl;
		total += binVal;
		int intensity = static_cast<int>(binVal*hpt /maxValue);//Proportional operation, the current number*230/maximum number, which is only different from dividing by the total number
		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[])
{
	Mat src = imread("D:/2.jpg",-1);
	//IplImage* image = cvLoadImage("D:/timg.jpg");
	int a = src.channels();//a = 3 channels
	imshow("b", src);
	if (!src.data)
	{
		cout << "no picture!\n";
		exit(1);
	}
	cvtColor(src, src, CV_BGR2GRAY, 0);
	a = src.channels();//a = 1 channel
	imshow("d", src);
	int image_count = 1;//The number of images to calculate the histogram
	int channels[1] = { 0};//The channel of the image'

	Mat out;//Computed histogram
	int dims = 1;//Get the dimension of the histogram
	int histsize[1] = { 256 };//Number of sub-intervals on the abscissa of the histogram
	float hrange[2] = { 0, 255 };//The total range of the interval
	const float *ranges[1] = { hrange };//Array of pointers
	
	calcHist(&src, image_count,channels, Mat(), out, dims, histsize, ranges);
	
	Mat last = getHistImage(out);
	imshow("ddd", last);
	waitKey();
	return 0;
}



Several key functions are introduced:

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 )

Calculate the histogram, count the number of pixels of each gray level, and the output is a multi-dimensional matrix
const Mat* images:
Pointer for the input image.
int nimages:
The number of images for which the histogram is to be calculated. This function can calculate the histogram for multiple images, we usually only act on a single image, so usually nimages=1.
const int* channels:
The channel of the image, it is an array, if it is a grayscale image, channels[1]={0}; if it is a color image, channels[3]={0,1,2}; if it is just a color image, the second The histogram of channels, then channels[1]={1};
IuputArray mask:
It is a mask image used to determine which points are involved in the calculation. It is a good parameter in practical applications. By default, we all set it to an empty image, namely: Mat().
OutArray hist:
Calculated histogram
int dims:
The dimension of the resulting histogram, 1-dimensional for grayscale images and 3-dimensional for color images.
const int* histSize:
The number of bins on the abscissa of the histogram. If it is 10, it will be divided into 10 parts on the abscissa, and then the sum of the pixels in each interval will be counted.
const float** ranges:
This is a two-dimensional array that indicates the range of each interval. The last two parameters have default values. The uniform parameter indicates whether the histogram is equidistant. The last parameter is related to the display and storage of the histogram under multiple images.


void minMaxLoc(InputArray src, double* minVal, double* maxVal=0, Point* minLoc=0, Point* maxLoc=0, InputArray mask=noArray())
Find the largest and smallest values ​​in a matrix and their coordinates
src – Source single-channel array.
minVal
– Pointer to the returned minimum value. NULL is used if not required. Pointer to the minimum value
maxVal
– Pointer to the returned maximum value. NULL is used if not required.
pointer to the maximum value
minLoc – Pointer to the returned minimum location (in 2D case). NULL is used if not required.
2D coordinate of the minimum value
maxLoc – Pointer to the returned maximum location (in 2D case). NULL is used if not required.
Maximum value 2D coordinate
mask – Optional mask used to select a sub-array.
Mask


Mat(int rows, int cols, int type, const Scalar& s)
Mat constructor, row, column, type, value per element


void cvLine( CvArr* img,CvPoint pt1, CvPoint pt2, CvScalar color,int thickness=1, int line_type=8, int shift=0 );
The first parameter img: the image of the line to be drawn;
the second parameter pt1: the starting point of the straight line
The second parameter pt2: the end point of the straight line
The third parameter color: the color of the straight line eg: Scalor(0,0,255)
The fourth parameter Parameter thickness=1: line thickness
The fifth  parameter line_type=8,
   8 (or 0) - 8-connected line (8 adjacent) connecting lines.
   4 - 4-connected line (4 adjacent) connecting lines.
   CV_AA - antialiased lines.
The sixth parameter: the number of decimal places of the coordinate point.


static_cast
Usage: static_cast < type-id > ( expression_r_r )
This operator casts expression_r_r to the type-id type, but there is no runtime type checking to ensure safe conversion. It is mainly used in the following ways: It is
used to convert pointers or references between base classes and subclasses in the class hierarchy. It is safe to perform up-casting (converting a pointer or reference of a subclass to the representation of the base class); when performing downcasting (converting a pointer or reference of a base class to a representation of the subclass), it is unsafe because there is no dynamic type checking. .
Used for conversion between basic data types, such as converting int to char, and converting int to enum. The security of this conversion should also be guaranteed by the developer.
Converts a null pointer to a null pointer of the target type.
Convert any type of expression to void type.
Note: static_cast cannot convert the const, volatile, or __unaligned attributes of expression_r_r.
Note: static_cast cannot convert the const, volatile, or __unaligned attributes of expression_r_r.
More detailed: http://blog.sina.com.cn/s/blog_4a84e45b0100f57m.html


It is worth noting that
the rows and cols of the Mat class in c++ are the same as the height and width of the image in c.
dim represents the dimension, generally 2 is 2, and channels is the dimension. In c++, it is viewed through the Mat::channels() function.
Note that the color map dim is also two, and the channels are three.


In order to test the effect of calculating the histogram function, I put out each element in the calculated matrix.

for (int i = 0; i < hist.rows; i++)
{
	for (int j = 0; j < hist.cols; j++)
	{
		float b = hist.at<float>(i, j);//The at function must be of type float. If it is int, it is equivalent to (int&)float. The output number is meaningless and the value is very large
		a += 1;
		cout << b << endl;
	}
}
The result is as follows:
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

It can be seen that the maximum value is 210867, and the minimum value is 0.
The total number of pixels is 1000000, because the original image is 1000*1000


If the pixel value is 4567980, it is converted into hexadecimal to 45b3ac, and each two-digit conversion into decimal is: 69 176 172


The height of each gray value in the corresponding RGB histogram is the number of pixels of the gray level / the maximum number of pixels in the picture *230 is calculated, and its proportion is calculated for the largest number, in fact, it is the same as for the total number, and the total number is always
1,000,000. The height used to display the histogram is 256, so give him a maximum limit of 0.9 * 256 = 230.


Finally, it can also be displayed by drawing a rectangle

                                                                         

     Line display Draw rectangle display





Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324400019&siteId=291194637