Basic Learning notes-opencv (19): histogram Calculation of Image Sequences

Source: Internet
Author: User
Tags float range ranges

 

  Preface

Histogram is a very important tool in computer vision. opencv provides many functions related to histogram processing. The most basic function is to calculate the histogram function calchist (). The histogram is also introduced in the previous blog: opencv (4) of basic learning notes: histogram usage learning. However, in my research, we need to calculate the one-dimensional histogram feature of multiple images, and each image should have its own mask matrix, and start to think of calchist () provided by opencv () the function can implement this function, because one of the overload functions has an inputarrayofarrays parameter. Do you think this is not enough to process multiple images? After careful research, I found that the function actually implemented is different from my needs. Therefore, I need to write a function independently to complete this function.

Development Environment: opencv2.4.3 + qtcreator2.5.1

 

  Lab Basics

First, let's take a look at the most important of the three overload functions calchist () in opencv for histogram calculation, as shown below:

  Cv_exports void calchist (const mat * images, int nimages, const int * channels, inputarray mask, outputarray Hist, int dims, const int * histsize, const float ** ranges, bool uniform = true, bool accumulate = false );

Parameter 1 indicates the source image sequence to be used to calculate the histogram. Therefore, multiple images of the same size and data type can be used to calculate the histogram features.

Parameter 2 indicates how many images in the image sequence are used to calculate the histogram.

The appearance of parameter 3 mainly takes into account that each input image may be multi-channel. For example, the RGB image is a 3-channel image, so statistically speaking, an RGB image is actually three single-channel images, and its nature is also for a single image when the histogram is calculated. Although there are many images in the input image sequence images, not every channel of each image is used for computation. Therefore, the function of parameter 3 is to specify which channels of images are used for calculation (subsequent interpretations assume that the image sequence is like 3 channels, some images may have multiple channels used for calculation, and some images may not have been used even one channel). In this case, parameter 3 stores the serial number of the channel, then, the channel number of the first image in the Image Sequence Images (assuming the 3 channels in the image) is, 2; the image sequence of the second image in the images is 3, 4, 5, and so on.

Parameter 4 is a mask operation, which specifies which pixels of each image are used to calculate the histogram. This mask Matrix cannot set a specific mask for a specific image, therefore, they are treated equally here.

Parameter 5 is the matrix that stores the calculated histogram result. It may be a multi-dimensional matrix.

Parameter 6 is the dimension of the histogram to be calculated.

Parameter 7 is the size of each dimension of the histogram to be calculated, that is, the number of bins in each dimension.

Parameter 8 is the range of each dimension of the histogram to be calculated. If the uniform of parameter 9 is true, the size of parameter 8 is 2, the element value indicates the upper and lower limits of each dimension. If the uniform of parameter 9 is false, the size of parameter 8 is the number of bin, that is, the value of parameter 7. The element values in parameter 8 must be manually specified. That is, the coordinate values of each dimension are not necessarily uniform and must be specified manually.

If the value 9 is true, each dimension of the histogram to be calculated has a uniform value according to its range and size. If the value is false, it indicates that each dimension of the histogram is not evenly distributed. For details, refer to the interpretation of parameter 8.

If the value of parameter 10 is false, The hist In the histogram output matrix is cleared when this function is used. If the value is true, The hist uses calchist () when the function is not cleared, the calculation result is accumulated into the value saved previously.

When using this function, note that if the default parameter is uniform = true, then the ranges size must be twice the size of histsize, and the channels size must be equal to the dims dimension.

It can be understood from the above that the value in channels has specified which single-channel images are used to calculate the target histogram. Therefore, once the channels size is determined, the corresponding histogram dimension is determined, therefore, we cannot use multiple images to calculate a one-dimensional histogram.

 

The form of another overload function is as follows:

  Cv_exports_w void calchist (inputarrayofarrays images, const vector <int> & channels, inputarray mask, outputarray Hist, const vector <int> & histsize,Const vector <float> & ranges, bool accumulate = false );

