用OPencv读取一副图像的直方图


  • 列表内容

    在读取直方图前,要了解一下图像的直方图是什么?其实图像直方图就是对一副图像每个像素的像素值的统计。比如一副灰度图像,每个像素只有一个通道,所以每个像素的值就是一个uchar的值,uchar的范围就是0~~255。也就是说,每个像素点只有256种可能,它就是0~255里的一个数值。直方图就是统计一副图像的每一个像素值的个数,(比如:像素值是0 的像素有20个,像素值是1是像素有30个,……像素值是254的像素有50个,像素值是255的像素有45个)。其实在实际应用是不会直接这样用直方图,想一想,一副图像有很多像素,如果我们想画出一副图像的直方图那像素值的个数是成千上万的,是很难画出来的。于是我们一般会把直方图归一化,归一化就是用每个像素值的个数除以图像的像素总数,这样的话,每一个像素值的个数就会变成一个小数,而所有像素值的个数加起来就是1;这样直方图的值域就限定在0到1啦,但是他们的比例不变。这样好像是可以了,但是我们用计算机画直方图是需要的是整数。于是我们又可以用要的直方图图像的高乘以归一化的直方图,这样有把直方图的值域换到可以接受的范围,又不会太大。
    下面是定义了一个类用来画出一副彩色图像的HSV三个通道的直方图:

#include <opencv2/opencv.hpp> 
#include <iostream>  
#include <cstring>
using namespace  cv;
using namespace std;

/*
* 功能:计算图形SHV的直方图和灰度图像直方图
* 
*
**/
class HistogramND
{
private:
    Mat src ;//源图像
    Mat hsv ;//转化后的SHV图像
    Mat rgb_hist[3] ,gray; //
    int histSize  ,hist_w ,hist_h;//定义直方图图像的大小,宽和高
    float range[2]; //直方图定义域的范围值
    const float *ranges ;
    vector<Mat> rgb_plances ;
    MatND r_hist , g_hist , b_hist ; //用来放直方图的一维向量
public:
    HistogramND(){ //初始化
        histSize = 256 ;
        range[0] = 0.0 ;
        range[1] = 255.0 ;
        ranges = &range[0] ;
    }
    ~HistogramND(){};
    //设置原图像
    void setImage(Mat &image){
        image.copyTo(src) ;
    }
    //导入原图像
    void importImage(string iamge){
        src = cv::imread(iamge);
    }
    //把图像从RGB转换到HSV
    void RGB2HSV(){
        if(src.channels() == 3){
     cvtColor(src, hsv, COLOR_BGR2HSV);
        }
    }
    //把SHV的三个通道分解
    void HSVsplic(){
        if(src.channels() == 3){
        split(hsv ,rgb_plances);
        }
    }
    //直方图处理程序
    //如果是彩色图像通道为3,灰度图像通道为1
    void ProcHist(){ if(src.channels()== 3){
    //获取直方图
        calcHist(&rgb_plances[2] ,1 , 0 ,Mat(),r_hist ,1,&histSize ,&ranges ,true ,false);
        calcHist(&rgb_plances[1] ,1, 0 ,Mat() ,g_hist,1 ,&histSize ,&ranges ,true ,false);
        calcHist(&rgb_plances[0] ,1, 0 ,Mat() , b_hist ,1, &histSize ,&ranges ,true ,false);
        //在控制台输出直方图的值
        for (int i = 0 ; i < 255;i++)
        {
            cout<<"Red Value"<<i<<"= "<<r_hist.at<float>(i)<<endl ;
            cout<<"Green Value"<<i<<"= "<<g_hist.at<float>(i)<<endl;
            cout<<"Blue Value"<<i<<"= "<<b_hist.at<float>(i) << endl ;

        }   } else{//处理灰度图像的直方图
            calcHist(&src , 1 , 0 ,Mat() , r_hist , 1 ,&histSize ,&ranges ,true ,false) ;
        }

    }
    Mat getSrc(){
        return src;
    }
    void Dspgr(){//显示灰度图像直方图
        hist_w =  400 ;
        hist_h =  600 ;
        gray = Mat(hist_h ,hist_w , CV_8UC3 ,Scalar::all(0));
        normalize(r_hist ,r_hist,0 ,hist_w-10 ,NORM_MINMAX);//规定化直方图
        for (int i = 0 ; i < 256 ; i++)
        {
            int val = saturate_cast<int>(r_hist.at<float>(i));
            rectangle(gray ,Point(i*2+10 ,gray.rows ), Point((i+1)*2+10, gray.rows-val),Scalar(0,0,255),1,8) ;
        }
        imshow("灰度直方图",gray) ;
    }
    void DisplayHist(){//显示彩色图像直方图
       hist_w = 400 ;
       hist_h = 600 ;
       for (int i = 0 ; i < 3 ; i++)
       {
           rgb_hist[i] = Mat(hist_w , hist_h ,CV_8UC3 ,Scalar::all(0));
       }
       normalize(r_hist, r_hist, 0, hist_w-10, NORM_MINMAX);  
       normalize(g_hist, g_hist, 0, hist_w-10, NORM_MINMAX);  
       normalize(b_hist, b_hist, 0, hist_w-10, NORM_MINMAX);
       for (int i = 0 ; i < 256 ; i++)
       {
           int val = saturate_cast<int>(r_hist.at<float>(i));
           rectangle(rgb_hist[0] ,Point(i*2+10 ,rgb_hist[0].rows ), Point((i+1)*2+10, rgb_hist[0].rows-val),Scalar(0,0,255),1,8) ;
           val = saturate_cast<int>(g_hist.at<float>(i));
           rectangle(rgb_hist[1] ,Point(i*2+10 ,rgb_hist[1].rows ), Point((i+1)*2+10, rgb_hist[1].rows-val),Scalar(0,255,0),1,8) ;
           val = saturate_cast<int>(b_hist.at<float>(i));
           rectangle(rgb_hist[2] ,Point(i*2+10 ,rgb_hist[2].rows ), Point((i+1)*2+10, rgb_hist[2].rows-val),Scalar(255,0,0),1,8) ;
       }

         cv::imshow("H" , rgb_hist[2]);
         imshow("S" , rgb_hist[1]);
         imshow("V" , rgb_hist[0]);
         imshow("image" , src);
    }

};

接下来可以在main函数调用上述函数;测试结果:
原图这里写图片描述
HSV直方图

H:这里写图片描述

S:
这里写图片描述

V:

这里写图片描述

灰度图像

灰度图像

灰度图像直方图:

这里写图片描述

控制塔输出结果:

这里写图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值