一、介绍

图像直方图是用一表示数字图像中亮度分布的直方图,标绘了图像中每个亮度值的像素数。可以借助观察该直方图了解需要如何调整亮度分布的直方图。这种直方图中,横坐标的左侧为纯黑、较暗的区域,而右侧为较亮、纯白的区域。因此,一张较暗图片的图像直方图中的数据多集中于左侧和中间部分,而整体明亮、只有少量阴影的图像则相反。计算机视觉邻域常借助图像直方图来实现图像的二值化。

二、API函数

C++ Void calcHist(const Mat* images,//输入图像指针int images,// 图像数目const int* channels,// 通道数InputArray mask,// 输入mask,可选,不用OutputArray hist,//输出的直方图数据int dims,// 维数const int* histsize,// 直方图级数const float* ranges,// 值域范围bool uniform,// true by defaultbool accumulate)// false by defaut
函数cvRound,cvFloor,cvCeil 都是用一种舍入的方法将输入浮点数转换成整数:cvRound():返回跟参数最接近的整数值,即四舍五入;
cvFloor():返回不大于参数的最大整数值,即向下取整;
cvCeil():返回不小于参数的最小整数值,即向上取整;

三、绘制图像直方图

1、使用API函数 calcHist计算图像直方图;

2、进行直方图归一化;

3、绘制各级直方图;

#include<opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
int main()
{Mat src, dst;src = imread("1.jpg");cvtColor(src, src, COLOR_BGR2GRAY);int histSize = 16;float range[] = { 0, 256 };const float* histRange = { range };if (src.data && src.channels()==1){cout << "您输入的是灰度图像" << endl;Mat hist;calcHist(&src, 1, 0, Mat(), hist, 1, &histSize, &histRange, true, false);//绘制直方图int hist_w = 512, hist_h = 400;//直方图中各点x轴距离int distance = cvRound((double)hist_w / histSize);//创建一个图像以显示直方图Mat histImage1(hist_h, hist_w, src.type(), Scalar(255, 255, 255));//归一化直方图normalize(hist, hist, 0, hist_h, NORM_MINMAX, -1,Mat());for (int i = 1; i < histSize; i++){// hist_h - cvRound(hist.at<float>(i)):hist.at<float>(i)存储的值是从图像//左上角为0开始计算的,所以需要使用hist_h减以后才是坐标轴的纵轴值line(histImage1, Point(distance * (i-1), hist_h - cvRound(hist.at<float>(i-1))),Point(distance * (i), hist_h - cvRound(hist.at<float>(i))),Scalar(0,0,255),2,8,0);}namedWindow("calcHist1", WINDOW_AUTOSIZE);imshow("calcHist1", histImage1);}else if (src.data && src.channels() == 3){cout << "您输入的是彩色图像" << endl;vector<Mat> mv;split(src, mv);Mat b_hist, g_hist, r_hist;calcHist(&mv[0], 1, 0, Mat(), b_hist, 1, &histSize, &histRange, true, false);calcHist(&mv[1], 1, 0, Mat(), g_hist, 1, &histSize, &histRange, true, false);calcHist(&mv[2], 1, 0, Mat(), r_hist, 1, &histSize, &histRange, true, false);// 绘制直方图int hist_w = 512,hist_h = 400;int distance = cvRound((double)hist_w / histSize);Mat histImage(hist_h, hist_w, CV_8UC3, Scalar(255, 255, 255));normalize(b_hist, b_hist, 0, hist_h, NORM_MINMAX, -1, Mat());normalize(g_hist, g_hist, 0, hist_h, NORM_MINMAX, -1, Mat());normalize(r_hist, r_hist, 0, hist_h, NORM_MINMAX, -1, Mat());for (int i = 1; i < histSize; i++){//line(histImage, Point(distance * (i - 1), hist_h - cvRound(b_hist.at<float>(i - 1))),Point(distance * (i), hist_h - cvRound(b_hist.at<float>(i))),Scalar(255, 0, 0), 2, 8, 0);line(histImage, Point(distance * (i - 1), hist_h - cvRound(g_hist.at<float>(i - 1))),Point(distance * (i), hist_h - cvRound(g_hist.at<float>(i))),Scalar(0, 255, 0), 2, 8, 0);line(histImage, Point(distance * (i - 1), hist_h - cvRound(r_hist.at<float>(i - 1))),Point(distance * (i), hist_h - cvRound(r_hist.at<float>(i))),Scalar(0, 0, 255), 2, 8, 0);}namedWindow("calcHist", WINDOW_AUTOSIZE);imshow("calcHist", histImage);}else{cout << "您未输入图像" << endl;return -1;}waitKey(0);return 0;
}

四、直方图比较

  1. 为了比较两个直方图( H1 和 H2 ),首先我们必须选择度量( d(H1,H2)来表示两个直方图的匹配度。
  2. OpenCV实现函数cv :: compareHist进行比较。它还提供4种不同的指标来计算匹配:
  • 相关性(CV_COMP_CORREL)(1为最相似)

其中:

N是直方图库的总数。

  • Chi-Square(CV_COMP_CHISQR)(0为最相似)

  • 交点(method= CV_COMP_INTERSECT)(越大越相似)

  • Bhattacharyya distance ( CV_COMP_BHATTACHARYYA )(0为最相似)

*Method* Base - Base
*Correlation* 1.000000
*Chi-square* 0.000000
*Intersection* 24.391548
*Bhattacharyya* 0.000000
#include<opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
int main()
{Mat src, dst;src = imread("12.bmp");namedWindow("原图", WINDOW_AUTOSIZE);imshow("原图", src);int histSize = 16;float range[] = { 0, 256 };const float* histRange = { range };if (src.data && src.channels()==1){cout << "您输入的是灰度图像" << endl;Mat hist;calcHist(&src, 1, 0, Mat(), hist, 1, &histSize, &histRange, true, false);//绘制直方图int hist_w = 512, hist_h = 400;//直方图中各点x轴距离int distance = cvRound((double)hist_w / histSize);//创建一个图像以显示直方图Mat histImage1(hist_h, hist_w, src.type(), Scalar(255, 255, 255));//归一化直方图normalize(hist, hist, 0, hist_h, NORM_MINMAX, -1,Mat());for (int i = 1; i < histSize; i++){// hist_h - cvRound(hist.at<float>(i)):hist.at<float>(i)存储的值是从图像//左上角为0开始计算的,所以需要使用hist_h减以后才是坐标轴的纵轴值line(histImage1, Point(distance * (i-1), hist_h - cvRound(hist.at<float>(i-1))),Point(distance * (i), hist_h - cvRound(hist.at<float>(i))),Scalar(0,0,255),2,8,0);}namedWindow("calcHist1", WINDOW_AUTOSIZE);imshow("calcHist1", histImage1);}else if (src.data && src.channels() == 3){cout << "您输入的是彩色图像" << endl;vector<Mat> mv;split(src, mv);Mat b_hist, g_hist, r_hist;calcHist(&mv[0], 1, 0, Mat(), b_hist, 1, &histSize, &histRange, true, false);calcHist(&mv[1], 1, 0, Mat(), g_hist, 1, &histSize, &histRange, true, false);calcHist(&mv[2], 1, 0, Mat(), r_hist, 1, &histSize, &histRange, true, false);// 绘制直方图int hist_w = 512,hist_h = 400;int distance = cvRound((double)hist_w / histSize);Mat histImage(hist_h, hist_w, CV_8UC3, Scalar(255, 255, 255));normalize(b_hist, b_hist, 0, hist_h, NORM_MINMAX, -1, Mat());normalize(g_hist, g_hist, 0, hist_h, NORM_MINMAX, -1, Mat());normalize(r_hist, r_hist, 0, hist_h, NORM_MINMAX, -1, Mat());for (int i = 1; i < histSize; i++){//line(histImage, Point(distance * (i - 1), hist_h - cvRound(b_hist.at<float>(i - 1))),Point(distance * (i), hist_h - cvRound(b_hist.at<float>(i))),Scalar(255, 0, 0), 2, 8, 0);line(histImage, Point(distance * (i - 1), hist_h - cvRound(g_hist.at<float>(i - 1))),Point(distance * (i), hist_h - cvRound(g_hist.at<float>(i))),Scalar(0, 255, 0), 2, 8, 0);line(histImage, Point(distance * (i - 1), hist_h - cvRound(r_hist.at<float>(i - 1))),Point(distance * (i), hist_h - cvRound(r_hist.at<float>(i))),Scalar(0, 0, 255), 2, 8, 0);}//比较直方图相似度double similar = compareHist(b_hist, b_hist, CV_COMP_CORREL);cout << similar << endl;namedWindow("calcHist", WINDOW_AUTOSIZE);imshow("calcHist", histImage);}else{cout << "您未输入图像" << endl;return -1;}waitKey(0);return 0;
}

直方图(opencv)相关推荐

  1. python绘制灰度图片直方图-opencv+python 统计及绘制直方图

    灰度直方图概括了图像的灰度级信息,简单的来说就是每个灰度级图像中的像素个数以及占有率,创建直方图无外乎两个步骤,统计直方图数据,再用绘图库绘制直方图. 统计直方图数据 首先要稍微理解一些与函数相关的术 ...

  2. 【图像处理 直方图 OpenCV实现】

    直方图与直方图匹配 最后一个代码比较实用,对于小角度的模板匹配,还是可以用此函数的. 文章目录 前言 一.直方图 二.使用步骤 1.引入库 2.绘制直方图 总结 前言 直方图统计的原理.直方图代表的图 ...

  3. 【OpenCV】直方图应用:直方图均衡化,直方图匹配,对比直方图

    本文链接:https://blog.csdn.net/xiaowei_cqu/article/details/7606607                                       ...

  4. 【拜小白opencv】45-二维H-S直方图绘制----calcHist()函数、minMaxLoc()函数

    常言道"温故而知新",写此文章就是对自己目前学习内容的小小的总结与记录. 本文力求用最简洁的语言,详细的代码将此部分内容讲解清楚,但由于博主同样是刚刚接触OpenCV,或许表达上有 ...

  5. opencv直方图该怎么画

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

  6. 【opencv】直方图-3:二维直方图(一维灰度强度,二维色相饱和度,)

    4_10_3_直方图3:二维直方图 - OpenCV中文官方文档 学习查找和绘制2D直方图. 前情提要 一维直方图仅考虑一个特征,即像素的灰度强度值. 二维直方图要考虑两个特征. 通常,它用于查找颜色 ...

  7. 【OpenCV-Python】21.OpenCV的二维直方图

    21.OpenCV的二维直方图 文章目录 前言 一.OpenCV中的二维直方图 二.Numpy中的二维直方图 三.直方图示例 1.使用Numpy函数计算直方图 2.使用OpenCV函数计算直方图 四. ...

  8. opencv图像处理总结

    opencv图像处理基本操作 1. 矩阵数据类型 通用矩阵数据类型: CV_<bit_depth>(S|U|F)C<number_of_channels> 其中,S表示带符号整 ...

  9. 直方图应用:直方图均衡化,直方图匹配,对比直方图

    直方图均衡化 直方图均衡化(Histogram Equalization)是直方图最典型的应用,是图像点运算的一种.对于一幅输入图像,通过运算产生一幅输出图像,点运算是指输出图像的每个像素点的灰度值由 ...

  10. 【图像处理】——图像增强Python实现直方图均衡化

    目录 一.相关概念 1.灰度直方图概念(hist) 2.灰度概率累积函数(cdf) 3.灰度直方图均衡化(equalizehist) 4.均衡化适用范围 二.均衡化的目的以及求解步骤 1.目的 2.求 ...

最新文章

  1. Flex Air程序打包成独立的exe安装文件
  2. python获取主机ip_Python 获取本地主机 hostname 和 IP 地址的简单方法
  3. 洛谷P2412 查单词 [trie树 RMQ]
  4. Myeclipse10下搭建SSH框架(图解)Struts2.1+Spring3.0+Hibernate3.3
  5. Shell教程(六):函数、联机帮助
  6. nRF51822之BootLoader
  7. 简单表单提交php教程,PHP 表单数据提交与接收 超级简单《SSS教程 10》
  8. 我的Go语言学习之旅七:创建一个GUI窗体
  9. go读取excel_Golang操作Excel
  10. 一起写框架-Ioc内核容器的实现-对象的调用-属性注入容器的对象(十)
  11. java mysql访问类_java 访问数据库公共类
  12. 深入解析:Row Movement 的原理和性能影响与关联
  13. Mybatis Interceptor 拦截器
  14. vijos 1083 小白逛公园
  15. 量化干货:量化交易系统设计的六大细节
  16. underscore 系列之字符实体与 _.escape
  17. 批量创建文件夹-批处理(一)
  18. 51单片机入门教程(2)——流水灯的实现
  19. 微型计算机的硬盘电源,17款SATA硬盘盒产品横向评测
  20. 2016十月新番简介

热门文章

  1. Django 模型成员2.2
  2. [JavaScript] 日期时间戳的使用与计算
  3. java模拟网银登录_用java编写模拟网上银行登录及存取款业务
  4. Android Dialog 弹框之外的区域 默认透明背景色修改
  5. 关于微信公众号注意事项
  6. [LeetCode] 130. Surrounded Regions Java
  7. Centos 6启动流程详解
  8. Oracle 触发器 Update 不能操作本表的疑问
  9. Qt/Linux 下的摄像头捕获(Video4Linux2)
  10. usaco Mixing Milk