Grayscale histogram is the simplest and most useful tool for digital images. This article mainly summarizes the structure and application of cvhistogram in opencv.
The definition of a grayscale histogram is a gray-level function that describes the number of pixels in the gray-level image (or the occurrence frequency of these pixels, the ordinate represents the number (frequency) of gray-level occurrences in the image ). The structure of a one-dimensional histogram is a high-dimensional histogram, which can be understood as a histogram of gray-level distribution of images in each dimension. A two-dimensional histogram is commonly used. For example, the two components of the red-blue histogram represent the gray value of the red image and the gray value of the blue image respectively. Its image coordinates (DR, DB) correspond to the number of pixels with gray level DR in the red light image and gray level dB in the Blu-ray image. This is a digital image based on multi-spectrum-each pixel has multiple variables-two dimensions correspond to each pixel statistical variable. The histogram cvhistogram in opencv. Note that when we understand the meaning of the histogram above, we will think more of it as
"Graph"And then understand the significance of the horizontal and vertical coordinates in the graph. In opencv, we should consider the Histogram
"Data Structure"To understand. Cvhistogram is used in opencv to represent a multi-dimensional histogram (http://www.opencv.org.cn/index.php/Cv%E5%9B%BE%E5%83%8F%E5%A4%84%E7%90%86#CvHistogram ):
[CPP]
View plaincopyprint?
- Typedef struct cvhistogram
- {
- Int type;
- Cvarr * bins; // array pointer for each gray level
- Float thresh [cv_max_dim] [2]; // even Histogram
- Float ** thresh2; // non-even Histogram
- Cvmatnd MAT; // internal data structure of the histogram Array
- }
- Cvhistogram;
Typedef struct cvhistogram {int type; cvarr * bins; // array pointer float thresh [cv_max_dim] [2] for each gray level; // even histogram float ** thresh2; // non-even histogram cvmatnd MAT; // internal data structure of the histogram array} cvhistogram;
This structure looks simple (much less than the iplimage * element ...) In fact, it is not easy to understand.
The type of the first Member is used to specify the type of the second member bins. The cvarr * interface is often seen in opencv and can be used to specify types such as cvmat, cvmatnd, and iplimage. In fact, cvarr * is a pointer to void. In a function, you sometimes need to get the exact type to point to, which requires the type to be specified. Thresh is used to specify the upper and lower bounds of the histogram distribution. For example, [0 255] indicates the distribution of pixels in the image in the gray-level [0 255] interval, and cv_max_dim corresponds to the histogram dimension, if the thresh of the Two-dimensional red-blue histogram is set to [0 255; 100 200], it is to calculate the gray-level distribution of the red image in [0 255] and the blue image in the gray-level [100 200] respectively. Thresh is used to specify the distribution of the even histogram. We understand that each pixel is a "even distribution". In fact, we can also calculate the distribution of pixels in several intervals. If the pixel distribution is measured in two intervals, it corresponds to the upper and lower bounds of [0 255], and the statistical interval of even distribution is the probability of [0 127] [127 255] distribution, this is also why the second dimension of thresh is 2 by default -- it will automatically share the upper and lower bounds; while thresh2 specifies the uneven distribution, which requires the upper and lower bounds of each interval, if you want to calculate the histogram distribution in the range (100,255, 100), you need to specify a dimension of thresh2 as [0 10 255], so it is represented in float ** format. In short, mat stores the histogram information, that is, the histogram distribution probability of our statistics. Create a histogram cvcreatehist () opencv using cvcreatehist () to create a histogram:
[CPP]
View plaincopyprint?
- Cvhistogram * cvcreatehist (
- Int dims, // histogram dimension
- Int * sizes, // dimension of the number of straight tumbler
- Int type, // The format of the Histogram
- Float ** ranges = NULL, // array of the block range in the figure
- Int uniform = 1 // normalized ID
- );
Cvhistogram * cvcreatehist (INT dims, // histogram dimension int * sizes, // int type of the number of vertices in a straight flip chart, // float format of the histogram ** ranges = NULL, // int uniform = 1 in the square range in the figure // normalization mark );
The length of the size array is dims. Each number indicates the number of bin allocated to the corresponding dimension. For example, if dims = 3, [S1, S2, S3] is used in size to specify the number of bins per dimension.
There are two types: cv_hist_array, which means that the histogram data is represented as a multi-dimensional dense array cvmatnd; cv_hist_tree means that the histogram data is represented as a multi-dimensional sparse array cvsparsemat. Ranges is the scope of Thresh, which is complex and hard to understand. Its content depends on the value of uniform. When the value of uniform is 0, it is uniform. If the value is not 0, it is uneven. The function for calculating the image histogram is calchist ():[CPP]
View plaincopyprint?
- Void cvcalchist (
- Iplimage ** image, // enter the image (cvmat is also available **)
- Cvhistogram * Hist, // histogram pointer
- Int accumulate = 0, // cumulative ID. If this parameter is set, the histogram is not cleared at the beginning.
- Const cvarr * mask = NULL // operate the mask to determine which pixel of the input image is counted
- );
Void cvcalchist (iplimage ** image, // input image (cvmat ** can also be used) cvhistogram * Hist, // histogram pointer int accumulate = 0, // accumulative ID. If this parameter is set, the histogram is not cleared at the beginning. Const cvarr * mask = NULL // operate the mask to determine which pixel of the input image is counted );
Note that this function is used to calculate one (or more)Single ChannelThe histogram of the image. To calculate multiple channels, use this function to calculate each single channel of the image. Practice: Use opencv to generate a one-dimensional histogram of an image.[CPP]
View plaincopyprint?
- Int main ()
- {
- Iplimage * src = cvloadimage ("baboon.jpg ");
- Iplimage * gray_plane = cvcreateimage (cvgetsize (SRC), 8, 1 );
- Cvcvtcolor (SRC, gray_plane, cv_bgr2gray );
- Int hist_size = 256; // histogram size
- Int hist_height = 256;
- Float range [] = {0,255}; // grayscale range
- Float * ranges [] = {range };
- // Create a one-dimensional histogram to calculate the even distribution of images in [0, 255] pixels
- Cvhistogram * gray_hist = cvcreatehist (1, & hist_size, cv_hist_array, ranges, 1 );
- // Calculate the one-dimensional histogram of the grayscale image
- Cvcalchist (& gray_plane, gray_hist, 0, 0 );
- // Normalized Histogram
- Cvnormalizehist (gray_hist, 1.0 );
- Int scale = 2;
- // Create a "Graph" of a one-dimensional histogram. The X-axis is grayscale, and the X-axis is the number of pixels (* scale)
- Iplimage * hist_image = cvcreateimage (cvsize (hist_size * scale, hist_height), 8, 3 );
- Cvzero (hist_image );
- // Calculate the maximum straight square in the Histogram
- Float max_value = 0;
- Cvgetminmaxhistvalue (gray_hist, 0, & max_value, 0, 0 );
- // Draw the values of each straight square to the graph respectively
- For (INT I = 0; I
- {
- Float bin_val = cvqueryhistvalue_1d (gray_hist, I); // The probability of pixel I
- Int intensity = cvround (bin_val * hist_height/max_value); // the height to be drawn.
- Cvrectangle (hist_image,
- Cvpoint (I * scale, hist_height-1 ),
- Cvpoint (I + 1) * scale-1, hist_height-intensity ),
- Cv_rgb (255,255,255 ));
- }
- Cvnamedwindow ("graysource", 1 );
- Cvshowimage ("graysource", gray_plane );
- Cvnamedwindow ("H-S histogram", 1 );
- Cvshowimage ("H-S histogram", hist_image );
- Cvwaitkey (0 );
- }
Int main () {iplimage * src = cvloadimage ("baboon.jpg"); iplimage * gray_plane = cvcreateimage (cvgetsize (SRC), 8, 1); cvcvtcolor (SRC, gray_plane, clerk ); int hist_size = 256; // histogram size int hist_height = 256; float range [] = {0,255}; // float * ranges [] = {range }; // create a one-dimensional histogram to calculate the even distribution of images in [0 255] pixels cvhistogram * gray_hist = cvcreatehist (1, & hist_size, cv_hist_array, ranges, 1 ); // calculate the one-dimensional histogram cvcalchist (& gray_plane, gray_hist, 1.0) of the grayscale image; // normalize the histogram cvnormalizehist (gray_hist,); int scale = 2; // create a "Graph" of a one-dimensional histogram. the abscissa is gray level, and the ordinate is the number of pixels (* scale) iplimage * hist_image = cvcreateimage (cvsize (hist_size * scale, hist_height ), 8, 3); cvzero (hist_image); // calculates the maximum straight square float max_value = 0 in the histogram; cvgetminmaxhistvalue (gray_hist, 0, & max_value ); // draw the values of each straight square to the graph for (INT I = 0; I
Test results: correspondingly, we can use the same idea to calculate the histogram of each channel and draw the Pixel Distribution of each channel of the image: Practice: we can also use the opencv example to generate a two-dimensional histogram:[CPP]
View plaincopyprint?
- Iplimage * r_plane = cvcreateimage (cvgetsize (SRC), 8, 1 );
- Iplimage * g_plane = cvcreateimage (cvgetsize (SRC), 8, 1 );
- Iplimage * B _plane = cvcreateimage (cvgetsize (SRC), 8, 1 );
- Iplimage * PLANeS [] = {r_plane, g_plane };
- // Separate the HSV image into different channels
- Cvcvtpixtoplane (SRC, B _plane, g_plane, r_plane, 0 );
- // Generate two-dimensional histogram data structure
- Int r_bins = 256, B _bins = 256;
- Cvhistogram * hist;
- {
- Int hist_size [] = {r_bins, B _bins };
- Float r_ranges [] = {0,255}; // hue is [0,180]
- Float B _ranges [] = {0,255 };
- Float * ranges [] = {r_ranges, B _ranges };
- Hist = cvcreatehist (2, hist_size, cv_hist_array, ranges, 1 );
- }
- // Calculate the histogram of one or more single-channel images (s)
- Cvcalchist (planes, Hist, 0, 0 );
Iplimage * r_plane = cvcreateimage (cvgetsize (SRC), 8, 1); iplimage * g_plane = cvcreateimage (cvgetsize (SRC), 8, 1 ); iplimage * B _plane = cvcreateimage (cvgetsize (SRC), 8, 1); iplimage * PLANeS [] = {r_plane, g_plane }; // separate the HSV image to cvcvtpixtoplane (SRC, B _plane, g_plane, r_plane, 0) in different channels; // generate a two-dimensional histogram data structure int r_bins = 256, B _bins = 256; cvhistogram * hist; {int hist_size [] = {r_bins, B _bins}; float r_ranges [] ={ 0,255 }; // hue is [0,180] float B _ranges [] = {0,255}; float * ranges [] = {r_ranges, B _ranges}; hist = cvcreatehist (2, hist_size, cv_hist_array, ranges, 1);} // calculate the histogram cvcalchist (planes, Hist, 0, 0) of one or more single-channel images (s );
In the preceding figure, we draw a straight square corresponding to each horizontal coordinate. in a two-dimensional chart, we need to draw each point:
[CPP]
View plaincopyprint?
- For (INT h = 0; H <r_bins; H ++ ){
- For (int s = 0; S <B _bins; s ++ ){
- Float bin_val = cvqueryhistvalue_2d (Hist, H, S); // query the value of the straight square
- Int intensity = cvround (bin_val * 255/max_value );
- Cvrectangle (hist_img,
- Cvpoint (H * scale, S * scale ),
- Cvpoint (H + 1) * scale-1, (S + 1) * scale-1 ),
- Cv_rgb (intensity, intensity, intensity ),
- Cv_filled );
- }
- }
For (INT h = 0; H <r_bins; H ++) {for (int s = 0; S <B _bins; s ++) {float bin_val = cvqueryhistvalue_2d (Hist, h, S); // query the value of the straight square int intensity = cvround (bin_val * 255/max_value); cvrectangle (hist_img, cvpoint (H * scale, S * scale ), cvpoint (H + 1) * scale-1, (S + 1) * scale-1), cv_rgb (intensity, intensity, intensity), cv_filled );}}
Generate a two-dimensional histogram: the application of the histogram will be discussed later. Reprinted, please specify the Source: Ghost