OpenCV学习笔记(16):直方图

灰度直方图:

C++: void calcHist(const Mat*images, intnimages, const int*channels, InputArraymask, OutputArrayhist, intdims, const int*histSize, const float**ranges, booluniform=true, boolaccumulate=false)

 
  • images – Source arrays. They all should have the same depth,CV_8U orCV_32F , and the same size. Each of them can have an arbitrary number of channels.
  • nimages – Number of source images.
  • channels – List of the dims channels used to compute the histogram. The first array channels are numerated from 0 toimages[0].channels()-1 , the second array channels are counted fromimages[0].channels() to images[0].channels() + images[1].channels()-1, and so on.
  • mask – Optional mask. If the matrix is not empty, it must be an 8-bit array of the same size asimages[i] . The non-zero mask elements mark the array elements counted in the histogram.
  • hist – Output histogram, which is a dense or sparse dims -dimensional array.
  • dims – Histogram dimensionality that must be positive and not greater thanCV_MAX_DIMS (equal to 32 in the current OpenCV version).
  • histSize – Array of histogram sizes in each dimension. 用于指出直方图数组每一维的大小的数组,即指出每一维的bin的个数的数组;(每维分成多少份)
  • ranges – 用于指出直方图每一维的每个bin(份)的上下界范围数组的数组
  • uniform直方图是否均匀的标志;【指定直方图每个bin统计的是否是相同数量的灰度级】
  • accumulate – Accumulation flag. If it is set, the histogram is not cleared in the beginning when it is allocated. This feature enables you to compute a single histogram from several sets of arrays, or to update the histogram in time. 
计算灰度图像的直方图:

#include
#include
using namespace std;
using namespace cv;
int main()
{
	Mat src,gray;
	src = imread("lena.png");
	if (!src.data)
		cout << "error:load image error!" << endl;
	cvtColor(src, gray, CV_BGR2GRAY);
	imshow("d", gray);
	Mat hist;
	int histSize = 256;
	float histRange[] = { 0, 255 };
    const float *range[] = { histRange };
	calcHist(&gray, 1,0, Mat(), hist, 1, &histSize, range, true, false);
	double max;
	minMaxLoc(hist, 0, &max, 0, 0);
	Mat hist_img (histSize, histSize, CV_8U, Scalar(255));
	int hh = static_cast(0.9*histSize);
	for (int i = 0; i < histSize; ++i)
	{
		float binVal = hist.at(i);
		int intensity = static_cast(binVal*hh / max);
		line(hist_img, Point(i, histSize), Point(i, histSize - intensity), Scalar::all(0));
	}
	imshow("dd", hist_img);
	waitKey(0);
	return 0;
}

OpenCV学习笔记(16):直方图_第1张图片         OpenCV学习笔记(16):直方图_第2张图片

计算彩色空间直方图:B,G,R

