从这篇博文开始,小生正式从一个毫不相干专业转投数字图像处理。废话不多说了,talk is cheap. show me the code.

  • 直方图均衡化目的

由于一些图像灰度的分布过于集中,这样会导致图像的层次不够分明,直方图均衡化就是为了让图像的灰度分布更均匀,图像的层次感更强。

  • 数学原理

  基于连续灰度分布的结论推导

直方图均衡化属于数字图像处理中灰度变换(intensity transformation)的内容,灰度变换的目的就是找到一个合适的映射函数s=T(r).将原图像的灰度值映射到新的图像中,已达到优化图像的目的。

假设原图像的灰度统计直方图标准化后为pr(r).原图像灰度范围为(0~L-1)。那么直方图均衡化找到的就是这样一个映射函数:

设映射后的图像的灰度分布为ps(s),在由概率论相关理论(随机变量函数的概率密度与随机变量概率密度的关系)可知:

对映射函数两边进行求导

所以我们可以得到变换后的图像直方图分布为

我们可以看到,变换后的图像灰度直方图分布恒为1/(L-1),这就达到了上面的目的,使得图像的灰度分布更均匀,层次感更强。

注:在灰度变换中,变换函数T(r)需要满足下面的两点要求,

  1. 当0≤r≤L-1时,T(r)是一个严格递增函数。
  2. 当0≤r≤L-1时,0≤T(r)≤L-1。

第一点要求的原因是,对于变化前像素和变换后像素灰度的明暗顺序不能改变,之所以要严格递增,是为了确保变化前和变换后像素可以一一对应。

第二点要求的原因是,变换后的图像不能超过原先的灰度级数。

不难发现,其实直方图均衡化的过程并不一定满足条件1。所以该变换时不可逆的。

  公式的离散化

设原图像灰度等级为0、1、2……L-1.离散化后的映射公式就是

在利用上面公式进行计算的时候,需要把计算的结果s(r),近似为最近的整数。

  • 基于OpenCV的直方图均衡化

OpenCV中有专门的直方图均衡化函数,equalizeHist,定义的头文件在imaproc/imaproc.hpp中。

基于OpenCV的直方图均衡化代码段:

 //load the original image and show
Mat src,dst_1;
src = imread("test.jpg",);
namedWindow("OriginalGrayImage");
imshow("OriginalGrayImage",src); //use the OpenCV measure do histogram equalization
equalizeHist(src,dst_1);
namedWindow("histogram equalization_opencv");
imshow("histogram equalization_opencv",dst_1);

仿真结果:

原图:

使用equalizeHist均衡化后的结果:

  • 根据推导过程,自己编写的直方图均衡化

代码段如下:

 //rewrite the histogram algorithm
//get some needed information
int nr = src.rows;
int nc = src.cols;
int n = nr*nc;
Mat dst_2(nr,nc,CV_8U); //get the histogram of original image
uchar *p_1 = NULL;
unsigned int hist[] = {};
for(int i=;i<nr;i++)
{
p_1 = src.ptr<uchar>(i);
for(int j=;j<nc;j++)
{
hist[p_1[j]] = hist[p_1[j]]+;
}
} //calculate the transform function
uchar transf_fun[] = {};
transf_fun[] = (uchar)(*hist[]/n);
for(int i=;i<;i++)
{
hist[i] = hist[i-]+hist[i];
transf_fun[i] = (uchar)(*hist[i]/n);
} //pad dst_2 the equalized values
uchar *p_2 = NULL;
for(int i=;i<nr;i++)
{
p_2 = dst_2.ptr<uchar>(i);
p_1 = src.ptr<uchar>(i);
for(int j=;j<nc;j++)
{
p_2[j] = transf_fun[p_1[j]];
}
} //show the results of our own histogram algorithm
namedWindow("histogram equalization_own");
imshow("histogram equalization_own",dst_2)

运行结果:

