有關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;

}

顯示如下:


原始圖片如下:


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