OpenCV提供了calcHist函数来计算图像直方图。

其中C++的函数原型如下:void calcHist(const Mat* arrays, int narrays, const int* channels, InputArray mask, OutputArray
hist, int dims, const int* histSize, const float** ranges, bool uniform=true, bool accumulate=
false );

void calcHist(const Mat* arrays, int narrays, const int* channels, InputArray mask, SparseMat&
hist, int dims, const int* histSize, const float** ranges, bool uniform=true, bool accumulate=
false );

参数解释:

arrays。输入的图像的指针,可以是多幅图像,所有的图像必须有同样的深度(CV_8U or CV_32F)。同时一副图像可以有多个channes。

narrays。输入的图像的个数。

channels。用来计算直方图的channes的数组。比如输入是2副图像,第一副图像有0,1,2共三个channel,第二幅图像只有0一个channel,

那么输入就一共有4个channes,如果int channels[3] = {3, 2, 0},那么就表示是使用第二副图像的第一个通道和第一副图像的第2和第0个通道来计

算直方图。

mask。掩码。如果mask不为空,那么它必须是一个8位(CV_8U)的数组,并且它的大小的和arrays[i]的大小相同,值为1的点将用来计算

直方图。

hist。计算出来的直方图

dims。计算出来的直方图的维数。

histSize。在每一维上直方图的个数。简单把直方图看作一个一个的竖条的话,就是每一维上竖条的个数。

ranges。用来进行统计的范围。比如

float rang1[] = {0, 20};

float rang2[] = {30, 40};

const float *rangs[] = {rang1, rang2};那么就是对0,20和30,40范围的值进行统计。

uniform。每一个竖条的宽度是否相等。

accumulate。Accumulation flag. If it is set, the histogram is not cleared in the beginning
when it is allocated. This feature enables you to compute a single histogram from several
sets of arrays, or to update the histogram in time.  是否累加。如果为true,在下次计算的时候不会首先清空hist。这个地方我是这样理解的,不知道有没有错,

请高手指点。

 Histogram1D::Histogram1D(){
histSize[] = ;
hranges[] = 0.0;
hranges[] = 255.0;
ranges[] = hranges;
channels[] = ;
} cv::MatND Histogram1D::getHistogram(const cv::Mat &image){
cv::MatND hist;
cv::calcHist(&image, //source image
, //histogram from 1 image only
channels, //the channel used
cv::Mat(),//no mask is uesd
hist, //the resulting histogram
, //it is a 1D histogram
histSize, //number of bins
ranges //pixel value range
);//直方图函数
return hist;
}

下面是计算1维图像的直方图:

cv::Mat Histogram1D::getHistogramImage(const cv::Mat &image){
//compute histogram first
cv::MatND hist = getHistogram(image);
//get min and max bin values
double maxVal = ;
double minVal = ;
cv::minMaxLoc(hist,&minVal,&maxVal,,);
//Image on which to display histogram
cv::Mat histImg(histSize[],histSize[],CV_8U,cv::Scalar());
//set highest point at 90% of nbins
int hpt = static_cast<int>(0.9*histSize[]);
//Draw a vertical line for each bin
for (int h =;h<histSize[];h++)
{
float binVal = hist.at<float>(h);
int intensity = static_cast<int>(binVal*hpt/maxVal);
cv::line(histImg,cv::Point(h,histSize[]),cv::Point(h,histSize[]-intensity),cv::Scalar::all());
}
return histImg;
}

计算H-S直方图分布:

/*********************************************
内容:计算H-S 直方图分布
时间:2013 5.27
作者:恋上蛋炒面
*********************************************/
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace cv; void main()
{
Mat source = imread("baboon.jpg");
namedWindow("Source");
imshow("Source",source);
Mat hsv;
cvtColor(source,hsv,CV_BGR2HSV);
//Quantize the hue to 60 levels
//and the saturation to 64 levels
int hbins = ,sbins = ;
int histSize[] = {hbins,sbins};
int histSize[] = {hbins,sbins};
//hue varies from 0 to 179
float hranges[] = {,};
//saturation varies from 0 to 255
float sranges[] = {,};
const float *ranges[] = {hranges,sranges};
//two channels 0th,1th
int channels[] = {,};
MatND hist;
//compute h-s histogram
calcHist(&hsv,,channels,Mat(),hist,,histSize,ranges);
//get the max value
double maxVal = .;
minMaxLoc(hist,,&maxVal,,);
int scale = ;
//show the histogram on the image
Mat histImg = Mat::zeros(sbins*scale,hbins*scale,CV_8UC3);
for (int h = ;h < hbins;h++)
{
for (int s = ;s<sbins;s++)
{
float binVal = hist.at<float>(h,s);
int intensity = cvRound(binVal*0.9*/maxVal);
rectangle(histImg,Point(h*scale,s*scale),Point((h+)*scale-,(s+)*scale-),Scalar::all(intensity),CV_FILLED);
}
} namedWindow("H-S Histogram");
imshow("H-S Histogram",histImg);
imwrite("hshistogram.jpg",histImg);
waitKey();
}