OpenCV-跟我一起学数字图像处理之直方图均衡化的更多相关文章

  1. OpenCV-跟我学一起学数字图像处理之中值滤波

    中值滤波(median filter)在数字图像处理中属于空域平滑滤波的内容(spatial filtering).对消除椒盐噪声具有很好的效果. 数学原理 为了讲述的便捷,我们以灰度图为例.RGB三 ...

  2. OpenCV-跟我一起学数字图像处理之拉普拉斯算子

    https://www.cnblogs.com/german-iris/p/4840647.html Laplace算子和Sobel算子一样,属于空间锐化滤波操作.起本质与前面的Spatial Fil ...

  3. 【OpenCV】像素操作的数字图像处理

    之前几天捣鼓matlab,用来处理数字图像,矩阵操作什么的,如果忘记线性代数就真的GG了. 在用了matlab被深深地吐槽之后,决定改用opencv,C++貌似也是处理数字图像的很好的工具 1. 在u ...

  4. 图像处理之直方图均衡化及C源码实现

    1 直方图均衡化(Histogram Equalization)简介 图像对比度增强的方法可以分成两类:一类是直接对比度增强方法;另一类是间接对比度增强方法.直方图拉伸和直方图均衡化是两种最常见的间接 ...

  5. opencv——图像的灰度处理(线性变换/拉伸/直方图/均衡化)

    实验内容及实验原理: 1.灰度的线性变换 灰度的线性变换就是将图像中所有的点的灰度按照线性灰度变换函数进行变换.该线性灰度变换函数是一个一维线性函数:f(x)=a*x+b 其中参数a为线性函数的斜率, ...

  6. 数字图像处理作业使用OpenCV - 使用笔记

    数字图像处理作业的输入图像全部都是灰度图像,所以汇总一下自己遇到的问题答案. OCV的图像容器是Mat<typename>,可以用imread(filename)读取图像,filename ...

  7. python数字图像处理(1):环境安装与配置

    一提到数字图像处理编程,可能大多数人就会想到matlab,但matlab也有自身的缺点: 1.不开源,价格贵 2.软件容量大.一般3G以上,高版本甚至达5G以上. 3.只能做研究,不易转化成软件. 因 ...

  8. 数字图像处理笔记与体会(一)——matlab编程基础

    最近开始学习数字图像处理,使用matlab实现,下面我就来记录笔记和体会,一方面是给大家提供参考,另一方面是防止我忘记了. 复习一下: 1.数字图像是用一个数字矩阵来表示的,数字阵列中的每个数字,表示 ...

  9. 数字图像处理:基于MATLAB的车牌识别项目 标签: 图像处理matlab算法 2017-06-24 09:17 98人阅读 评论(0)

    学过了数字图像处理,就进行一个综合性强的小项目来巩固一下知识吧.前阵子编写调试了一套基于MATLAB的车牌识别的项目的代码.今天又重新改进了一下代码,识别的效果好一点了,也精简了一些代码.这里没有使用 ...

随机推荐

  1. Spring Boot + MyBatis + Pagehelper 配置多数据源

    前言: 本文为springboot结合mybatis配置多数据源,在项目当中很多情况是使用主从数据源来读写分离,还有就是操作多库,本文介绍如何一个项目同时使用2个数据源. 也希望大家带着思考去学习!博 ...

  2. centos6.9 安装完xampp 7.2.0后,执行/opt/lampp/lampp报错

    # /opt/lampp/lampp egrep: error while loading shared libraries: libc.so.6: cannot open shared object ...

  3. mongodb基本使用(三)

    MongoDB 创建数据库 语法 MongoDB 创建数据库的语法格式如下: use DATABASE_NAME 如果数据库不存在,则创建数据库,否则切换到指定数据库. 如果你想查看所有数据库,可以使 ...

  4. 【Py大法系列--01】20多行代码生成你的微信聊天机器人

    前言 近期Stack Overflow公布了一项调查显示,Python已经成了发展最快的主流编程语言,Python搭乘着数据科学和机器学习以及人工智能的浪潮,席卷了整个技术圈.越来越多的人想了解.想学 ...

  5. 将React Native 集成进现有OC项目中(过程记录) 、jsCodeLocation 生成方式总结

    将RN集成到现有OC项目应该是最常见的,特别是已经有OC项目的,不太可能会去专门搞个纯RN的项目.又因为RN不同版本,引用的依赖可能不尽相同,所以特别说明下,本文参考的文档是React Native ...

  6. 作业6 团队项目之需求 (NABCD模型)

     N A B C D模型分析 WorkGroup:NewApps 组员:欧其锋(201306114305  http://www.cnblogs.com/ouqifeng/) 吕日荣(20130611 ...

  7. 使用Fabric自动化你的任务

    Fabric是一个Python库,可以通过SSH在多个host上批量执行任务.你可以编写任务脚本,然后通过Fabric在本地就可以使用SSH在大量远程服务器上自动运行.这些功能非常适合应用的自动化部署 ...

  8. 关于Actions和Robot的区别简单说明

    Actions和Robot都是可以用来模拟键盘操作,但是两者还是有区别的 Actions actions =new Actions(driver) 实例化一个Actions后,我们可以使用action ...

  9. redis哨兵机制二(转)

    概述 Redis-Sentinel是Redis官方推荐的高可用性(HA)解决方案,当用Redis做Master-slave的高可用方案时,假如 master宕机了,Redis本身(包括它的很多客户端) ...

  10. [转帖]Intel为何吊打AMD,先进半导体工艺带来什么?

    Intel为何吊打AMD,先进半导体工艺带来什么? 2016-3-10 15:38  |  作者:Strike   |  关键字:超能课堂,半导体工艺,CPU制程 分享到       按照摩尔定律的发 ...