新版本对直方图不再使用之前的histogram的形式,而是用统一的Mat或者MatND的格式来存储直方图,可见新版本Mat数据结构的优势。

#include "stdafx.h"

#include <cv.h>
#include <highgui.h> using namespace cv; int main( int argc, char** argv )
{
Mat src, hsv; /* if( argc != 2 || !(src=imread(argv[1], 1)).data )
return -1; */ src=imread("zhang.jpg", 1); cvtColor(src, hsv, CV_BGR2HSV); // Quantize the hue to 30 levels
// and the saturation to 32 levels
int hbins = 30, sbins = 32; // bin 步长 int histSize[] = {hbins, sbins};
// hue varies from 0 to 179, see cvtColor
float 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 channels
int channels[] = {0, 1}; // --- hue && saturation calcHist( &hsv, 1, channels, Mat(), // do not use mask
hist, 2, histSize, ranges,
true, // the histogram is uniform
false );
double maxVal=0;
minMaxLoc(hist, 0, &maxVal, 0, 0); // Finds the global minimum and maximum in an array.
// void minMaxLoc(InputArray src, double* minVal, double* maxVal=0, Point* minLoc=0, Point* maxLoc=0, InputArray mask=noArray()) // 直方图显示
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();
}

 
 
  • 05-11 22:05