【OpenCV】直方图——一维

关于直方图的基本概念坛子里介绍的很多,能用代码表示尽量不多话!

int main()
{
	IplImage* src = cvLoadImage("J:\\baboon.jpg", CV_LOAD_IMAGE_COLOR);//加载原始图像,路径根据实际情况替换
	IplImage* gray_plan = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1);//创建单通道的灰度图像对象
	IplImage* b_plan = cvCreateImage(cvGetSize(src), 8, 1);//创建蓝色通道的图像对象
	IplImage* g_plan = cvCreateImage(cvGetSize(src), 8, 1);//创建绿色通道的灰度图像对象
	IplImage* r_plan = cvCreateImage(cvGetSize(src), 8, 1);//创建红色通道的灰度图像对象
	IplImage* ept_plan = cvCreateImage(cvGetSize(src), 8, 1);//创建单通道的“空白”图像对象,用来合成RGB3通道图像对象
	cvZero(ept_plan);//将图像所有通道所有元素都设置为0,否则在用cvMerge合并图像时,得到的结果不是“正色”。感兴趣可以自己cvShowImage ept_plan看看什么样子。
	cvCvtColor(src, gray_plan, CV_BGR2GRAY);//将原始图像(BGR)转换成灰度图像

	IplImage* bImg = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 3);//创建3通道图像
	IplImage* gImg = cvCreateImage(cvGetSize(src), 8, 3);
	IplImage* rImg = cvCreateImage(cvGetSize(src), 8, 3);

	cvSplit(src, b_plan, g_plan, r_plan, 0);//将原始图像分离成B、G、R 3个单通道的图像
	cvMerge(b_plan, ept_plan, ept_plan, 0, bImg);//合并3通道蓝色图像
	cvMerge(ept_plan, g_plan, ept_plan, 0, gImg);
	cvMerge(ept_plan, ept_plan, r_plan, 0, rImg);
	cvNamedWindow("B-Image", 1);
	cvShowImage("B-Image", bImg);
	cvNamedWindow("G-Image", 1);
	cvShowImage("G-Image", gImg);
	cvNamedWindow("R-Image", 1);
	cvShowImage("R-Image", rImg);

	int dims = 1;//直方图维数
	int hist_size = 256;//直方图维数的长度
	int hist_height = 256;//源图像尺寸 512*512

	//灰度直方图
	float range[] = {0, 255};//直方图中每个维数对应的取值范围,该值会影响直方图统计结果
	float* ranges[] = { range };//数组的长度与维数相同
	CvHistogram* gray_hist = cvCreateHist(1, &hist_size, CV_HIST_ARRAY, ranges, 1);//创建直方图对象
	cvCalcHist(&gray_plan, gray_hist, 0, 0);//计算图像直方图
	cvNormalizeHist(gray_hist, 1.0);//归一化直方图元素
	float max_value = 0;
	cvGetMinMaxHistValue(gray_hist, 0, &max_value, 0, 0);//获取直方图中最大值

	//蓝色直方图
	float rangeB[] = {0, 255};
	float* rangesB[] = {rangeB};
	CvHistogram* b_hist = cvCreateHist(1, &hist_size, CV_HIST_ARRAY, rangesB, 1);
	cvCalcHist(&b_plan, b_hist, 0, 0);
	cvNormalizeHist(b_hist, 1.0);
	float max_value_b = 0;
	cvGetMinMaxHistValue(b_hist, 0, &max_value_b, 0, 0);

	//绿色直方图
	float rangeG[] = { 0, 255 };
	float* rangesG[] = { rangeG };
	CvHistogram* g_hist = cvCreateHist(1, &hist_size, CV_HIST_ARRAY, rangesG, 1);
	cvCalcHist(&g_plan, g_hist, 0, 0);
	cvNormalizeHist(g_hist, 1.0);
	float max_value_g = 0;
	cvGetMinMaxHistValue(g_hist, 0, &max_value_g, 0, 0);

	//红色直方图
	float rangeR[] = { 0, 255 };
	float* rangesR[] = { rangeR };
	CvHistogram* r_hist = cvCreateHist(1, &hist_size, CV_HIST_ARRAY, rangesR, 1);
	cvCalcHist(&r_plan, r_hist, 0, 0);
	cvNormalizeHist(r_hist, 1.0);
	float max_value_r = 0;
	cvGetMinMaxHistValue(r_hist, 0, &max_value_r, 0, 0);

	int scale = 2;//生成的直方图图像的比例向量
	int split = 5;//灰度、蓝色、绿色、红色 四个类型直方图在直方图图像中的间隔像素
	IplImage* hist_image = cvCreateImage(cvSize(hist_size * scale * 2 + split, hist_height * 2 + split), 8, 3);//创建直方图图像对象(在一张图里面显示四种直方图)
	cvZero(hist_image);

	for (int i = 0; i < hist_size; i++)//画灰度直方图
	{
		float bin_val = cvQueryHistValue_1D(gray_hist, i);
		int intensity = cvRound(bin_val*hist_height / max_value);//要绘制的高度
		cvRectangle(hist_image,//矩形画在直方图图像内
			cvPoint(i*scale, hist_height),//矩形对角线中的一个点
			cvPoint((i + 1) * scale - 1, hist_height - intensity),//矩形对角线中的另一个点
			CV_RGB(255, 255, 255));
	}

	for (int i = 0; i < hist_size; i++)//画蓝色通道直方图
	{
		float bin_val = cvQueryHistValue_1D(b_hist, i);
		int intensity = cvRound(bin_val * hist_height / max_value_b);
		cvRectangle(hist_image,
			cvPoint(i * scale + (split + hist_size * scale), hist_height),
			cvPoint((i + 1) * scale - 1 + (split + hist_size * scale), hist_height - intensity),
			CV_RGB(0, 0, 255));
	}

	for (int i = 0; i < hist_size; i++)//画绿色通道直方图
	{
		float bin_val = cvQueryHistValue_1D(g_hist, i);
		int intensity = cvRound(bin_val * hist_height / max_value_g);
		cvRectangle(hist_image,
			cvPoint(i * scale + split, hist_height * 2 + split),
			cvPoint((i + 1) * scale - 1 + split, hist_height * 2 + split - intensity),
			CV_RGB(0, 255, 0));
	}

	for (int i = 0; i < hist_size; i++)//画红色通道直方图
	{
		float bin_val = cvQueryHistValue_1D(r_hist, i);
		int intensity = cvRound(bin_val * hist_height / max_value_r);
		cvRectangle(hist_image,
			cvPoint(i * scale + (split + hist_size * scale), hist_height * 2 + split),
			cvPoint((i + 1) * scale - 1 + (split + hist_size * scale), hist_height * 2 + split - intensity),
			CV_RGB(255, 0, 0));
	}

	cvNamedWindow("Gray Source", 1);
	cvNamedWindow("Histogram", 1);
	cvShowImage("Gray Source", gray_plan);
	cvShowImage("Histogram", hist_image);

	cvWaitKey(0);

	cvDestroyAllWindows();
	cvReleaseImage(&gray_plan);
	cvReleaseImage(&hist_image);
}

运行的结果如下:





完整工程(vs2013)源代码下载:点击下载


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值