My opencv Study Notes (15): Use reverse projection histograms to find specific content

Source: Internet
Author: User

What is a reverse projection histogram? Simply put, in each vertex (x, y) of the grayscale image, replace it with the bin value of its corresponding histogram (that is, the number of pixels falls in the bin. Therefore, if the bin value is large, the reverse projection result will be brighter, otherwise it will be darker.

From a statistical point of view, the value of the pixel point of the Back-output image is the probability of the observed Array under a certain distribution (histogram.

Therefore, we have obtained the histogram of an object. We can calculate its reverse projection in another image to determine whether the object exists in this image.

Opencv provides a function for calculating the reverse projection histogram: calcbackproject is used to calculate the reverse projection of an image for a given histogram.

The code below:

The following is a class for calculating the grayscale image histogram:

# If! Defined histogram # define histogram # include <opencv2/CORE/core. HPP> # include <opencv2/imgproc. HPP> # include <iostream> using namespace STD; using namespace CV; Class histogram1d {PRIVATE: // number of points in the histogram int histsize [1]; // The histogram range float hranges [2]; // the pointer to this range const float * ranges [1]; // The channel int channels [1]; public: // constructor histogram1d () {histsize [0] = 256; hranges [0] = 0.0; hranges [1] = 255.0; ranges [0] = hranges; channels [0] = 0;} mat gethistogram (const mat & image) {mat hist; // calculate the histogram function // The parameter is the source image (sequence) address, number of input images, number of channels, mask, output result, histogram dimension, size of each dimension, value range of each dimension: calchist (& image, 1, channels, MAT (), hist, 1, histsize, ranges); // although this function has many parameters, it is only used for Grayscale Images or color images. // However, allow multiple images to be specified by specifying a multi-channel image // 6th Parameters specify the histogram dimension return hist;} mat gethistogramimage (const mat & image) {// calculate the histogram mat hist = gethistogram (image); // obtain the maximum and minimum values. Double maxval = 0; double minval = 0; // minmaxloc is used to obtain the maximum and minimum values, the following two parameters are the positions of the minimum and maximum values. 0 indicates that minmaxloc (Hist, & minval, & maxval,) is not required. // The canvas that displays the histogram: the background color is white mat histimg (histsize [0], histsize [0], cv_8u, scalar (255 )); // set the highest point to 90% of the total bin count // int hpt = static_cast <int> (0.9 * histsize [0]); int hpt = static_cast <int> (histsize [0]); // draw a line for each Bin (INT h = 0; H 

 

The following class is used to calculate the histogram of a color image:

# If! Defined colorhistogram # define colorhistogram # include <opencv2/CORE/core. HPP> # include <opencv2/imgproc. HPP> using namespace CV; Class colorhistogram {PRIVATE: int histsize [3]; float hranges [2]; const float * ranges [3]; int channels [3]; public: // constructor colorhistogram () {histsize [0] = histsize [1] = histsize [2] = 256; hranges [0] = 0.0; hranges [1] = 255.0; ranges [0] = hranges; ranges [1] = hranges; ranges [2] = hrange S; channels [0] = 0; channels [1] = 1; channels [2] = 2;} // calculate the color image histogram mat gethistogram (const mat & image) {mat hist; // BGR histogram hranges [0] = 0.0; hranges [1] = 255.0; channels [0] = 0; channels [1] = 1; channels [2] = 2; // calculate calchist (& image, 1, channels, MAT (), Hist, 3, histsize, ranges); Return hist ;} // calculate the color histogram mat gethuehistogram (const mat & image) {mat hist; MAT hue; // convert to HSV space cvtcolor (image, hue, cv_bgr2hsv ); // set the hranges parameter used by the 1-Dimensional Histogram [0] = 0.0; hranges [1] = 180.0; channels [0] = 0; // calculate the histogram calchist (& hue, 1, channels, MAT (), Hist, 1, histsize, ranges); return hist;} // reduce the color mat colorreduce (const mat & image, int DIV = 64) {int n = static_cast <int> (log (static_cast <double> (DIV)/log (2.0); uchar mask = 0xff <n; MAT _ <vec3b>:: const_iterator it = image. begin <vec3b> (); MAT _ <vec3b>: const_iterator itend = image. end <vec3b> (); // sets the output image mat result (image. rows, Image. Cols, image. Type (); MAT _ <vec3b >:: iterator itr = result. Begin <vec3b> (); For (; it! = Itend; ++ it, ++ itr) {(* itr) [0] = (* It) [0] & Mask) + DIV/2; (* itr) [1] = (* It) [1] & Mask) + DIV/2; (* itr) [2] = (* It) [2] & Mask) + DIV/2;} return result ;};# endif

The colorreduce function is used to reduce the color of the color image. The color image histogram class also includes a function for calculating the hue component histogram in the HSV space. It will be used in the main function

With the histogram function, let's look at the class for calculating the reverse projection histogram:

# If! Defined contentfinder # define contentfinder # include <opencv2/CORE/core. HPP> # include <opencv2/highgui. HPP> # include <opencv2/imgproc. HPP> using namespace CV; Class contentfinder {private: Float hranges [2]; const float * ranges [3]; int channels [3]; float threshold; MAT histogram; public: contentfinder (): threshold (-1.0f) {// All channels have the same range of ranges [0] = hranges; ranges [1] = hranges; ranges [2] = hranges ;} // set the threshold parameter [0, 1] void setthreshold (float t) {Threshold = T;} // obtain the Threshold Parameter float getthreshold () {return threshold ;} // set the reference histogram void sethistogram (const mat & H) {histogram = H; normalize (histogram, histogram, 1.0 );} // use the reverse projection histogram to find mat find (const mat & image) {mat result; hranges [0] = 0.0; hranges [1] = 255.0; channels [0] = 0; channels [1] = 1; channels [2] = 2; calcbackproject (& image, 1, channels, histogram, result, ranges, 255.0 ); if (threshold> 0.0) {CV: threshold (result, result, 255 * threshold, 255, CV: thresh_binary);} return result ;} // The complex Inverse Projection histogram is used to add some parameters mat find (const mat & image, float minvalue, float maxvalue, int * channels, int dim) {mat result; hranges [0] = minvalue; hranges [1] = maxvalue; For (INT I = 0; I <dim; I ++) {This-> channels [I] = channels [I];} calcbackproject (& image, 1, channels, histogram, result, ranges, 255.0); If (threshold> 0.0) CV: threshold (result, result, 255 * threshold, 255, thresh_binary); return result ;};# endif

 

The difference between the two functions is that a computed Inverse Projection histogram within a specified range.

Finally, let's look at the main function:

# Include "contentfinder. H "# include" histogram. H "# include" colorhistogram. H "int main () {// read image mat image = imread (" D:/picture/images/waves.jpg ", 0); If (! Image. data) Return-1; // define the area of interest mat imageroi = image (rect (36, 40,50 )); // calculate the histogram histogram1d H of the region of interest using the previously designed class; MAT hist = H. gethistogram (imageroi); // create a contentfinder object contentfinder finder; finder. sethistogram (hist); finder. setthreshold (-1.0f); // obtain the Inverse Projection mat result1; result1 = finder. find (image); mat tmp; result1.convertize (TMP, cv_8u,-1.0, 255.0); imshow ("reverse projection result", TMP); // obtain binary reverse projection finder. setthreshold (0.12f); result1 = finder. find (image); imshow ("grayscale image detection result (1)", result1); // Add a rectangular rectangle (image, rect (36, 40,50) to the source image ), scalar (, 0); imshow ("source image", image); // for another image: this image also contains a large number of clouds mat image2 = imread ("D: /picture/images/dog.jpg ", 0); MAT result2 = finder. find (image2); imshow ("grayscale image detection result (2)", result2 ); // *************** the color information is not used for the above detection, so the effect is very poor ************** // obtain the color histogram // read the color image colorhistogram HC; MAT color = imread ("D: /picture/images/waves.jpg "); imshow (" source image (1) ", color); // to reduce the computational workload, use the colorreduce function color = HC. colorreduce (color, 32); // defines the areas of interest: cloud imageroi = color (rect (,); // obtains the histogram mat shist = HC. gethistogram (imageroi); finder. sethistogram (shist); finder. setthreshold (0.05f); // obtain the reverse projection histogram result1 = finder. find (color); imshow ("Color Image Detection Result (1)", result1); // read the second image and detect mat color2 = imread ("D: /picture/images/dog.jpg "); imshow (" source image (2) ", color2); color2 = HC. colorreduce (color2, 32); result2 = finder. find (color2); imshow ("color image detection result (2)", result2 ); // **************** the above results take into account the color information, therefore, the effect is better. ******************** // only the color information is considered to form a histogram, perform reverse projection detection color = imread ("D:/picture/images/waves.jpg"); imageroi = color (rect (,); MAT colorhist = HC. gethuehistogram (imageroi); finder. sethistogram (colorhist); finder. setthreshold (0.3f); mat hsv; cvtcolor (color, HSV, cv_bgr2hsv); int ch [2] = {1, 2}; ch [0] = 0; result1 = finder. find (HSV, 0.0f, 180.0f, CH, 1); imshow ("result with color (1)", result1 ); // change the image color2 = imread ("D:/picture/images/dog.jpg"); cvtcolor (color2, HSV, cv_bgr2hsv); result2 = finder. find (HSV, 0.0f, 180.0f, CH, 1); imshow ("result of Color Detection (2)", result2); waitkey (0); Return 0 ;}

In the main function, we compare several methods of projection histograms:

Only use the histogram of the grayscale image, use the color image histogram, and the color image information histogram in the HSV space.

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.