opencv学习之路(19)、直方图

一、概述

 二、一维灰度直方图

 1 #include "opencv2/opencv.hpp"
 2 #include<iostream>
 3 using namespace cv;
 4 using namespace std;
 5 
 6 void main()
 7 {
 8     Mat img = imread("E://0.jpg", 0);  //以灰度方式打开,灰度图和彩色图直方图结果不同
 9     imshow("src", img);
10 
11     Mat dstHist;  //定义存储直方图变量
12     int dims = 1;  //需要统计的特征数目(只统计灰度值)
13     float hranges[] = {0, 256};  //范围[0,256),注意是最大值加1
14     const float* ranges[] = {hranges};
15     int bins = 256;//组距:简单理解为直方图分为几个柱子
16     int channels = 0;
17     //计算直方图
18     calcHist(&img, 1, &channels, Mat(), dstHist, dims, &bins, ranges);
19 
20     int scale = 1;
21     Mat dstImg(bins * scale, bins*1, CV_8UC3, Scalar(0));  //定义直方图输出图像,长×宽
22     double minValue = 0;
23     double maxValue = 0;
24     minMaxLoc(dstHist, &minValue, &maxValue);//统计直方图dstHist的最小最大值,并返回该值位置
25     int hpt = saturate_cast<int>(0.9*bins);  //设置最大值并防止溢出
26     int j=0;
27     //绘制直方图
28     for(int i=0; i<256; i++)
29     {
30         float binValue = dstHist.at<float>(i);
31         //if(i>250)
32             cout<<"i="<<i<<"---Value="<<binValue<<endl;
33         int realValue = saturate_cast<int>(binValue*hpt/maxValue);  //归一化数据
34             //cout<<"i="<<i<<"---Value="<<realValue<<endl;
35         line(dstImg, Point(i*scale, bins-1), Point(i*scale, bins-realValue), Scalar(0, 255, 0), 1, 8);//左上角和右下角坐标,坐标系如下图所示
36         //rectangle(dstImg, Point(i*scale, bins-1), Point(i*scale+1, bins-realValue), Scalar(0, 255, 0), 1);
37         //rectangle(dstImg, Point(j*scale, bins-1), Point(j*scale+1, bins-realValue), Scalar(rand()%255, rand()%255, rand()%255), -1);
38         //rectangle(dstImg, Point(j*scale, bins-1), Point(j*scale+1, bins-realValue), Scalar(rand()%255, rand()%255, rand()%255), -1);
39         //j=j+3;
40     }
41     imshow("Histogram", dstImg);
42     waitKey(0);
43     destroyAllWindows();
44 }

第35行代码的坐标为Point(i*scale, bins-1), Point(i*scale, bins-realValue)的原因。

