S0.6 直方图均衡化
S0.6 直方图均衡化
- 直方图均衡化能提高图像的质量
累积直方图
这是后面均衡化所要知道的先验知识。
如果说直方图统计的是等于像素值的数量,那么累积直方图统计的就是小于等于像素值的数量

均衡化步骤
我们均衡化的目标就是把灰度直方图变得平坦,那么什么是最平坦的直方图呢?当然就是下图这样:
4X4的图像,每个像素有4个,按概率论的角度来讲,这是均匀分布。

我们一般用和概率相关的直方图来表示,像这样:

我们希望直方图都像均匀分布的直方图那样,可以换种思路:只要任何直方图的累积直方图像均匀分布的累积直方图那样(即阶梯型),我们同样可以使直方图均匀分布。
假设我们有如下直方图:

首先,我们说明灰度直方图均衡化可能会发生的事:
- 相邻的两个像素可能会合并为一个,其后所有的像素值向前移一格。如图:
图1的像素值0和1由于太小而合并,小的具体判断标准是少于累积灰度直方图的\(\frac{k}{N}\),N为原像素种类,这里为8(其实可以取更大的任何值),k为第几个柱子,这里是第1个,具体看例子。
- 可能会空出一个像素区域。
当某一个像素的数量太大时,(例如图中的像素值6),它的前面往往会空出一个像素区域,以平衡该区域。(在直方图中我们假设不做分离,把像素值当做一个整体,不把同一像素值的数量分为两份,但可以合并不同像素值的数量)
例子
实际操作我们是看累积直方图,一个一个柱子分析并建立像素映射关系表。
第一个柱子为像素值0,它的值为0.02,小于\(\frac{1}{8}\)=0.125,大于\(\frac{0}{8}\)=0,于是把它映射到0。(需要说明的是,本例子像素值正好是0,1,2,3……,要是像素值不是这样,读者可以想想)
第二个柱子为像素值1,它的值为0.06,小于\(\frac{1}{8}\)=0.125,大于\(\frac{0}{8}\)=0.125,于是把它映射到0。
第三个柱子为像素值2,它的值为0.16,小于\(\frac{2}{8}\)=0.25,大于\(\frac{1}{8}\)=0.125,于是把它映射到1。
第四个柱子为像素值3,它的值为0.28,小于\(\frac{3}{8}\)=0.375,大于\(\frac{2}{8}\)=0.25,于是把它映射到2。
第五个柱子为像素值4,它的值为0.42,小于\(\frac{4}{8}\)=0.5,大于\(\frac{3}{8}\)=0.375,于是把它映射到3。
第六个柱子为像素值5,它的值为0.62,小于\(\frac{5}{8}\)=0.625,大于\(\frac{4}{8}\)=0.5,于是把它映射到4。
第七个柱子为像素值6,它的值为0.84,小于\(\frac{7}{8}\)=0.875,大于\(\frac{6}{8}\)=0.75,于是把它映射到6。
第八个柱子为像素值7,它的值为1,等于\(\frac{8}{8}\)=1,于是把它映射到7。
映射表f->g如下:
| f | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
|---|---|---|---|---|---|---|---|---|
| g | 0 | 0 | 1 | 2 | 3 | 4 | 6 | 7 |
我们根据映射关系得到新的均衡化直方图:(横坐标变成g)

