OpenCV入门(二十一)-- 绘制彩色图像的直方图

本文中的代码大多来源于:

http://wiki.opencv.org.cn/index.php/%E5%9B%BE%E5%83%8F%E9%A2%9C%E8%89%B2%E5%88%86%E5%B8%83%E7%9B%B4%E6%96%B9%E5%9B%BE

颜色直方图的一些概念       

颜色直方图可以是基于不同的颜色空间坐标系。最常用的颜色空间是RGB颜色空间,原因在于大部分的数字图像都是用这种颜色空间表达的。然而,RGB空间结构并不符合人们对颜色相似性的主观判断。因此,有人提出了基于HSV空间、Luv空间和Lab空间的颜色直方图,因为它们更接近于人们对颜色的主观认识。其中HSV空间是直方图最常用的颜色空间。它的三个分量分别代表色彩(Hue)、饱和度(Saturation)和值(Value)。

HSV
HSV颜色空间:HSV(hue,saturation,value)颜色空间的模型对应于圆柱坐标系中的一个圆锥形子集,圆锥的顶面对应于V=1. 它包含RGB模型中的R=1,G=1,B=1 三个面,所代表的颜色较亮。色彩H由绕V轴的旋转角给定。红色对应于 角度0° ,绿色对应于角度120°,蓝色对应于角度240°。在HSV颜色模型中,每一种颜色和它的补色相差180° 。饱和度S取值从0到1,所以圆锥顶面的半径为1。HSV颜色模型所代表的颜色域是CIE色度图的一个子集,这个 模型中饱和度为百分之百的颜色,其纯度一般小于百分之百。在圆锥的顶点(即原点)处,V=0,H和S无定义, 代表黑色。圆锥的顶面中心处S=0,V=1,H无定义,代表白色。从该点到原点代表亮度渐暗的灰色,即具有不同 灰度的灰色。对于这些点,S=0,H的值无定义。可以说,HSV模型中的V轴对应于RGB颜色空间中的主对角线。 在圆锥顶面的圆周上的颜色,V=1,S=1,这种颜色是纯色。HSV模型对应于画家配色的方法。画家用改变色浓和色深的方法从某种纯色获得不同色调的颜色,在一种纯色中加入白色以改变色浓,加入黑色以改变色深,同时 加入不同比例的白色,黑色即可获得各种不同的色调。

http://baike.baidu.com/item/%E9%A2%9C%E8%89%B2%E7%9B%B4%E6%96%B9%E5%9B%BE?fr=aladdin


HSV颜色模型

HSV(Hue, Saturation, Value)是根据颜色的直观特性由A. R. Smith在1978年创建的一种颜色空间, 也称六角锥体模型(Hexcone Model)。
这个模型中颜色的参数分别是:色调(H),饱和度(S),亮度(V)。

色调H
用角度度量,取值范围为0°~360°,从红色开始按逆时针方向计算,红色为0°,绿色为120°,蓝色为240°。它们的补色是:黄色为60°,青色为180°,品红为300°;

饱和度S
取值范围为0.0~1.0,值越大,颜色越饱和。
亮度V
取值范围为0.0(黑色)~1.0(白色)。


RGB和CMY颜色模型都是面向硬件的,而HSV(Hue Saturation Value)颜色模型是面向用户的。
HSV模型的三维表示从RGB立方体演化而来。设想从RGB沿立方体对角线的白色顶点向黑色顶点观察,就可以看到立方体的六边形外形。六边形边界表示色彩,水平轴表示纯度,明度沿垂直轴测量。

http://baike.baidu.com/subview/541362/8445478.htm?from_id=12630604&type=syn&fromtitle=HSV%E9%A2%9C%E8%89%B2%E7%A9%BA%E9%97%B4&fr=aladdin



代码:绘制lena图像的直方图

#include "highgui.h"
#include "cv.h"
#include<iostream>

using namespace std;

void doHistDraw(IplImage* img)
{
	IplImage* hsv = cvCreateImage(cvGetSize(img), 8, 3);
	
	IplImage* h_plane = cvCreateImage(cvGetSize(img), 8, 1);
	IplImage* s_plane = cvCreateImage(cvGetSize(img), 8, 1);
	IplImage* v_plane = cvCreateImage(cvGetSize(img), 8, 1);
	IplImage* planes[] = {h_plane, s_plane};

	int h_bins = 16,s_bins = 8;
	int hist_size[] = {h_bins, s_bins};
	
	// H分量的变化范围
	float h_ranges[] = {0,180};
	// S分量的变化范围
	float s_ranges[] = {0,255};
	float* ranges[] = {h_ranges, s_ranges};
	
	//将图像转换到HSV颜色空间
	cvCvtColor(img,hsv, CV_BGR2HSV);
	cvCvtPixToPlane(hsv, h_plane, s_plane, v_plane, 0);

	//创建直方图
	CvHistogram* hist = cvCreateHist(2, hist_size, CV_HIST_ARRAY, ranges, 1);
	// 根据H,S两个平面数据统计直方图
	cvCalcHist(planes,hist, 0,0);

	//获取直方图统计的最大值和最小值,用于动态显示直方图
	float max_value;
	cvGetMinMaxHistValue(hist, 0, &max_value, 0, 0);

	//设置直方图显示图像
	int height = 240;
	int width = (h_bins*s_bins*6);
	IplImage* hist_img = cvCreateImage(cvSize(width, height), 8, 3);
	cvZero(hist_img);

	//用来进行HSV到RGB颜色转换的临时图像
	IplImage* hsv_color = cvCreateImage(cvSize(1,1), 8,3);
	IplImage* rgb_color = cvCreateImage(cvSize(1,1), 8, 3);
	int bin_w = width/(h_bins*s_bins);
	for(int h = 0; h < h_bins; h++)
	{
		for(int s = 0; s < s_bins; s++)
		{
			int i = h*s_bins+s;
			//获得直方图中的统计次数,计算显示在图中的高度
			float bin_val = cvQueryHistValue_2D(hist, h, s);
			int intensity = cvRound(bin_val*height/max_value);

			//获取当前直方图代表的颜色,转换成RGB用于绘制
			cvSet2D(hsv_color, 0, 0, cvScalar(h*180.f/h_bins, s*255.f/s_bins, 255,0));
			cvCvtColor(hsv_color, rgb_color,CV_HSV2BGR);
			CvScalar color = cvGet2D(rgb_color, 0, 0);

			cvRectangle(hist_img, cvPoint(i*bin_w, height),
				cvPoint((i+1)*bin_w, height - intensity), 
				color, -1, 8, 0);
		}
	}

	cvNamedWindow("H-S",1);
	cvShowImage("H-S",hist_img);
	cvWaitKey(0);
}

结果:lena的直方图为:




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值