zoukankan      html  css  js  c++  java
  • OpenCV2第一个马拉松8环——画一个柱状图

    在包里
    • 灰度直方图
    • 彩色直方图

    葵花宝典
    直方图的理论还是非常丰富的,应用也非常多,诸如:
    直方图均衡化
    直方图匹配(meanshift,camshift)

    在这里,我先介绍基础。怎样绘制图像的直方图。

    拿灰度图像来说。直方图就是不同的灰度相应的个数,横轴(x)就是[0,256), 纵轴(y)就是相应的个数
    例如以下图,各自是灰度直方图和彩色直方图





    初识API
    C++: void calcHist(const Mat* images, int nimages, const int* channels, InputArray mask, SparseMat& hist, int dims, const int* histSize, const float** ranges, bool uniform=true, bool accumulate=false )
     
    • images – 是一个图像数组。简单起见。我们都仅仅传一个图像. 
    • nimages – 图片数组大小。我们固定为1
    • channels – 是一个数组,灰度图像为0就能够,彩色图像要0,1,2
    • mask – 这里我们不须要。传Mat()就能够
    • hist – 输出的直方图
    • dims – 计算彩色RGB要3,gray传1
    • histSize – 是一个数组。一般来说内容就是256
    • ranges – 是一个二维数组,每一个数组包含的都是一个范围,[0,255]最经常使用,以下会看到
    • uniform – 在这里用默认就足够.
    • accumulate – 在这里用默认就足够.
    如果我们要计算灰度图像的直方图,例如以下调用就可以:
    int histSize[1]; // number of bins
    float hranges[2]; // min and max pixel value
    const float* ranges[1];
    int channels[1]; // only 1 channel used here

    histSize[0]= 256;
    hranges[0]= 0.0;
    hranges[1]= 255.0;
    ranges[0]= hranges;
    channels[0]= 0; // by default, we look at channel 0

    // Computes the 1D histogram.
    Mat hist;
    // Compute histogram
    calcHist(&image,1,channels,Mat(),hist,1,histSize,ranges);



    荷枪实弹
    先看看设计的一个灰度类
    第一个方法是构造函数
    第二个方法是获得直方图
    第三个方法是绘制直方图
    class Histogram1D {
    private:
    	int histSize[1]; // number of bins
    	float hranges[2]; // min and max pixel value
    	const float* ranges[1];
    	int channels[1]; // only 1 channel used here
    public:
    	Histogram1D() {
    		histSize[0]= 256;
    		hranges[0]= 0.0;
    		hranges[1]= 255.0;
    		ranges[0]= hranges;
    		channels[0]= 0; // by default, we look at channel 0
    	}
    	
    	// Computes the 1D histogram.
    	Mat getHistogram(const cv::Mat &image) {
    		Mat hist;
    		// Compute histogram
    		calcHist(&image,1,channels,Mat(),hist,1,histSize,ranges);
    		return hist;
    	}
    	
    	Mat getHistogramImage(const cv::Mat &image){
    		// Compute histogram first
    		Mat hist= getHistogram(image);
    		// Get min and max bin values
    		double maxVal=0;
    		double minVal=0;
    		minMaxLoc(hist, &minVal, &maxVal, 0, 0);
    		// Image on which to display histogram
    		Mat histImg(histSize[0], histSize[0],CV_8U,Scalar(255));
    		// set highest point at 90% of nbins
    		int hpt = static_cast<int>(0.9*histSize[0]);
    		// Draw a vertical line for each bin
    		for( int h = 0; h < histSize[0]; h++ ) {
    			float binVal = hist.at<float>(h);
    			int intensity = static_cast<int>(binVal*hpt/maxVal);
    			// This function draws a line between 2 points
    			line(histImg,Point(h,histSize[0]),
    			Point(h,histSize[0]-intensity),
    			Scalar::all(0));
    		}
    		return histImg;
    	}
    };
    

    然后,主函数调用
    Mat image,gray;
    image = imread( argv[1], 1 );
    if( !image.data )
    	return -1;
     cvtColor(image, gray, CV_BGR2GRAY);
        
    Histogram1D h;
    namedWindow("Histogram");
    imshow("Histogram",h.getHistogramImage(gray));

    灰度直方图已经画好,以下画彩色直方图
    画彩色直方图的过程和灰度直方图差点儿相同,是把RGB三通道分别独自出来,各自计算
    /// Separate the image in 3 places ( B, G and R )
    vector<Mat> bgr_planes;
    split( src, bgr_planes );
    如今,你就有了3个Mat存放在bgr_planes,再次强调下。OpenCV里面彩色图像的第一个通道是blue,BGR哦
    然后。你用我们之前的Histogram1D类分别调用就能够了


    举一反三
    有时候。我们还能够绘制不同色彩空间的直方图
    以下我们绘制2D Hue-Saturation histogram for a color image


    因为我对HSV色彩空间的理论没有学过。所以以下就贴出官方教程的代码
    #include <cv.h>
    #include <highgui.h>
    
    using namespace cv;
    
    int main( int argc, char** argv )
    {
        Mat src, hsv;
        if( argc != 2 || !(src=imread(argv[1], 1)).data )
            return -1;
    
        cvtColor(src, hsv, CV_BGR2HSV);
    
        // Quantize the hue to 30 levels
        // and the saturation to 32 levels
        int hbins = 30, sbins = 32;
        int histSize[] = {hbins, sbins};
        // hue varies from 0 to 179, see cvtColor
        float hranges[] = { 0, 180 };
        // saturation varies from 0 (black-gray-white) to
        // 255 (pure spectrum color)
        float sranges[] = { 0, 256 };
        const float* ranges[] = { hranges, sranges };
        MatND hist;
        // we compute the histogram from the 0-th and 1-st channels
        int channels[] = {0, 1};
    
        calcHist( &hsv, 1, channels, Mat(), // do not use mask
                 hist, 2, histSize, ranges);
        double maxVal=0;
        minMaxLoc(hist, 0, &maxVal, 0, 0);
    
        int scale = 10;
        Mat histImg = Mat::zeros(sbins*scale, hbins*10, CV_8UC3);
    
        for( int h = 0; h < hbins; h++ )
            for( int s = 0; s < sbins; s++ )
            {
                float binVal = hist.at<float>(h, s);
                int intensity = cvRound(binVal*255/maxVal);
                rectangle( histImg, Point(h*scale, s*scale),
                            Point( (h+1)*scale - 1, (s+1)*scale - 1),
                            Scalar::all(intensity),
                            CV_FILLED );
            }
    
        namedWindow( "Source", 1 );
        imshow( "Source", src );
    
        namedWindow( "H-S Histogram", 1 );
        imshow( "H-S Histogram", histImg );
        waitKey();
    }


    计算机视觉讨论群:162501053
    转载请注明:http://blog.csdn.net/abcd1992719g



    版权声明:本文博客原创文章,博客,未经同意,不得转载。

  • 相关阅读:
    关于 TIdHttp
    DCEF3 相关资料
    WPF RichTextBox 控件常用方法和属性
    Delphi Data Type to C# Data Type
    获取 CPU 序列号
    Visual Studio 调用 Delphi DLL 会退出的解决方案
    IDHttp的基本用法(转)
    TChromeTabs 优化改进
    java与json转换
    js charAt()方法
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/4608868.html
Copyright © 2011-2022 走看看