opencv 二维直方图

2D直方图生成与可视化
#define cvCvtPixToPlane cvSplit
#define cvCvtPlaneToPix cvMerge


void hist_2D(void)
{
	IplImage *src=cvLoadImage("lena.jpg");
	IplImage *hsv=cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 3);
	cvCvtColor(src, hsv, CV_BGR2HSV_FULL);

	IplImage *h_plane=cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1);
	IplImage *s_plane=cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1);
	IplImage *v_plane=cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1);
	IplImage *planes[]={h_plane, s_plane};
	cvCvtPixToPlane(hsv, h_plane, s_plane, v_plane, 0);

	//Build the histogram and compute its contents.
	int h_bins=256, s_bins=256;
	CvHistogram *hist;
	{
		int hist_size[]={h_bins, s_bins};
		float h_ranges[]={0, 255}; //hue is [0, 180]
		float s_ranges[]={0, 255}; 
		float* ranges[]={h_ranges, s_ranges};
		hist=cvCreateHist(2, hist_size, CV_HIST_ARRAY, ranges, 1);
	}
	cvCalcHist(planes, hist, 0, 0); //Compute histogram
	cvNormalizeHist(hist, 1.0); //Normalize it
	//Create an image to use to visualize our histogram
	int scale=2;
	IplImage *hist_img=cvCreateImage(cvSize(h_bins*scale, s_bins*scale), IPL_DEPTH_8U, 3);
	cvZero(hist_img);

	//populate our visualization with little gray squares.
	float max_value=0;
	cvGetMinMaxHistValue(hist, 0, &max_value, 0, 0);
	for (int h=0; h<h_bins; h++)
	{
		for (int s=0; s<s_bins; s++)
		{
			float bin_val=cvQueryHistValue_2D(hist, h, s);
			int intensity=cvRound(bin_val*255/max_value);
			cvRectangle(hist_img, cvPoint(h*scale, s*scale), cvPoint((h+1)*scale-1, (s+1)*scale-1), CV_RGB(intensity, intensity, intensity), CV_FILLED);
		}
	}

	cvNamedWindow("Source");
	cvShowImage("Source", src);

	cvNamedWindow("H-S Histogram");
	cvShowImage("H-S Histogram", hist_img);

	cvWaitKey(0);
}







### 如何使用 OpenCV 绘制 HSV 图像的二维直方图 绘制 HSV 图像的二维直方图通常涉及色调 (Hue, H) 和饱和度 (Saturation, S),因为这两个通道能够很好地表示颜色信息。以下是实现该功能的具体方法: #### 使用 `calcHist` 函数计算二维直方图 OpenCV 提供了 `cv::calcHist` 函数来计算直方图。对于二维直方图,需要指定两个通道作为输入参数,并设置相应的范围和 bin 数量。 ```cpp #include <opencv2/opencv.hpp> #include <iostream> int main() { // 加载图像并转换到 HSV 空间 cv::Mat image = cv::imread("image.jpg"); if (image.empty()) { std::cout << "Could not open or find the image!" << std::endl; return -1; } cv::Mat hsvImage; cv::cvtColor(image, hsvImage, cv::COLOR_BGR2HSV); // 定义用于计算直方图的参数 int h_bins = 30; // 色调通道 bins int s_bins = 32; // 饱和度通道 bins int histSize[] = {h_bins, s_bins}; // 每个维度的 bins 数量 float h_ranges[] = {0, 180}; float s_ranges[] = {0, 256}; const float* ranges[] = {h_ranges, s_ranges}; int channels[] = {0, 1}; // 计算 H 和 S 通道的直方图 cv::MatND hist; cv::calcHist(&hsvImage, 1, channels, cv::Mat(), hist, 2, histSize, ranges); // 归一化直方图以便于显示 double maxVal = 0; cv::minMaxLoc(hist, nullptr, &maxVal); hist /= maxVal; // 显示直方图 int scale = 10; cv::Mat histImg(h_bins * scale, s_bins * scale, CV_8UC3, cv::Scalar(0, 0, 0)); for (int h = 0; h < h_bins; ++h) { for (int s = 0; s < s_bins; ++s) { float val = hist.at<float>(h, s); cv::rectangle(histImg, cv::Point(s * scale, h * scale), cv::Point((s + 1) * scale - 1, (h + 1) * scale - 1), cv::Scalar(255 * val, 255 * val, 255 * val), cv::FILLED); } } cv::imshow("Histogram", histImg); cv::waitKey(); return 0; } ``` 上述代码实现了以下功能: - 将 BGR 图像转换为 HSV 格式[^1]。 - 设置色调和饱和度的 bin 数量以及取值范围[^2]。 - 利用 `cv::calcHist` 函数计算二维直方图。 - 对直方图数据进行归一化处理以便可视化。 - 创建一个空白画布并将直方图数据显示其上。 #### 关键点解析 - **`channels` 参数**:指定了参与直方图计算的通道,这里选择了 H 和 S 通道。 - **`histSize` 参数**:定义了每个维度上的 bin 数量。 - **`ranges` 参数**:设定了各通道的有效数值区间。 - **归一化操作**:通过除以最大值使所有像素值映射到 `[0, 1]` 的范围内,便于后续绘图。 #### 结果展示 最终生成的二维直方图可以直观反映图像中不同色调和饱和度组合的分布情况。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值