有关opencv的学习(10)—彩色图像的直方图显示

将彩色图像分割进BGR三个通道,然后分别显示其直方图,代码如下:

#ifndef ColorHistogramND_h
#define ColorHistogramND_h


#endif /* ColorHistogramND_h */

class ColorHistogramND {
    
private:
    
    cv::Mat image;
    int histSize[1],hisWidth,hisHeight;     //直方图的大小及宽度、高度
    float range[2];    //值范围
    const float *ranges;
    cv::Mat channelsBGR[3];     //分离的BGR通道
    cv::MatND outputBGR[3];     //输出直方图分量
    
    
public:
    
    ColorHistogramND()
    {
        //准备用于彩色图像的默认参数
        
        histSize[0]=256;
        //每个维度256个箱子
        hisWidth=500;
        hisHeight=500;
        range[0]=0.0;//从0开始(含)
        range[1]=255.0;//到256(不含)
        ranges=&range[0];
        
        
    }
    
    //导入图片
    bool importImage(cv::String path){
        image = cv::imread(path);
        if (!image.data)
            return false;
        return true;
    }
    
    
   //分离通道
    void splitChannels()
    {
        split(image, channelsBGR);
    };
    
    
    //计算直方图
    void getColorHistogram()
    {
        calcHist(&channelsBGR[0], 1, 0, cv::Mat(), outputBGR[0], 1, histSize, &ranges);
        calcHist(&channelsBGR[1], 1, 0, cv::Mat(), outputBGR[1], 1, histSize, &ranges);
        calcHist(&channelsBGR[2], 1, 0, cv::Mat(), outputBGR[2], 1, histSize, &ranges);
        
        for(int i=0;i<histSize[0];i++)
        {
            std::cout << i << "B:" << outputBGR[0].at<float>(i);
            std::cout <<"G:" << outputBGR[1].at<float>(i);
            std::cout << "R:" << outputBGR[2].at<float>(i) << std::endl;
        }
    }
        //显示直方图
        void displayColorHisttogram()
        {
            cv::Mat bgrHist[3];
            for (int i = 0; i < 3; i++)
            {
                bgrHist[i] = cv::Mat(hisWidth, hisHeight, CV_8UC3, cv::Scalar::all(0));
            }
            
            normalize(outputBGR[0], outputBGR[0], 0, hisWidth - 20, cv::NORM_MINMAX);
            normalize(outputBGR[1], outputBGR[1], 0, hisWidth - 20, cv::NORM_MINMAX);
            normalize(outputBGR[2], outputBGR[2], 0, hisWidth - 20, cv::NORM_MINMAX);
            
            
            for (int i = 0; i < histSize[0]; i++)
            {
                int val = cv::saturate_cast<int>(outputBGR[0].at<float>(i));
                rectangle(bgrHist[0], cv::Point(i * 2 + 10, bgrHist[0].rows), cv::Point((i + 1) * 2 + 10, bgrHist[0].rows - val), cvScalar(255, 0, 0), 1, 8);
                
                val = cv::saturate_cast<int>(outputBGR[1].at<float>(i));
                rectangle(bgrHist[1], cv::Point(i * 2 + 10, bgrHist[1].rows), cv::Point((i + 1) * 2 + 10, bgrHist[1].rows - val), cvScalar(0, 255, 0), 1, 8);
                
                val = cv::saturate_cast<int>(outputBGR[2].at<float>(i));
                rectangle(bgrHist[2], cv::Point(i * 2 + 10, bgrHist[2].rows), cv::Point((i + 1) * 2 + 10, bgrHist[2].rows - val), cvScalar(0, 0, 255), 1, 8);
                
            }
            
            cv::imshow("B", bgrHist[0]);
            imshow("G", bgrHist[1]);
            imshow("R", bgrHist[2]);
            imshow("image", image);
    
    }
    
};

主程序如下:

#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/opencv.hpp>
#include "ColorHistogramND.h"

using namespace cv;
using namespace std;

int main()
{
    //Mat image=imread("/Users/zhangxiaoyu/Desktop/lena.jpg");
    //if(image.empty())
    //{
        //cout<<"Error!cannot be read...../n";
        //return -1;
    //}
    
    string path="/Users/zhangxiaoyu/Desktop/lena.jpg";
    
    ColorHistogramND hist;
    if(!hist.importImage(path))
    {
        cout<<"Import error!!"<<endl;
        return -1;
    }
    hist.splitChannels();
    hist.getColorHistogram();
    hist.displayColorHisttogram();
    
    waitKey(0);
    return 0;

}

显示如下:


原始图片如下:


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章