Although the first parameter is an image sequence, we cannot use this function to calculate a one-dimensional histogram of these image sequences. In this function, you do not need to specify a parameter as in the previous function to indicate how many images are involved in the computation, because the images already exists. In addition, this function does not need to specify the dimension of the histogram like the preceding function, because this overload function indicates that the dimension of the histogram is the same as that of channels by default. Finally, the uniform in this overload function is set to true inside the function, and each dimension of the surface histogram must be evenly distributed.

In short, the above two functions are used to calculate the histogram of multiple images. The Histogram can be multidimensional, and the dimension is equal to the number of images in the single channel used to calculate the histogram.

 

The self-designed function for calculating the histogram is:

  Void calchist (vector <mat> image_array, vector <mat> mask_array, const int * histsize, const float ** ranges );

The internal implementation of the function actually calls the calchist () function of opencv.

Parameter 1 is the sequence of images that need to be used to calculate one-dimensional histograms.

Parameter 2 is the mask sequence corresponding to the image sequence in parameter 1.

Parameter 3 corresponds to the histogram size when each image is computed;

Parameter 4 corresponds to the horizontal coordinate range of the histogram when each graph is calculated.

This function is used to calculate the one-dimensional histogram of the Image Sequence image_array. Whether the pixels in image_array are involved in the calculation is determined by the mask sequence mask_array. The size of the abscissa of the calculated one-dimensional histogram is stored in histsize, And the range is stored in ranges (in fact, there is no need to use a pointer here, because within this function is an image to calculate the image in the image sequence, and the histogram calculation of all images shares a final histogram, all histsize requires only one value ).

 

  Opencv knowledge point summary:

Use the cv_assert () function instead of cv_assert () when using the internal judgment conditions of opencv ().

Experiments show that although the histogram calculated by the calchist () function is stored in Hist, hist is of the mat type and if it is a one-dimensional histogram, then, hist is a column vector.

 

 

  Lab results

If we do not apply the mask matrix, that is, each pixel is involved in the work, if it is the following figure:

  

 

The histogram distribution is as follows:

 

If the mask matrix is the middle part of the image, that is, the length and frame centered on the image center are half the rectangle of the original image, that is, the valid pixel of the mask is half of the original image. The histogram image to be calculated is as follows:

  

  

Then its histogram is shown as follows:

  

 

From the above four pictures, we can see that the general background of the two images is similar and there is a black area in the image, but during the first test, the black area is located in the lower right corner of the image, and the experiment is to calculate the histogram of the entire image. Therefore, the black area in the histogram results occupies a large part, but at the same time, because there are other pixels in the background, therefore, the ratio of histograms is also quite large. In the second experiment, only the histogram of the middle area of the image is calculated, because the black area is also moved to the middle, therefore, the histogram shows that the vast majority of the results are black pixels.

The preceding simple explanations show that the self-designed histogram calculation should work (although this experiment is not strictly explained ).

 

  The main part of the experiment code is the annotation (the appendix contains the Engineering Code ):

  Chistogram. h:

#ifndef CHISTOGRAM_H#define CHISTOGRAM_H#include <opencv2/core/core.hpp>#include <vector>using namespace cv;class CHistogram{public:    CHistogram();    ~CHistogram();    void Init();    void CalcHist(vector<Mat> image_array, vector<Mat> mask_array, const int *histsize, const float **ranges);    Mat getHistogram1DImage(const Mat &hist, Size hist_image_size, Scalar color);    Mat cr_hist_trained, cb_hist_trained;private:};#endif //

 

Chistogram. cpp:

