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. 实现短信超链接调起APP

    因APP推广的需求,需要给APP用户定期发送短信提醒登录使用,为了更好的用户体验在短信内容中嵌入了可以直接打开APP的超链接,下面介绍一下具体的代码实现. 编辑openApp.html文件: < ...

  2. 基于C#的机器学习--模糊逻辑-穿越障碍

    模糊逻辑-穿越障碍 模糊逻辑.另一个我们经常听到的术语.但它的真正含义是什么?它是否意味着不止一件事?我们马上就会知道答案. 我们将使用模糊逻辑来帮助引导一辆自动驾驶汽车绕过障碍,如果我们做得正确,我 ...

  3. Java跨平台的实现原理

    不同操作系统支持的指令集有所差异,只要在不同操作系统上安装对应的jvm,jvm负责把Java字节码翻译成对应机器的二进制码,从而实现java语言的跨平台.

  4. 一个网页从输入URL到页面加载完的过程

    过程概述 1.浏览器查找域名对应的IP地址 2.浏览器根据IP地址与服务器建立socket连接 3.浏览器与服务器通信:浏览器请求,服务器处理请求和响应 4.浏览器与服务器断开连接 具体过程 1.搜索 ...

  5. Spark Shuffle之Hash Shuffle

    源文件放在github,如有谬误之处,欢迎指正.原文链接https://github.com/jacksu/utils4s/blob/master/spark-knowledge/md/hash-sh ...

  6. PAT L1 - 056 猜数字

    https://pintia.cn/problem-sets/994805046380707840/problems/994805074646122496 一群人坐在一起,每人猜一个 100 以内的数 ...

  7. php反射机制应用

    用来获取指定的类的信息,包括类中的属性,方法,方法权限,注释等 用途:1.thinkPHP框架中的前置,后置控制器的实现 2.与debug_backtrace函数结合使用,文件调用的权限管理 使用方法 ...

  8. Centos 7 环境下,如何使用 Apache 实现 SSL 虚拟主机 双向认证 的详细教程:

    1. testing ! ... 1 1 原文参考链接: http://showerlee.blog.51cto.com/2047005/1266712 很久没有更新LAMP的相关文档了,刚好最近单位 ...

  9. UVA12545_Bits Equalizer

    题目意思很简单,给你两个串,第一个串为0,1或者?,第二个串为0,1, 每次你可以对第一个串进行三种操作,1.0变为1:2.?变为0或者1:3.交换任意两个数的位置. 现在问你能否把第一个串变为第一个 ...

  10. UVA11625_Lines of Containers

    题意很简单,给你一个n*m的矩阵,现在问你这个矩阵能否变为标准矩阵(即数字从小到大),如果能最少需要几步呢? 其实是个赤果果的水题.记得暑假安叔也出过一个类似的题目,那个好像是在codeforces上 ...