我想你应该已经懂了-。-
算法代码演示
我们统计图片0-255的灰度,然后均衡化这个灰度图。
from cv2 import *
import numpy as np
import matplotlib.pyplot as plt
src = imread(r"images/favorite/Lena.jpg",0)
dst = src.copy()
hist_array = [0 for i in range(256)]
for i in range(src.shape[0]):
for j in range(src.shape[1]):
hist_array[src[i,j]] += 1
hist_sum_array = [hist_array[i] for i in range(256)]
for i in range(1, len(hist_array)):
hist_sum_array[i] += hist_sum_array[i-1]
print(hist_array)
# print(hist_sum_array)
plt.figure()
plt.subplot(2,2,3)
width = 0.35
index = np.arange(0, 256, 1)
plt.bar(index, hist_array, width, color = "#87CEFA")
plt.xlabel("f")
plt.ylabel("c(f)")
plt.xticks(np.arange(0, 300, 60))
plt.yticks(np.arange(0, 1000, 100))
plt.subplot(2,2,4)
k = 0
eta = 1.0
map = [i for i in range(256)]
for i in range(256):
while hist_sum_array[i]/256 - k*eta > 0:
k+=1
map[i] = k
if map[i] == 256:
map[i] = 255
print(map)
for k in range(256):
# print(dst[0])
# print(k,"->",map[k])
for i in range(dst.shape[0]):
for j in range(dst.shape[1]):
if(src[i,j] == k):
dst[i,j] = map[k]
# for i in range(dst.shape[0]):
# print(dst[i])
hist_array = [0 for i in range(256)]
for i in range(dst.shape[0]):
for j in range(dst.shape[1]):
hist_array[dst[i,j]] += 1
print(hist_array)
plt.bar(index, hist_array, width, color="#87CEFA")
plt.xlabel("g")
plt.ylabel("c(g)")
plt.xticks(np.arange(0, 300, 60))
plt.yticks(np.arange(0, 1000, 100))
plt.subplot(221), plt.imshow(src,'gray'), plt.title('Origin')
plt.subplot(222), plt.imshow(dst,'gray'), plt.title('Equalize')
plt.show()

OpenCV函数实现
参考https://blog.csdn.net/yjp19871013/article/details/78232726
OpenCV均衡方法有两种,第一种(全局直方图均衡化)属于本文提到的方法,即使某一像素过大也不会把它减少,第二种(限制对比度的自适应直方图均衡化)方法会把过大像素减少。
from cv2 import *
import matplotlib.pyplot as plt
src = imread(r"images/favorite/Lena.jpg",0)
hist = calcHist([src], [0], None, [256], [0,256])
equ_src = equalizeHist(src)
equ_hist = calcHist([equ_src], [0], None, [256], [0,256])
clahe = createCLAHE(clipLimit=3.0)
clahe_src = clahe.apply(src)
clahe_hist = calcHist(clahe_src, [0], None, [256], [0, 256])
plt.subplot(231), plt.imshow(src,'gray'), plt.title('Origin')
plt.subplot(232), plt.imshow(equ_src,'gray'), plt.title('Equalize')
plt.subplot(233), plt.imshow(clahe_src,'gray'), plt.title('Clahe')
plt.subplot(234)
plt.hist(hist.flatten(), 256, [0, 256], color='b')
plt.title('Origin Hist')
plt.subplot(235)
plt.hist(equ_hist.flatten(), 256, [0, 256], color='b')
plt.title('Equalize Hist')
plt.subplot(236)
plt.hist(clahe_hist.flatten(), 256, [0, 256], color='b')
plt.title('Equalize Hist')
plt.show()