# Include "chistogram. H "# include <opencv2/CORE/core. HPP> # include <opencv2/highgui. HPP> # include <opencv2/imgproc. HPP> # include <vector> # define number_train_hand_skin_model 20 using namespace CV; chistogram: chistogram () {} chistogram ::~ Chistogram () {}/* this function is used to calculate the one-dimensional histogram of multiple images. Each image has a corresponding mask matrix */void chistogram :: calchist (vector <mat> image_array, vector <mat> mask_array, const int * histsize, const float ** ranges) {int image_array_size = image_array.size (); int channels [] = {0}; For (INT I = 0; I <image_array_size; I ++) {// The last parameter is true, it is because we need to accumulate some calchist (& image_array [I], 1, channels, mask_array [I], cr_hist_trained, 1, histsize, ranges, true, true) in hist );} // normalize the calculated histogram long sum_hist_value = 0; For (INT I = 0; I <cr_hist_trained.rows; I ++) for (Int J = 0; j <cr_hist_trained.cols; j ++) sum_hist_value + = cr_hist_trained.at <float> (I, j); cr_hist_trained/= sum_hist_value;}/* this function is used to display a one-dimensional histogram */MAT chistogram :: gethistogram1dimage (const mat & Hist, size hist_image_size, scalar color) {mat hist_image (hist_image_size, cv_8uc3); // defines the image int padding = 10; int display_width = hist_image_size.width-2 * padding; int display_height = hist_image_size.height-2 * padding; double max_hist_value = 0.0; minmaxloc (Hist, null, & max_hist_value ); // find the maximum value float height_percent = display_height/max_hist_value In the histogram; // calculate the appropriate proportion of the height display. Int bin_width = display_width/(Hist. rows); // because hist is a column vector/* bar chart of the histogram drawn */For (int K = 0; k <Hist. rows; k ++) {point up (padding + K * bin_width, hist_image_size.height-padding-height_percent * Hist. at <float> (k); point bottom (padding + K * bin_width, hist_image_size.height-padding); line (hist_image, bottom, up, color, bin_width);} return hist_image ;}

 

Main. cpp:

# Include <opencv2/CORE/core. HPP> # include <opencv2/imgproc. HPP> # include <opencv2/highgui. HPP> # include <iostream> # include <vector> # include "chistogram. H "# define train_hand_color_frames 20 using namespace STD; using namespace CV; int histsize [] = {256}; float range [] = {0,256 }; const float * ranges [] = {range}; long test_number = 0; chistogram histogram; int main () {vector <mat> image_array, Ma Sk_array; MAT image, hist_display_image, mask, test_image; int number = 0; videocapture cam (0); If (! Cam. isopened () return 0; cam> image; cv_assert (! Image. empty (); mask. create (image. size (), cv_8uc1); mask. setto (0); rect (image. cols/4, image. rows/4, image. cols/2, image. rows/2); // calculate the histogram in the middle of the image // rect (0, 0, image. rows, image. cols); // calculate all histogram rectangle (mask, rect, 255,-1); While (true) {cam> image; cv_assert (! Image. empty (); Number ++; If (number <= train_hand_color_frames) {image_array.push_back (image); // obtain the image matrix sequence mask_array.push_back (mask ); // obtain the sequence of mask matrix} If (train_hand_color_frames = Number) {histogram. calchist (image_array, mask_array, histsize, ranges); // calculate a one-dimensional histogram} If (number> train_hand_color_frames) number = train_hand_color_frames + 1; /* display the normalized histogram */If (number = train_hand_color_frames) {// obtain the image hist_display_image = histogram with a histogram. gethistogram1dimage (histogram. cr_hist_trained, size (660,480), scalar (255, 0, 0); imshow ("hist", hist_display_image); test_image = image. clone (); imshow ("test", test_image);} imshow ("image", image); waitkey (30);} return 0 ;}

 

 

  Experiment summary:Histogram is a useful tool. In programming, you should be familiar with functions related to histogram operations in opencv.

 

 

  Appendix:Download the lab project code.

 

 

  References:

Basic Learning notes-opencv (4): histogram Learning

Http://blog.csdn.net/caiqi1123/article/details/8146858

 

 

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.