RGB直方图:

 #include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp> #include <fstream> using namespace cv;
using namespace std; void main()
{
//Mat source = imread("red.jpg");
Mat source = imread("baboon.jpg"); //读取图片
//Mat source(300,300,CV_8UC3,Scalar(1,1,244));
//imwrite("red.jpg",source);
namedWindow("Source");//窗口显示图片
imshow("Source",source);
//初始化calcHist函数的参数
int channels_r[],channels_g[],channels_b[],histSize[],range;
float hranges[];
const float *ranges[];
histSize[] = ;
hranges[] = 0.0;
hranges[] = 255.0;
ranges[] = hranges;
channels_b[] = ;
channels_g[] = ;
channels_r[] = ;
MatND hist_r,hist_g,hist_b; double max_val_r,max_val_g,max_val_b;
Mat histImage(histSize[],*histSize[],CV_8UC3); //定义一个显示直方图的图片,长256*3 高256
//R
calcHist(&source,,channels_r,Mat(),hist_r,,histSize,ranges);//分别计算R,G,B的直方图分布
minMaxLoc(hist_r,,&max_val_r,,);//计算直方图中统计最大值
//G
calcHist(&source,,channels_g,Mat(),hist_g,,histSize,ranges);
minMaxLoc(hist_g,,&max_val_g,,);
//B
calcHist(&source,,channels_b,Mat(),hist_b,,histSize,ranges);
minMaxLoc(hist_b,,&max_val_b,,); //将r,g,b的最大统计值,以及像素点从0-255的统计值写入txt中
ofstream outfile1("d:\\r.txt");
ofstream outfile2("d:\\g.txt");
ofstream outfile3("d:\\b.txt"); //在txt中写入最大统计值
outfile1<<"max_val_r = "<<max_val_r<<endl;
outfile2<<"max_val_g = "<<max_val_g<<endl;
outfile3<<"max_val_b = "<<max_val_b<<endl; for (int i =;i<histSize[];i++)
{
//R,G,B= i的统计值
float binVal_r = hist_r.at<float>(i);
float binVal_g = hist_g.at<float>(i);
float binVal_b = hist_b.at<float>(i);
//统一R,G,B统计值的大小,以高度的90%封顶
int intensity_r = static_cast<int>(0.9*histSize[]*binVal_r/max_val_r);
outfile1<<i<<" "<<binVal_r<<" "<<intensity_r<<endl;
int intensity_g = static_cast<int>(0.9*histSize[]*binVal_g/max_val_g);
outfile2<<i<<" "<<binVal_g<<" "<<intensity_g<<endl;
int intensity_b = static_cast<int>(0.9*histSize[]*binVal_b/max_val_b);
outfile3<<i<<" "<<binVal_b<<" "<<intensity_b<<endl;
//画出R,G,B的直方图直线
line(histImage,Point(i,histImage.rows),Point(i,histImage.rows-intensity_r),Scalar(,,));
line(histImage,Point(i+histSize[],histImage.rows),Point(i+histSize[],histImage.rows-intensity_g),Scalar(,,));
line(histImage,Point(i+histSize[]*,histImage.rows),Point(i+histSize[]*,histImage.rows-intensity_b),Scalar(,,));
}
namedWindow("RGB Histogram");
imshow("RGB Histogram",histImage);
imwrite("RGB_Histogram.jpg",histImage);
waitKey();
}