S0.6 直方图均衡化的更多相关文章
- matlab 直方图均衡化
原理: 直方图均衡化首先是一种灰度级变换的方法: 原来的灰度范围[r0,rk]变换到[s0,sk]变换函数为:s=T(r); 为便于实现,可以用查找表(look-up table)的方式存储,即:原始 ...
- 灰度图像--图像增强 直方图均衡化(Histogram equalization)
灰度图像--图像增强 直方图均衡化(Histogram equalization) 转载请标明本文出处:http://blog.csdn.net/tonyshengtan,欢迎大家转载,发现博客被某些 ...
- 图解直方图均衡化及其Python实现
在理解直方图均衡化的过程中,参考了一些书籍和博客,让人困惑的是,笔者对于直方图的理解还是停留在表面,并没有深入理解其内涵.因此,本文拟结合图片对直方图的概念进行阐述,并给出其Python实现,最后对她 ...
- MATLAB - 练习程序,直方图均衡化
直方图均衡化的作用是图像增强. 有两个问题比较难懂,一是为什么要选用累积分布函数,二是为什么使用累积分布函数处理后像素值会均匀分布. 第一个问题.均衡化过程中,必须要保证两个条件:①像素无论怎么映射, ...
- opencv直方图均衡化
#include <iostream> #include "highgui.h" #include "cv.h" #include "cx ...
- opencv 彩色图像亮度、对比度调节 直方图均衡化
直接上代码: #include <Windows.h> #include <iostream>// for stand I/O #include <string> ...
- OpenCV-Python教程(10、直方图均衡化)
相比C++而言,Python适合做原型.本系列的文章介绍如何在Python中用OpenCV图形库,以及与C++调用相应OpenCV函数的不同之处.这篇文章介绍在Python中使用OpenCV和NumP ...
- 数学之路-python计算实战(14)-机器视觉-图像增强(直方图均衡化)
我们来看一个灰度图像,让表示灰度出现的次数,这样图像中灰度为 的像素的出现概率是 是图像中全部的灰度数, 是图像中全部的像素数, 实际上是图像的直方图,归一化到 . 把 作为相应于 的累计概率 ...
- 直方图均衡化CImg实现
这篇博客是关于试用CImg库来实现灰度图和彩色图的直方图均衡化操作.感觉效果还不错,除了彩色图在均衡化时会有一定的色彩失真. C++代码实现: // // hEqualization.hpp // 直 ...
随机推荐
- 如何识别Studio 5000程序开发版本号
前言:中.大型AB PLC的编程软件从以前的RSLogix 5000到目前的Studio 5000,都是有版本号的,如RSLogix 5000 V19.0.Studio 5000 V32.高版本的软件 ...
- BLSTM的训练算法、解码算法以及模型的改进
摘要 BLSTM解码时,解码器需要等待整个音频到达后才开始解码,因为时间反方向的前向传播需要末尾的历史信息.BLSTM这一延时问题使其不适用与实时语音识别.context-sensitive-chun ...
- html-webpack-plugin详解
引言 我们来看看主要作用: 为html文件中引入的外部资源如script.link动态添加每次compile后的hash,防止引用缓存的外部文件问题 可以生成创建html入口文件,比如单页面可以生成一 ...
- class和style属性
值类型: 1.表达式计算出的字符串结果或者字符串. 2.对象(表达式或者对象名,建议采用对象名) key为className,值的真假控制这个name的有无. //class <div v-bi ...
- Sublime Text 3删除插件
Ctrl+Shift+P调出命令窗口,输入remove: 选择第二个Remove Package,会看到如下界面: 里面列出了你已经安装的插件,之后选择你想要卸载的就好了.
- spring cloud 学习笔记(1)
SpringCloud + Eureka / Nacos git:https://github.com/huanmsf/springCloudLearn.git 项目目录: 父pom: <?xm ...
- zynq DMA控制器
Zynq-7000系列器件PS端的DMA控制器采用ARM的IP核DMA-330(PL-330)实现. 特点: 1.8个独立的通道,4个可用于PL—PS间数据管理,每个通道有1024Byte的MFIFO ...
- Java中int和String类型之间转换
int –> String int i=123; String s=""; 第一种方法:s=i+""; //会产生两个String对象 第二种方法:s=S ...
- 试题 E: 迷宫
[问题描述]下图给出了一个迷宫的平面图,其中标记为 1 的为障碍,标记为 0 的为可以通行的地方.010000000100001001110000迷宫的入口为左上角,出口为右下角,在迷宫中,只能从一个 ...
- MySQL时区错误导致server time zone value 'Öйú±ê׼ʱ¼ä' 错误
时区错误 由于中国是东八区,跟mysql配置不同,需要修改: 管理员登录MySQL OK成功