本文主要是介绍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的直方图为:
这篇关于OpenCV入门(二十一)-- 绘制彩色图像的直方图的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!