It turns out that the histogram function in opencv is very simple. It is needed temporarily today to find that the calchist function of opencv is so powerful that it can not only compute common 1D Hist, calchist theoretically supports hist of less than 32 dimensions. (32-dimensional !)
VoidCalchist(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)
Image: Input ImageSequence
Nimages: number of source images
Channels: used to calculate the hist ChannelList
Mask: not explained
Hist: The generated Hist.
Dims: hist dimension (must be greater than 0. The current version cannot be greater than cv_max_dims = 32)
Histszie: size of each dimension (bins)
Ranges: the value of bins in each dimension of the histogram.BoundarySequence
Uniform: alignment or not
Accumlate: If set is true, the histogram is not clear before use. It is used to save the histograms of multiple image sets in one Hist, or to update hist in time.
Implementation Code:
Two histogram plotting functions are implemented here to draw 1D and 2D histograms respectively.
BGR three-channel 1D histogram:
In the program, multiple images are displayed in a window. You can also use mat1.put _ back (mat2), but push_back pushes mat to the Y axis, soy Sauce purple shows a long and thin window, so it is better to use the ROI user experience.
Mat drawhist (MAT Hist, int bins, int height, scalar RGB) {double maxval = 0; minmaxloc (Hist, 0, & maxval, 0); int scale = 1; mat histimg = mat: zeros (height, bins, cv_8uc3); float * binval = Hist. PTR <float> (0); For (INT I = 0; I <bins; I ++) {int intensity = cvround (binval [I] * Height/maxval ); rectangle (histimg, point (I * scale, 0), point (I + 1) * scale, (intensity), RGB, cv_filled);} flip (histimg, histimg, 0); Return histimg;} void darwhistrgb (const mat & SRC) {mat histb, histg, histr; int bins = 256; int histsize [] = {bins }; float range [] ={ 0,256}; const float * ranges [] = {range}; int channelsb [] = {0}; int channelsg [] = {1 }; int channelsr [] = {2}; calchist (& SRC, 1, channelsb, MAT (), histb, 1, histsize, ranges, true, false); calchist (& SRC, 1, channelsg, MAT (), histg, 1, histsize, ranges, true, false); calchist (& SRC, 1, channelsr, MAT (), histr, 1, histsize, ranges, true, false); MAT histbimg = drawhist (histb, bins, 200, scalar (200, 0, 0); MAT histgimg = drawhist (histg, bins, scalar (0,255, 0); MAT histrimg = drawhist (histr, bins, 200, scalar (255 )); // display multiple images in a window mat display (200, bins * 3, cv_8uc3); MAT displayroi = display (rect (200, bins,); resize (histbimg, displayroi, displayroi. size (); displayroi = display (rect (bins, 0, bins, 200); resize (histgimg, displayroi, displayroi. size (); displayroi = display (rect (bins * 200, bins,); resize (histrimg, displayroi, displayroi. size (); imshow ("histrgb", display); waitkey () ;}int main () {mat src = imread ("D:/demo.jpg", 1 ); darwhistrgb (SRC); return 1 ;}
HSV H-S channel 2D Histogram:
The gray value represents the height of the histogram. It can be seen as a three-dimensional bar chart from the top down (-Z axis.
int main( ){Mat src, hsv;src = imread("D:/demo.jpg", 1);cvtColor(src, hsv, CV_BGR2HSV);// Quantize the hue to 30 levels// and the saturation to 32 levelsint hbins = 30, sbins = 32;int histSize[] = {hbins, sbins};// hue varies from 0 to 179, see cvtColorfloat hranges[] = { 0, 180 };// saturation varies from 0 (black-gray-white) to// 255 (pure spectrum color)float sranges[] = { 0, 256 };const float* ranges[] = { hranges, sranges };MatND hist;// we compute the histogram from the 0-th and 1-st channelsint channels[] = {0, 1};calcHist( &hsv, 1, channels, Mat(), // do not use maskhist, 2, histSize, ranges,true, // the histogram is uniformfalse );double maxVal=0;minMaxLoc(hist, 0, &maxVal, 0, 0);int scale = 10;Mat histImg = Mat::zeros(sbins*scale, hbins*10, CV_8UC3);for( int h = 0; h < hbins; h++ )for( int s = 0; s < sbins; s++ ){float binVal = hist.at<float>(h, s);int intensity = cvRound(binVal*255/maxVal);rectangle( histImg, Point(h*scale, s*scale),Point( (h+1)*scale - 1, (s+1)*scale - 1),Scalar::all(intensity),CV_FILLED );}namedWindow( "Source", 1 );imshow( "Source", src );namedWindow( "H-S Histogram", 1 );imshow( "H-S Histogram", histImg );waitKey();}
Maximum Entropy Segmentation
Use hist to implement the Maximum Entropy Model
Information Entropy:
Maximum Entropy segmentation:
# Include <iostream> # include <opencv/cv. h> # include <opencv/highgui. h> using namespace STD; using namespace CV; typedef Enum {back, object} entropy_state; float total; // draw hist; MAT drawhist (MAT Hist, int bins, int height, scalar RGB) {double maxval = 0; minmaxloc (Hist, 0, & maxval, 0); int scale = 1; MAT histimg = mat: zeros (height, bins, cv_8uc3); float * binval = Hist. PTR <float> (0); For (INT I = 0; I <bins; I ++) {int intensity = cvround (binval [I] * Height/maxval ); rectangle (histimg, point (I * scale, 0), point (I + 1) * scale, (intensity), RGB, cv_filled);} flip (histimg, histimg, 0); Return histimg;} // calculate the histogram; MAT hist (const mat & SRC) {mat hist; int bins = 256; int histsize [] = {bins }; float range [] ={ 0,256}; const float * ranges [] = {range}; int channels [] = {0}; calchist (& SRC, 1, channels, MAT (), Hist, 1, histsize, ranges, true, false); MAT histimg = drawhist (Hist, bins, 200, scalar (, 0, 0 )); imshow ("histrgb", histimg); Return hist ;}// calculate the current entropy; float calentropy (const mat & Hist, int threshold) {float total_back = 0, total_object = 0; float entropy_back = 0, entropy_object = 0; float entropy = 0; int I = 0; const float * hist_p = (float *) Hist. PTR <float> (0); for (I = 0; I <threshold; I ++) {total_back + = hist_p [I] ;}total_object = total-total_back; // background entropy; for (I = 0; I <threshold; I ++) {// If (hist_p [I] = 0) // continue; float percentage = hist_p [I]/total_back; entropy_back + =-percentage * logf (percentage); // energy Definition Formula} // foreground entropy; for (I = threshold; I <Hist. cols; I ++) {// If (hist_p [I] = 0) // {// continue; //} float percentage = hist_p [I]/total_object; entropy_object + =-percentage * logf (percentage); // defines the formula for energy;} entropy = entropy_object + entropy_back; return entropy;} void maxentropy (mat img, mat hist) {Total = sum (hist) [0]; float maxentropyvalue = 0.0, maxentropythreshold = 0.0; float TMP; For (INT I = 0; I <Hist. cols; I ++) {TMP = calentropy (Hist, I); If (TMP> maxentropyvalue) {maxentropyvalue = TMP; maxentropythreshold = I ;}} threshold (IMG, IMG, maxentropythreshold, 255, cv_thresh_binary); imshow ("thresholdimg", IMG); imwrite ("D:/Hangzhou", IMG); cout <maxentropythreshold <Endl; cout <maxentropyvalue <Endl;} int main () {mat src = imread ("D:/test1.jpg", 0); imshow ("src", Src ); mat hist = Hist (SRC ). T (); maxentropy (SRC, hist); waitkey (); return 1 ;}