OpenCV之颜色空间:
颜色空间RGB(Red 红色,Green 绿色,Blue 蓝色)
R的取值范围:0-255
G的取值范围:0-255
B的取值范围:0-255
颜色空间HSV (Hue 色相,Saturation 饱和度,intensity 亮度)
H的取值范围:0-179
S的取值范围:0-255
V的取值范围:0-255
颜色空间HLS (Hue 色相,lightness 亮度,Saturation 饱和度)
H的取值范围:0-179
L的取值范围:0-255
S的取值范围:0-255
—————————————————————————————————————————————————————
知道了一些经常使用的颜色空间各个通道的像素的取值范围,我们以下讨论颜色直方图
一维直方图:
比方,我们仅仅计算上图S通道的直方图,并有30个bin。
<span style="font-size:18px;">#include<opencv2\core\core.hpp> #include<opencv2\highgui\highgui.hpp> #include<opencv2\imgproc\imgproc.hpp> using namespace cv; #include<iostream> using namespace std; int main(int argc ,char** argv) { Mat src,hsv; if(argc != 2 || !(src = imread(argv[1],1)).data || src.channels() != 3) return -1; //颜色空间的转换BGR转HSV cvtColor(src,hsv,CV_BGR2HSV); //把H通道分为30个bin,把S通道等分为32bin int hbins = 30; //int sbins = 32; //int histSize[] = {hbins,sbins}; int histSize[] = {hbins}; //H的取值范围 0-179 float hranges [] = {0,180}; //S的取值范围 0-255 //float sranges [] ={0,255}; //const float* ranges [] = {hranges,sranges}; const float* ranges [] = {hranges}; MatND hist; //我们依据图像第一个通道一维直方图 int channels[] = {0}; calcHist(&hsv,1,channels,Mat(),hist,1,histSize,ranges,true,false); //输出直方图 cout<<hist<<endl; return 0; }</span>
输出结果,肯定一个30维的向量:
解释:第一个数60571,就是代表H在[0,5]之间的像素点的个数,第二个数12194就是代表H在[6,11]之间的像素点的个数。
—————————————————————————————————————————————————————
二维直方图:
<span style="font-size:18px;"><span style="font-family:Microsoft YaHei;font-size:14px;"><span style="font-family:Microsoft YaHei;font-size:14px;">#include<opencv2\core\core.hpp> #include<opencv2\highgui\highgui.hpp> #include<opencv2\imgproc\imgproc.hpp> using namespace cv; #include<iostream> using namespace std; int main(int argc ,char** argv) { Mat src,hsv; if(argc != 2 || !(src = imread(argv[1],1)).data || src.channels() != 3) return -1; //颜色空间的转换BGR转HSV cvtColor(src,hsv,CV_BGR2HSV); //把H通道分为30个bin,把S通道等分为32bin int hbins = 5; int sbins = 4; int histSize[] = {hbins,sbins}; //H的取值范围 0-179 float hranges [] = {0,180}; //S的取值范围 0-255 float sranges [] ={0,256}; const float* ranges [] = {hranges,sranges}; MatND hist; //我们依据图像第一个通道和第二通道,计算二维直方图 int channels[] = {0,1}; calcHist(&hsv,1,channels,Mat(),hist,2,histSize,ranges,true,false); //输出直方图 cout<<hist<<endl; return 0; }</span></span></span>
我们以上图为例,输出的二维直方图为:
如今我们来解释一下,这是一个5行4列二维直方图,第一行第一列的128239,代表H和S的数值在[0,35]x[0,63],第二行第一列的18585代表H和S的值在[36,71]x[0,63],依次类推,怎么验证呢?我们仅仅须要把上面的程序,改几个数,比方我们仅仅计算H和S的值在[36,71]x[0,63]的直方图:
<span style="font-size:18px;">#include<opencv2\core\core.hpp> #include<opencv2\highgui\highgui.hpp> #include<opencv2\imgproc\imgproc.hpp> using namespace cv; #include<iostream> using namespace std; int main(int argc ,char** argv) { Mat src,hsv; if(argc != 2 || !(src = imread(argv[1],1)).data || src.channels() != 3) return -1; //颜色空间的转换BGR转HSV cvtColor(src,hsv,CV_BGR2HSV); //把H通道分为30个bin,把S通道等分为32bin int hbins = 1; int sbins = 1; int histSize[] = {hbins,sbins}; //H的取值范围 0-179 float hranges [] = {36,72}; //S的取值范围 0-255 float sranges [] ={0,64}; const float* ranges [] = {hranges,sranges}; MatND hist; //我们依据图像第一个通道和第二通道,计算二维直方图 int channels[] = {0,1}; calcHist(&hsv,1,channels,Mat(),hist,2,histSize,ranges,true,false); //输出直方图 cout<<hist<<endl; return 0; }</span>
输出结果:
。
________________________________________________________________________________________________________________________________
理解了简单的颜色直方图,把颜色直方图作为一张图片简单的特征,做一个简单的图像检索。