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_castUsage: 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