zoukankan      html  css  js  c++  java
  • 图像特征之颜色直方图

    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<opencv2corecore.hpp>
    #include<opencv2highguihighgui.hpp>
    #include<opencv2imgprocimgproc.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<opencv2corecore.hpp>
    #include<opencv2highguihighgui.hpp>
    #include<opencv2imgprocimgproc.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<opencv2corecore.hpp>
    #include<opencv2highguihighgui.hpp>
    #include<opencv2imgprocimgproc.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>

    输出结果:


    ________________________________________________________________________________________________________________________________

    理解了简单的颜色直方图,把颜色直方图作为一张图片简单的特征,做一个简单的图像检索。

  • 相关阅读:
    javascript定义函数后立即执行(IIFE)
    工作流选型专项,Camunda or flowable or?
    Excel中的xlsm宏密码怎么破解
    《生命是什么》总结
    《麦肯锡教我的思考武器》总结
    《作为意志和表象的世界》总结
    Go语言如何将json时间格式化为dateime格式
    《少有人走的路》总结
    《时间简史》总结
    架构的常规分类及复用重点
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/4385326.html
Copyright © 2011-2022 走看看