如果觉得直方图太密集了,可以调整宽度

 三、不均匀灰度直方图

 1 #include "opencv2/opencv.hpp"
 2 #include<iostream>
 3 using namespace cv;
 4 using namespace std;
 5 
 6 void main()
 7 {
 8     Mat img = imread("E://0.jpg",0); 
 9     imshow("src", img);
10 
11     Mat dstHist;  
12     int channels = 0; 
13     int histSize[1]={5};
14     float hranges[6]={0,50,100,150,200,256};
15     const float* ranges[1]={hranges};
16     int size=256;
17     //计算直方图
18     calcHist(&img,1,&channels,Mat(),dstHist,1,histSize,ranges,false);
19 
20     int scale=1;
21     Mat dstImg(size*scale,size,CV_8UC3,Scalar(0));
22     double minValue=0;
23     double maxValue=0;
24     minMaxLoc(dstHist,&minValue,&maxValue,0,0);
25     int hpt=saturate_cast<int>(0.9*size);//设置最大值并防止溢出
26     int j=0;
27     for (int i = 0; i < 5; i++)
28     {
29         float binValue=dstHist.at<float>(i);
30         cout<<"i="<<i<<"---Value="<<binValue<<endl;
31         int realValue=saturate_cast<int>(binValue*hpt/maxValue);
32         rectangle(dstImg,Point(j*scale,size-1),Point((j+20)*scale-1,size-realValue),Scalar(0, 255, 0), -1);
33         j+=35;
34     }
35 
36     imshow("Histogram", dstImg);
37     waitKey(0);
38     destroyAllWindows();
39 
40 }

 四、RGB三色直方图

 1 #include "opencv2/opencv.hpp"
 2 using namespace cv;
 3 
 4 void main()
 5 {
 6     Mat src=imread("E://0.jpg");
 7     int bins = 256;
 8     int hist_size[] = {bins};
 9     float range[] = { 0, 256 };
10     const float* ranges[] = { range};
11     Mat hist_r,hist_g,hist_b;
12 
13     int channels_r[] = {2};
14     calcHist( &src, 1, channels_r, Mat(), // do not use mask
15         hist_r, 1, hist_size, ranges,
16         true, // the histogram is uniform
17         false );
18 
19     int channels_g[] = {1};
20     calcHist( &src, 1, channels_g, Mat(),hist_g, 1, hist_size, ranges,true,false);
21     int channels_b[] = {0};
22     calcHist( &src, 1, channels_b, Mat(),hist_b, 1, hist_size, ranges,true,false);
23 
24     double max_val_r,max_val_g,max_val_b;
25     minMaxLoc(hist_r, 0, &max_val_r, 0, 0);
26     minMaxLoc(hist_g, 0, &max_val_g, 0, 0);
27     minMaxLoc(hist_b, 0, &max_val_b, 0, 0);
28     int scale = 1;
29     int hist_height=256;
30     Mat hist_img = Mat::zeros(hist_height, bins*3+5, CV_8UC3);
31     for(int i=0;i<bins;i++)
32     {
33         float bin_val_r = hist_r.at<float>(i); 
34         float bin_val_g = hist_g.at<float>(i);
35         float bin_val_b = hist_b.at<float>(i);
36         int intensity_r = cvRound(bin_val_r*hist_height/max_val_r);  //要绘制的高度
37         int intensity_g = cvRound(bin_val_g*hist_height/max_val_g);  //要绘制的高度
38         int intensity_b = cvRound(bin_val_b*hist_height/max_val_b);  //要绘制的高度
39         rectangle(hist_img,Point(i*scale,hist_height-1),
40             Point((i+1)*scale - 1, hist_height - intensity_r),
41             CV_RGB(255,0,0));
42 
43         rectangle(hist_img,Point((i+bins)*scale,hist_height-1),
44             Point((i+bins+1)*scale - 1, hist_height - intensity_g),
45             CV_RGB(0,255,0));
46 
47         rectangle(hist_img,Point((i+bins*2)*scale,hist_height-1),
48             Point((i+bins*2+1)*scale - 1, hist_height - intensity_b),
49             CV_RGB(0,0,255));
50 
51     }
52     imshow( "src", src );
53     imshow( "RGB Histogram", hist_img );
54 
55     waitKey(0);
56     destroyAllWindows();
57 
58 }

五、二维直方图

 1 #include "opencv2/opencv.hpp"
 2 using namespace cv;
 3 
 4 void main()
 5 {
 6     Mat src=imread("E://0.jpg");
 7     Mat hsv;
 8     int Bbins = 256, Gbins = 256;
 9     int histSize[] = {Bbins, Gbins};
10     float hranges[] = { 0, 256 };
11     float sranges[] = { 0, 256 };
12     const float* ranges[] = { hranges, sranges };
13     Mat hist;
14 
15     int channels[] = {0, 1};
16     calcHist( &src, 1, channels, Mat(), hist, 2, histSize, ranges);
17     double maxVal=0;
18     minMaxLoc(hist, 0, &maxVal, 0, 0);
19     int scale = 2;
20     Mat histImg = Mat::zeros(Bbins*(scale), Bbins*(scale), CV_8UC3);
21     for( int h = 0; h < Bbins; h++ )
22         for( int s = 0; s < Bbins; s++ )
23         {
24             float binVal = hist.at<float>(h, s);
25             //cout<<"h="<<h<<"s="<<s<<"binValue="<<binVal<<endl;
26             //int intensity = cvRound(binVal*255/maxVal);
27             int intensity = int(binVal*255/maxVal);
28             rectangle( histImg, Point(h*scale, s*scale),
29                 Point((h+1)*scale - 1, (s+1)*scale - 1),
30                 Scalar::all(intensity),CV_FILLED );
31         }
32     namedWindow( "Source", 1 );
33     imshow( "Source", src );
34     namedWindow( "B-G Histogram", 1 );
35     imshow( "B-G Histogram", histImg );
36 
37     waitKey(0);
38     destroyAllWindows();
39 
40 }

 

posted @ 2017-08-16 21:33  进击的小猴子  阅读(1906)  评论(0编辑  收藏  举报