您的位置:首页 > 运维架构

OPENCV——直方图计算calcHist

2015-09-10 13:21 393 查看
图像的灰度直方图是一个离散函数,它表示图像每一灰度级与该灰度级出现频率的对应关系。可以应用于各种需要统计的数据中,使用简单、方便。但该运算是一个不可逆的过程。

函数原型如下:
//! computes the joint dense histogram for a set of images.
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 );

//! computes the joint sparse histogram for a set of images.
CV_EXPORTS void calcHist( const Mat* images, int nimages,
const int* channels, InputArray mask,
SparseMat& hist, int dims,
const int* histSize, const float** ranges,
bool uniform=true, bool accumulate=false );

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 );


       参数:

        nimages——输入的图像的个数。

        channels——指明通道数。int channels[] = {0, 1};通道0和通道1。

        mask——掩码。如果mask不为空,那么它必须是一个8位(CV_8U)的数组,为0的像素点不统计。

        hist——保存直方图的矩阵

        dims——直方图的维数。

        histSize——每维bin的个数。

        ranges——用来进行统计的范围。    float rang1[] = {0, 256}; float rang2[] = {0, 256};

 const float *rangs[] = {rang1, rang2};那么就是对0,256和0,256范围的值进行统计,2D直方图)。

       uniform——如果为true,采用均匀直方图。

       accumulate——直方图建立时清除内存痕迹标志,默认为0,即清除。
下面是1D和2D直方图计算CODE:

#include "opencv2/opencv.hpp"
using namespace std;
using namespace cv;
int main()
{
//生成一幅单通道图像。
cv::Mat src = cv::imread("lena.png");
if( !src.data )
{ return -1; }
<pre name="code" class="cpp" style="color: rgb(0, 128, 0); font-size: 14px; line-height: 21px;">#pragma region single
/// 分割成3个单通道图像 ( R, G 和 B )vector<Mat> rgb_planes;split( src, rgb_planes );
/// 设定bin数目
int histSize = 255;

/// 设定取值范围 ( R,G,B) )
float range[] = { 0, 255 } ;
const float* histRange = { range };
bool uniform = true; bool accumulate = false;

Mat r_hist, g_hist, b_hist;

/// 计算直方图:
calcHist( &rgb_planes[0], 1, 0, Mat(), r_hist, 1, &histSize, &histRange, uniform, accumulate );
calcHist( &rgb_planes[1], 1, 0, Mat(), g_hist, 1, &histSize, &histRange, uniform, accumulate );
calcHist( &rgb_planes[2], 1, 0, Mat(), b_hist, 1, &histSize, &histRange, uniform, accumulate );

// 创建直方图画布
int hist_w = 400; int hist_h = 400;
int bin_w = cvRound( (double) hist_w/histSize );

Mat histImage( hist_w, hist_h, CV_8UC3, Scalar( 0,0,0) );

/// 将直方图归一化到范围 [ 0, histImage.rows ]
normalize(r_hist, r_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat() );
normalize(g_hist, g_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat() );
normalize(b_hist, b_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat() );

// 在直方图画布上画出直方图
for( int i = 1; i < histSize; i++ )
{
line( histImage, Point( bin_w*(i-1), hist_h - cvRound(r_hist.at<float>(i-1)) ) ,
Point( bin_w*(i), hist_h - cvRound(r_hist.at<float>(i)) ),
Scalar( 0, 0, 255), 2, 8, 0  );
line( histImage, Point( bin_w*(i-1), hist_h - cvRound(g_hist.at<float>(i-1)) ) ,
Point( bin_w*(i), hist_h - cvRound(g_hist.at<float>(i)) ),
Scalar( 0, 255, 0), 2, 8, 0  );
line( histImage, Point( bin_w*(i-1), hist_h - cvRound(b_hist.at<float>(i-1)) ) ,
Point( bin_w*(i), hist_h - cvRound(b_hist.at<float>(i)) ),
Scalar( 255, 0, 0), 2, 8, 0  );
}

/// 显示直方图
namedWindow("calcHist sDemo", CV_WINDOW_AUTOSIZE );
imshow("calcHist sDemo", histImage );
waitKey(0);
#pragma endregion single

#pragma region multi
MatND hist;
/// 计算直方图:
int rbins = 255, gbins = 255, bbins = 255;
int histSize1[] = {rbins, gbins, bbins};

float rranges[] = { 0, 256};
float granges[] = { 0, 256};
float branges[] = { 0, 256};

const float*ranges[] = { rranges, granges, branges };
int channels[] = {0, 1, 2};
calcHist( &src, 1,channels , Mat(), hist, 2, histSize1, ranges, true, false );
double maxVal=0;
minMaxLoc(hist, 0, &maxVal, 0, 0);
int scale = 2;
Mat histImg = Mat::zeros(gbins*scale, rbins*scale, CV_8UC3);

int n = hist.channels();

for( int h = 0; h < rbins; h++ )
{
for( int s = 0; s < gbins; 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("<span style="font-family: 'Courier New'; white-space: pre-wrap;">calcHist MDemo</span><span style="font-family: 'Courier New'; white-space: pre-wrap;">"</span><span style="line-height: 1.5; font-family: 'Courier New'; white-space: pre-wrap;">, 1 );  </span><span style="font-family: 'Courier New'; white-space: pre-wrap;">
</span>	imshow( "<span style="font-family: 'Courier New'; white-space: pre-wrap;">calcHist MDemo</span><span style="line-height: 1.5; font-family: 'Courier New'; white-space: pre-wrap;">", histImg );  </span>
waitKey(0);
#pragma endregion multi
return 0;
}



                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: