【从零学习openCV】使用直方图统计像素
来源:互联网 发布:淘宝权重的因素 编辑:程序博客网 时间:2024/06/05 19:58
1. 计算图像直方图
图像是由像素组成的,在一个单通道的灰度图像中,每个像素的值介于0到255之间,而直方图就是一个简单的表,给出了一幅或者一组图像中拥有给定数值的像素数量。当然直方图也可以归一化,归一化后的所有项的和为1,在这种情况下,每一项给出的都是拥有特定数值的像素在图像中占的比例。
下面我们看看如何用opencv计算单通道图像的直方图,我用一个Histogram1D封装了与单通道直方图操作相关的变量和函数:
#ifndef HISTOGRAM1D_H#define HISTOGRAM1D_H#include <opencv2/core/core.hpp>#include <opencv2/highgui/highgui.hpp>#include <opencv2/imgproc/imgproc.hpp>using namespace cv;class Histogram1D{private: int histSize[1]; //项的数量 float hranges[2]; //像素的最小及最大值 const float* ranges[1]; int channels[1]; //仅用到一个通道public: Histogram1D(){ //准备1D直方图的参数 histSize[0] =256; hranges[0] = 0.0; hranges[1] = 255.0; ranges[0] = hranges; channels[0] = 0; //默认情况,我们考察0号通道 } //计算1D直方图 MatND getHistogram(const Mat&image) { MatND hist; //计算直方图 calcHist(&image, 1, //计算单张图像的直方图 channels, //通道的数量 Mat(), //不使用图像作为掩码 hist, //返回的直方图 1, //这是1D的直方图 histSize, //项的数量 ranges //像素值的范围 ); return hist; } //计算1D直方图,并返回一幅图像 Mat getHistogramImage(const Mat &image) { //首先计算直方图 MatND hist = getHistogram(image); //获取最大值和最小值 double maxVal = 0; double minVal = 0; minMaxLoc(hist,&minVal,&maxVal,0,0); //显示直方图的图像 Mat histImg(histSize[0],histSize[0],CV_8U,Scalar(255)); //设置最高点为nbins的90% int hpt = static_cast<int>(0.9*histSize[0]); //每个条目都绘制一条垂直线 for(int h = 0;h<histSize[0];h++){ float binVal =hist.at<float>(h); int intensity = static_cast<int>(binVal*hpt/maxVal); //两点之间绘制一条线 line(histImg,Point(h,histSize[0]), Point(h,histSize[0]-intensity), Scalar::all(0)); } return histImg; }};#endif // HISTOGRAM1D_Hmain函数如下,直接调用getHistogramImage即可得到直方图:
#include <QCoreApplication>#include "Histogram1D.h"int main(int argc, char *argv[]){ namedWindow( "src1", WINDOW_AUTOSIZE ); namedWindow( "src2", WINDOW_AUTOSIZE ); Mat image = imread( "test.jpg",0 ); //读取灰度图 Histogram1D h; while(1) { imshow( "src1", image); imshow( "src2", h.getHistogramImage(image)); char c = waitKey(30); if( 27==c ) return 0; }}效果如下:
原始灰度图像
直方图
当然我们还可以用calcHist函数来计算彩色BGR图像的直方图,这时候直方图变成三维的了:
#ifndef COLORHISTOGRAM_H#define COLORHISTOGRAM_H#include <opencv2/core/core.hpp>#include <opencv2/highgui/highgui.hpp>#include <opencv2/imgproc/imgproc.hpp>#include<QDebug>using namespace cv;class ColorHistogram{private: int histSize[3]; //项的数量 float hranges[2]; //像素的最小及最大值 const float* ranges[3]; int channels[3]; //用到三个通道public: ColorHistogram(){ //准备彩色直方图的参数 histSize[0] = histSize[1]= histSize[2]=256; hranges[0] = 0.0; hranges[1] = 255.0; ranges[0] =ranges[1]=ranges[2]=hranges; //所有通道都有相同的范围 channels[0] = 0; //3个通道 channels[1] = 1; channels[2] = 2; } //计算三维直方图 MatND getHistogram(const Mat&image) { MatND hist; //计算直方图 calcHist(&image, 1, //计算单张图像的直方图 channels, //通道的数量 Mat(), //不使用图像作为掩码 hist, //返回的直方图 3, //这是三维的直方图 histSize, //项的数量 ranges //像素值的范围 ); qDebug()<<hist.dims; return hist; }};#endif // COLORHISTOGRAM_H这时候getHistogram返回的是一个256*256*256的矩阵,包含了超过1600万个元素,这计算代价是非常大的,可以参考opencv操作像素中所述的方法减少颜色的数量,或者可以使用cv::SparseMat数据结构,用于存储大型的稀疏矩阵,这样可以极大地减少内存的消耗。
PS:至于绘制三维直方图的绘制比较麻烦,以后有时间看看用qt实现个界面,感兴趣的话可以先参看下这篇文章http://blog.csdn.net/foolpanda1168/article/details/6078463
2. 查找表的使用
查找表实际上就是一个简单的一对一(或者多对一)的函数,定义了如何将像素值转换为新的值,本质上就是一个一维数组。
openCV中用cv::LUT的方法对图像应用查找表生成新图像,我们将这个功能加到Histogram1D类中:
//应用查找表,image为输入图像,lookup是1*256的unchar矩阵,代表查找表Mat applyLookUp(const Mat&image,const Mat&lookup){ Mat result; //应用查找表 LUT(image,lookup,result); return result;}这时我们可以做个简单的实验,比如将原先每个像素强度进行反转,即x变成255-x:
int dim(256); Mat lut(1,&dim,CV_8U); for(int i=0;i<256;i++) { lut.at<uchar>(i) = 255-i; } Mat reverse = h.applyLookUp(image,lut);
效果如下:
3. 直方图均衡化
直方图均衡化其实就是为了让直方图更加的平坦,能够大幅改善图像的外观。
openCV中提供了一个简单易用的函数cv::equalizeHist来执行直方图均衡化。
//直方图均衡化 Mat equalize(const Mat &image) { Mat result; equalizeHist(image,result); return result; }
应用与之前的图像,效果如下:
、
可以看出图像的对比度增强了,直方图也更加的平坦。
参考书籍
《openCV2计算机视觉编程手册》
(转载请注明作者和出处:Shawn-HT http://blog.csdn.net/shawn_ht)
0 0
- 【从零学习openCV】使用直方图统计像素
- 【OpenCV学习笔记 007】使用直方图统计像素
- 使用直方图统计像素
- 【从零学习openCV】opecv操作像素
- opencv 学习之直方图统计
- opencv直方图使用学习
- OpenCV学习之直方图统计应用【转】
- 《OpenCV2》编程手册——使用直方图统计像素
- OpenCV—使用积分图像统计像素
- Opencv学习笔记——绘制图像的像素直方图
- OpenCV_用直方图统计像素
- opencv 直方图统计
- opencv直方图统计1
- opencv直方图统计2
- opencv直方图统计例子
- opencv灰度直方图统计
- Opencv图像识别从零到精通(10)-----直方图均衡化与直方图拉伸
- 关于OpenCV中rectangle函数的使用+统计直方图
- Yar – 并行的RPC框架(Concurrent RPC framework)
- 被坑了,js语法跟Java面向对象语法还是有区别的
- c#窗体关闭时可查看关闭的原因
- 小黑小波比.sql某字段累加1或者减1
- 几张趣图让你快速了解云计算起源及发展
- 【从零学习openCV】使用直方图统计像素
- JQuery Validate学习笔记
- iOS: CGPathAddArc和CGPathAddArcToPoint函数
- css3在工作中运用上的总结(圆角、内阴影、外阴影)
- FilenameFilter文件名称过滤器
- junit相关内容
- gc overhead limit exceeded解决方案
- 2014年校招面试问题总结
- 华三交换机 S3100 web页登陆设置