opencv2 直方图之calchist函数使用(转)的更多相关文章

  1. opencv2——直方图5

    (一)图像直方图 图像的构成是有像素点构成的,每个像素点的值代表着该点的颜色(灰度图或者彩色图).所谓直方图就是对图像的中的这些像素点的值进行统计,得到一个统一的整体的灰度概念.直方图的好处就在于可以 ...

  2. OpenCV2:直方图

    一.简介 在一个单通道的灰度图像中,每个像素的值介于0(黑色)~255(白色)之间,灰色图像的直方图有256个条目(或称为容器)

  3. opencv —— calcHist、minMaxLoc 计算并绘制图像直方图、寻找图像全局最大最小值

    直方图概述 简单来说,直方图就是对数据进行统计的一种方法,这些数据可以是梯度.方向.色彩或任何其他特征.它的表现形式是一种二维统计表,横纵坐标分别是统计样本和该样本对应的某个属性的度量. 计算直方图: ...

  4. opencv直方图该怎么画

    图像直方图是反映图像中像素分布特性的统计表,一般显示如下: 其中横坐标代表的是图像像素的种类,或者说是灰度级,纵坐标代表的是每一级灰度下像素数或者该灰度级下像素数在所有图像总像素数总所占的百分比. 直 ...

  5. 【浅墨著作】《OpenCV3编程入门》内容简单介绍&amp;勘误&amp;配套源码下载

    经过近一年的沉淀和总结,<OpenCV3编程入门>一书最终和大家见面了. 近期有为数不少的小伙伴们发邮件给浅墨建议最好在博客里面贴出这本书的文件夹,方便大家更好的了解这本书的内容.事实上近 ...

  6. OpenCV编程入门目录

    第一部分 快速上手OpenCV 第1 章 邂逅OpenCV 图像处理.计算机视觉与OpenCV OpenCV 概述 起源及发展 应用概述 .2OpenCV 基本架构分析 .3OpenCV3 带来了什么 ...

  7. 【Opencv】直方图函数 calchist()

    calchist函数需要包含头文件 #include <opencv2/imgproc/imgproc.hpp> 函数声明(三个重载 calchist函数): //! computes t ...

  8. Opencv中直方图函数calcHist

    calcHist函数在Opencv中是极难理解的一个函数,一方面是参数说明晦涩难懂,另一方面,说明书给出的实例也不足以令人完全搞清楚该函数的使用方式.最难理解的是第6,7,8个参数dims.histS ...

  9. OpenCV2+入门系列(四):计算图像的直方图,平均灰度,灰度方差

    本篇懒得排版,直接在网页html编辑器编辑 在图像处理时,我们常常需要求出图像的直方图.灰度平均值.灰度的方差,这里给出一个opencv2+自带程序,实现这些功能. 直方图 对于直方图,使用cv::c ...

随机推荐

  1. Python基础入门(模块和包)

    1 模块 1.1 什么是模块 在 Python 中,一个 .py 文件就称之为一个模块(Module). 我们学习过函数,知道函数是实现一项或多项功能的一段程序 .其实模块就是函数功能的扩展.为什么这 ...

  2. wepy中如何使用stylus等样式预处理器

    wepy中如何使用stylus等样式预处理器 一.如何在wepy中使用stylus 1.安装wepy-compiler-stylus(以及stylus, stylus-loader) npm inst ...

  3. java 数据存储

    简单的记录一下而已. 1.寄存器: 特点:快,存储有限. 存储地点:处理器内部. 2.堆栈 特点:仅次于寄存器快,通过堆栈指针在处理器获取支持.堆栈指针下移,分配内存,上移,释放内存.此外须知生命周期 ...

  4. es6 babel编译

    本文主要参照阮一峰的es6入门,为提高自己写了一份随笔. 原文地址请戳这里  ECMAScript 6 入门 ECMAScript 6是JavaScript语言的下一代标准.因为当前版本的ES6是在2 ...

  5. php memcache 使用学习

    Memcache是什么Memcache是danga.com的一个项目,最早是为 LiveJournal 服务的,目前全世界不少人使用这个缓存项目来构建自己大负载的网站,来分担数据库的压力.它可以应对任 ...

  6. LeetCode 289. Game of Life (C++)

    题目: According to the Wikipedia's article: "The Game of Life, also known simply as Life, is a ce ...

  7. Java 学习笔记 ------第三章 基础语法

    本章学习目标: 认识类型与变量 学习运算符的基本使用 了解类型转换细节 运用基本流程语法 一.类型(基本类型) 所谓基本类型,就是在使用时,得考虑一下数据用多少内存长度存比较经济,利用程序语法告诉JV ...

  8. RIGHT-BICEP单元测试——“二柱子四则运算升级版”

    RIGHT-BICEP单元测试 ——“二柱子四则运算升级版” ”单元测试“这对于我们来说是一个全新的专业含义,在上了软件工程这门课,并当堂编写了简单的"求一组数中的最大值"函数的单 ...

  9. UVALive 6913 I Want That Cake 博弈+dp

    题目链接: http://acm.hust.edu.cn/vjudge/problem/96343 I Want That Cake Time Limit: 3000MS 64bit IO Forma ...

  10. HDU 5225 枚举

    题目链接: hdu:http://acm.hdu.edu.cn/showproblem.php?pid=5225 bc(中文):http://bestcoder.hdu.edu.cn/contests ...