首页 > 代码库 > OpenCV2马拉松第8圈——绘制直方图
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
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=http://www.mamicode.com/imread(argv[1], 1)).data )>
计算机视觉讨论群:162501053
转载请注明:http://blog.csdn.net/abcd1992719g
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。