灰度直方图

目录

参数意义

1维直方图

2维直方图

参数意义

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 )

const Mat* images:输入图像

int nimages:输入图像的个数 

const int* channels:需要统计直方图的第几通道 ->(索引从0开始)

InputArray mask:掩膜,,计算掩膜内的直方图  ...Mat()    ->(不使用掩膜时,输入Mat())

OutputArray hist:输出的直方图数组

int dims:需要统计直方图通道的个数

const int* histSize:指的是直方图分成多少个区间,,,就是 bin的个数  ->(将横纵坐标均分成bin份)

const float** ranges: 统计像素值得区间  ->(1维直方图代表横坐标范围,2维直方图代表横轴坐标范围)

bool uniform=true::是否对得到的直方图数组进行归一化处理

bool accumulate=false:在多个图像时,是否累计计算像素值得个数

1维直方图

opencv代码

void histogram_demo(Mat image)
{
	std::vector bgr;
	split(image, bgr);
	//定义参数变量
	const int channels[1] = { 0 };
	const int bins[1] = { 256 };  //每个直方图的灰度范围,将横坐标均分为256份
	float hranges[2] = { 0,255 };  //直方图取值范围 
	const float* ranges[1] = { hranges };
	Mat b_hist;
	Mat g_hist;
	Mat r_hist;  //分别存储bgr三通道的灰度值对应的像素点个数  256*1 256行1列
	//计算bgr通道的直方图
	calcHist(&bgr[0], 1, 0,Mat(), b_hist, 1, bins, ranges);
	calcHist(&bgr[1], 1, 0, Mat(), g_hist, 1, bins, ranges);
	calcHist(&bgr[2], 1, 0, Mat(), r_hist, 1, bins, ranges);
	//显示直方图
	int hist_w = image.cols;
	int hist_h = image.rows; //直方图尺寸
	int bin_w = cvRound((double)hist_w / bins[0]); //直方图横坐标均分成256份 每份的值
	Mat histImage = Mat::zeros(hist_h, hist_w, CV_8UC3);
	//归一化直方图数据 (范围归一化 直方图纵坐标取值范围是(0, histImage.rows))
	normalize(b_hist, b_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat());
	normalize(g_hist, g_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat());
	normalize(r_hist, r_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat());
	//绘制直方图曲线  图像坐标=画布高度-直方图值(范围是(0,hist_h))
	for (int i = 1; i < bins[0]; i++)
	{
		line(histImage, Point(bin_w * (i - 1), hist_h-cvRound(b_hist.at(i-1))),       
			Point(bin_w * (i), hist_h - cvRound(b_hist.at(i))), 
            Scalar(255, 0, 0), 2, 8, 0);
		line(histImage, Point(bin_w * (i - 1), hist_h-cvRound(g_hist.at(i-1))),
			Point(bin_w * (i), hist_h - cvRound(g_hist.at(i))), 
            Scalar(0, 255, 0), 2, 8, 0);
		line(histImage, Point(bin_w * (i - 1), hist_h-cvRound(r_hist.at(i-1))),
			Point(bin_w * (i), hist_h - cvRound(r_hist.at(i))), 
            Scalar(0, 0, 255), 2, 8, 0);
	}
	namedWindow("histogram", WINDOW_AUTOSIZE);
	imshow("histogram", histImage);
}

代码中涉及到的归一化函数:

void normalize(InputArray src,OutputArray dst, double alpha=1, double beta=0, int norm_type=NORM_L2, int dtype=-1, InputArray mask=noArray() )

参数意义:

src:输入数组

dst:输出数组,支持原地运算

alpha:range normalization模式的最小值,当alpha取1时代表范数归一化模式,此时beta为0。

beta:range normalization模式的最大值,不用于norm normalization(范数归一化)模式。

normType:归一化的类型,可以有以下的取值:

        NORM_MINMAX:数组的数值被平移或缩放到一个指定的范围,线性归一化,一般较常用。

        NORM_INF: 此类型的定义没有查到,根据OpenCV 1的对应项,可能是归一化数组的C-范数(绝对值的最大值)

        NORM_L1 :归一化数组的L1-范数(绝对值的和)

        NORM_L2:归一化数组的(欧几里德)L2-范数

dtype:dtype为负数时,输出数组的type与输入数组的type相同;否则,输出数组与输入数组只是              通道数相同,而tpye=CV_MAT_DEPTH(dtype).

mask:操作掩膜,用于指示函数是否仅仅对指定的元素进行操作。

2维直方图

opencv代码

void histogram_2d_demo(Mat image)
{
	Mat hsv, hs_hist;  //hs_hist是存储h通道s通道的灰度值分布数组,2*30*32
    //将图像转化为hsv空间,绘制hs通道的直方图
	cvtColor(image, hsv, COLOR_BGR2HSV);
	int hbins = 30, sbins = 32;  //h通道范围(0,180),将其分成30份,
                                   s通道范围(0,255),将其分成32份                                   
	int hist_bins[] = { hbins,sbins };
	float h_range[] = { 0, 180 };
	float s_range[] = { 0, 256 };
	const float* hs_ranges[] = { h_range,s_range };
	int hs_channels[] = { 0,1 };
	calcHist(&hsv, 1, hs_channels, Mat(), hs_hist, 2, hist_bins, hs_ranges, true, false);
	double maxVal = 0;
	minMaxLoc(hs_hist, 0, &maxVal, 0, 0);
	int scale = 10;
	Mat hist2d_image = Mat::zeros(sbins * scale, hbins * scale, CV_8UC3);
	for (int h = 0; h < hbins; h++)
	{
		for (int s = 0; s < sbins; s++)
		{
			float binVal = hs_hist.at(h, s);
			int intensity = cvRound(binVal * 255 / maxVal);
			rectangle(hist2d_image,Point(h*scale, s*scale),
                      Point((h+1)*scale-1,(s+1)*scale-1), 
				      Scalar::all(intensity), -1);
		}
	}
	applyColorMap(hist2d_image, hist2d_image, COLORMAP_JET);
	imshow("H-S Histogram", hist2d_image);
}


 

你可能感兴趣的:(c++,opencv)