#include
using namespace cv;
int main()
{
	Mat src;
	src = imread("lena.png");
	if (!src.data)
	{
		return -1;
	}
	vector bgr_plane;
	split(src, bgr_plane);
	//imshow("f", bgr_plane[2]);

	int histSize = 256;
	float histRange[] = { 0, 255 };
	const float*ranges[] = { histRange };
	Mat hist_b, hist_g, hist_r;

	calcHist(&bgr_plane[0], 1, 0, Mat(), hist_b, 1, &histSize, ranges, true, false);
	calcHist(&bgr_plane[1], 1, 0, Mat(), hist_g, 1, &histSize, ranges, true, false);
	calcHist(&bgr_plane[2], 1, 0, Mat(), hist_r, 1, &histSize, ranges, true, false);

	int hist_w = 600; int hist_h = 400;
	int bin_w = cvRound((double)hist_w / histSize);
	Mat hist_image(hist_h, hist_w, CV_8UC3, Scalar(0, 0, 0));

	normalize(hist_b, hist_b, 0, hist_image.rows, NORM_MINMAX, -1, Mat());
	normalize(hist_g, hist_g, 0, hist_image.rows, NORM_MINMAX, -1, Mat());
	normalize(hist_r, hist_r, 0, hist_image.rows, NORM_MINMAX, -1, Mat());

	Mat img_bgr[3];
	for (int i = 0; i < 3; i++)
	{
		img_bgr[i] = Mat(hist_h, hist_w, CV_8UC3, Scalar::all(0));

	}


	for (int i = 1; i < histSize; i++)
	{
		line(hist_image, Point(bin_w*(i - 1), hist_h -cvRound( hist_b.at(i - 1))), Point(bin_w*i, hist_h -cvRound( hist_b.at(i))), Scalar(255, 0, 0), 2, 8, 0);
		line(hist_image, Point(bin_w*(i - 1), hist_h - cvRound(hist_g.at(i - 1))), Point(bin_w*i, hist_h - cvRound(hist_g.at(i))), Scalar(0, 255, 0), 2, 8, 0);
		line(hist_image, Point(bin_w*(i - 1), hist_h - cvRound(hist_r.at(i - 1))), Point(bin_w*i, hist_h - cvRound(hist_r.at(i))), Scalar(0, 0, 255), 2, 8, 0);

	}

	for (int j = 0; j < histSize; j++)
	{
		int val = static_cast(hist_b.at(j));
		rectangle(img_bgr[0], Point(j * 2 + 10, img_bgr[0].rows), Point((j + 1) * 2 + 10, img_bgr[0].rows - val),Scalar(255,0,0), 1, 8);
		 val = static_cast(hist_g.at(j));
		rectangle(img_bgr[1], Point(j * 2 + 10, img_bgr[1].rows), Point((j + 1) * 2 + 10, img_bgr[1].rows - val),Scalar(0,255,0), 1, 8);
		 val = static_cast(hist_r.at(j));
		rectangle(img_bgr[2], Point(j * 2 + 10, img_bgr[2].rows), Point((j + 1) * 2 + 10, img_bgr[2].rows - val),Scalar(0,0,255), 1, 8);
	}

	namedWindow("hist DEMO", CV_WINDOW_AUTOSIZE);
	imshow("hist DEMO", hist_image);
	imshow("B", img_bgr[0]);
	imshow("G", img_bgr[1]);
	imshow("R", img_bgr[2]);

	waitKey(0);
	return 0;
}




归一化normalize:

void normalize(InputArray src, OutputArray dst, double alpha=1, doublebeta=0, intnorm_type=NORM_L2, int dtype=-1, InputArraymask=noArray())

  Parameter s:
  • src – input array.
  • dst – output array of the same size as src .
  • alpha – norm value to normalize to or the lower range boundary in case of the range normalization.
  • beta – upper range boundary in case of the range normalization; it is not used for the norm normalization.
  • normType – normalization type (see the details below).
  • dtype – when negative, the output array has the same type assrc; otherwise, it has the same number of channels assrc and the depth=CV_MAT_DEPTH(dtype).
  • mask – optional operation mask. 

OpenCV学习笔记(16):直方图_第3张图片                             OpenCV学习笔记(16):直方图_第4张图片


OpenCV学习笔记(16):直方图_第5张图片    OpenCV学习笔记(16):直方图_第6张图片    OpenCV学习笔记(16):直方图_第7张图片

channels参数:

参考:http://blog.csdn.net/ljbkiss/article/details/7420429

calcHist函数的channels参数和narrays以及dims共同来确定用于计算直方图的图像;
首先dims是最终的直方图维数,narrays指出了arrays数组中图像的个数,其中每一幅图像都可以是任意通道的【只要最终dims不超过32即可】

如果channels参数为0,则narrays和dims必须相等,否则弹出assert,此时计算直方图的时候取数组中每幅图像的第0通道。
当channels不是0的时候,用于计算直方图的图像是arrays中由channels指定的通道的图像,channels与arrays中的图像的对应关系,如channels的参数说明的,将arrays中的图像从第0幅开始按照通道摊开排列起来,然后channels中的指定的用于计算直方图的就是这些摊开的通道;
假设有arrays中只有一幅三通道的图像image,那么narrays应该为1,如果是想计算3维直方图【最大也只能是3维的】,想将image的通道2作为第一维,通道0作为第二维,通道1作为第三维,则可以将channels设置为channesl={2,0,1};这样calcHist函数计算时就按照这个顺序来统计直方图。
可以看出channels不为0时narrays可以和dims不相等,只要保证arrays中至少有channels指定的通道就可以。


你可能感兴趣的:(OpenCV学习笔记)