直方图均衡,顾名思义,是处理影像灰度在统计直方图上分布问题,是一种图像增强算法。以图像某灰度值分布概率以及低于该值得所有值得分布概率之和p与该图像所有灰度级别L的乘积作为该灰度值均衡后的值。

直方图均衡公式:

以8位灰度图像的直方图均衡为例,第一步是统计图像所有灰度值在0~255分布概率;第二步通过从低到高累加各个灰度级别概率p(i),直方均衡公式p(i)*255计算出对应值,生成查找表;第三部通过原图对应查找表生成直方均衡后图形。

统计概率分布和直方均衡计算:

private Map<Integer, Double> getPDF(BufferedImage image) {Map<Integer, Double> map = new HashMap<>();int width = image.getWidth();int height = image.getHeight();double totalPixel = 3 * width * height;for (int i = 0; i < 256; i++) {map.put(i, 0.0);// 通过循环,往集合里面填充0~255个位置,初始值都为0}//分别统计图像上0~255上分布总数for (int i = 0; i < image.getWidth(); i++) {for (int j = 0; j < image.getHeight(); j++) {int rgb = image.getRGB(i, j);int r = (rgb >> 16) & 0xff;int g = (rgb >> 8) & 0xff;int b = rgb & 0xff;map.put(r, map.get(r) + 1);map.put(g, map.get(g) + 1);map.put(b, map.get(b) + 1);}}
直方均衡计算,生成查找表:
private void getTable(Map<Integer, Double> map) {double param = 0.0;for(int i = 0;i < 256;i++) {param += map.get(i);table[i] = (int)Math.round(param * 255);}}

测试图像:

分布概率直方图:

直方均衡后:

直方均衡后概率分布:

从图像和概率直方图分布看,原图的灰度峰值在50左右,且大部分都分布在较小灰度值上,经过直方图均衡后,图像变亮,且灰度值在0~255上分布比较均匀。这是传统直方图均衡实现方式,但其中存在缺陷,由于中间部分灰度因为占据较小概率分布,有可能被其附近较大概率的灰度淹没。例如,灰度值为100的统计概率为50%,那么均衡后值为128,而110处概率分布为50.1%,那么均衡计算后值仍为128,原图中100~110之间灰度也就被淹没。从测试图像细节中也可以发现这个问题,如下所示:

原图部分细节:

从图像上可以看到三叉路口存在较明显的亮度差异形成的边界线。那么再看直方均衡后图像细节。

由于直方均衡的作用,部分灰度级被淹没,三叉路口路面边界线已经丢失,整个路面也完全变为白色,丢失了大量细节。目前直方图均衡算法的改进也有很多,一种是基于HSI色彩空间。由于RGB色彩空间灰度值为离散整数值,在计算过程中容易丢失精度。将图像从RGB色彩空间转换为HSI色彩空间,分离出来的亮度I值为连续变换值,在直方均衡过程中更容易保留更多细节。那么首先要将RGB转换为HSI。

RGB转HSI代码:

public Double[] rgb2HSI(int[] rgb) {double sum = rgb[0] + rgb[1] + rgb[2];double r = rgb[0] / sum;double g = rgb[1] / sum;double b = rgb[2] / sum;double s1 = 0.5 * ((r - g) + (r - b));double s2 = Math.pow((r - g), 2) + (r - b) * (g - b);double s3 = s1 / Math.sqrt(s2);double h = 0.0;if (b <= g) {h = Math.acos(s3);} else if (b > g) {h = 2 * Math.PI - Math.acos(s3);}double s = 1 - 3 * Math.min(r, Math.min(g, b));double H = ((h * 180.0) / Math.PI);double S = s * 100.0;double I = sum / 3;return new Double[] { H, S, I };}

HSI转换RGB代码:

public Integer[] hsi2RGB(Double[] hsi) {double h = (hsi[0] * Math.PI) / 180.0;double s = hsi[1] / 100.0;double i = hsi[2] / 255.0;double x = i * (1 - s);double y = i * (1 + (s * Math.cos(h)) / Math.cos(Math.PI / 3.0 - h));double z = 3 * i - (x + y);double r = 0, g = 0, b = 0;if (h < ((2 * Math.PI) / 3)) {b = x;r = y;g = z;} else if (h >= ((2 * Math.PI) / 3) && h < ((4 * Math.PI) / 3)) {h = h - ((2 * Math.PI) / 3.0);x = i * (1 - s);y = i * (1 + (s * Math.cos(h)) / Math.cos(Math.PI / 3.0 - h));z = 3 * i - (x + y);r = x;g = y;b = z;} else if (h >= ((4 * Math.PI) / 3) && h < ((2 * Math.PI))) {h = h - ((4 * Math.PI) / 3.0);x = i * (1 - s);y = i * (1 + (s * Math.cos(h)) / Math.cos(Math.PI / 3.0 - h));z = 3 * i - (x + y);g = x;b = y;r = z;}int red = (int) Math.round((r * 255));int green = (int) Math.round((g * 255));int blue = (int) Math.round((b * 255));return new Integer[] { red, green, blue};}

尽管HSI色彩空间可以解决直方均衡中灰度级丢失问题,但HSI与RGB色彩空间的转换需要耗费大量计算,导致图像处理过程比较缓慢。下面就介绍一下博主自己想到的一种解决办法。

虽然使用传统直方均衡容易丢失部分灰度级,但仍然可以采用传统方式进行直方均衡计算,将直方均衡计算后图像与原图进行均值融合,便可以恢复部分丢失的灰度值。尽管该方法不能完全恢复丢失的灰度级别,但相对于传统直方均衡,已经有了很大改善。处理流程为:对原图分别进行直方均衡和自动色阶,将计算后的图像进行均值融合,得到最终图像。

效果图:

相对于传统直方均衡,该方法计算后图像稍暗,但可以保留更多细节。再看细节部分。

从放大后的细节上看,三叉路口处的边界线仍然清晰可辨。路面也没有完全变为白色。

实际上,编程实现还可以对算法进一步优化,由于自动色阶算法同样需要概率分布计算,那么直方图均衡和自动色阶的概率分布计算可以一起做!然后根据概率分布分别计算直方图均衡和自动色阶查找表,之后取出原图每个像素,利用查找表计算直方图均衡和自动色阶对应的值,对两个值求均值即可。

实现代码:

public BufferedImage histogramEqualization(BufferedImage image) {BufferedImage resultImage = new BufferedImage(image.getWidth(), image.getHeight(), image.getType());Map<Integer, Double> map = getPDF(image);getTable(map);  //初始化直方图均衡查找表// 自动色阶前裁切掉最暗和最亮部分占比较少的值int min = getMin(map, 0.0001);int max = getMax(map, 0.0001);int[] arr = new int[] { min, max };getContrastByMaxMin(arr);    // 初始化自动色阶查找表int width = image.getWidth();int height = image.getHeight();for (int i = 0; i < width; i++) {for (int j = 0; j < height; j++) {int rgb = image.getRGB(i, j);int R = (rgb >> 16) & 0xff;int G = (rgb >> 8) & 0xff;int B = rgb & 0xff;double hisR = histogramtTable[R];double hisG = histogramtTable[G];double hisB = histogramtTable[B];double contrastR = autoContrastTable[R];double contrastG = autoContrastTable[G];double contrastB = autoContrastTable[B];R = (int) Math.round((hisR + contrastR) / 2);G = (int) Math.round((hisG + contrastG) / 2);B = (int) Math.round((hisB + contrastB) / 2);rgb = (255 & 0xff) << 24 | (R & 0xff) << 16 | (G & 0xff) << 8 | (B & 0xff);resultImage.setRGB(i, j, rgb);}}return resultImage;}

直方图均衡算法及结合自动色阶的改进相关推荐

  1. 2017年深度学习优化算法最新进展:如何改进SGD和Adam方法?

    2017年深度学习优化算法最新进展:如何改进SGD和Adam方法? 深度学习的基本目标,就是寻找一个泛化能力强的最小值,模型的快速性和可靠性也是一个加分点. 随机梯度下降(SGD)方法是1951年由R ...

  2. 亮度均匀性 matlab,求:亮度保持的夜景图像直方图均衡算法 matlab程序

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 求:亮度保持的夜景图像直方图均衡算法 matlab程序 我是大四学生,最近在做一个论文,头疼死了,不知道这个论文的程序怎么写.这里是matlab论坛 我想 ...

  3. 【排序算法】快速排序的分析改进

    基本的快速排序 最基本的快速排序是由C.A.R.Hoare在1960年提出的,快速排序的算法是一种分治排序算法 它将数组划分为两个部分,然后分别对两个部分进行排序 快速每次对数组重新排序,选择一个基准 ...

  4. 智能优化算法——正余弦优化算法(SCA)及其改进策略

    正余弦优化算法(SCA)及其改进策略 一.基本介绍 1. 背景 2. 算法简介 二.基本的SCA算法 1. 算法介绍 2. 算法步骤 三.算法分析 1. 正余弦分布 2. 算法实验结果 3. 算法优缺 ...

  5. 【智能优化算法】基于全局优化的改进鸡群算法求解单目标优化问题(ECSO)附matlab代码

    1 简介 智能算法分为两种,一种是群体智能算法(swarmintelligencealgorithm),该算法大多模拟自然界中动植物的特有行为,并将其表达成数学语言,从而进行迭代寻优,如模拟蝙蝠回声定 ...

  6. 指定起终点的最短路算法-Dijkstra标号法及其改进

    源代码来源于司守奎老师<数学建模与算法>,本人加了一些注释供大家参考: function [mydistance,mypath]=mydijkstra(a,sb,db); % 输入:a-邻 ...

  7. 数字图像处理:OpenCV直方图均衡算法研究及模拟实现

    一.引言 在<数字图像处理:直方图均衡(Histogram Equalization)的原理及处理介绍 >(链接:https://blog.csdn.net/LaoYuanPython/a ...

  8. [matlab数字图像处理4]打开一幅过度曝光图像,拉伸其图像,观察图像变换,对图像直方图均衡算法

    %任务:打开一幅过度曝光图像,拉伸其图像,观察图像变换,对图像直方图均衡算法: %本作业使用MATLAB2021A完成 clear; clc; close all f=imread("4.j ...

  9. 基本粒子群算法(PSO)的改进

    基本PSO的改进 虽然粒子群在求解优化函数时,表现了较好的寻优能力:通过迭代寻优计算,能够迅速找到近似解: 但基本的PSO容易陷入局部最优,导致结果误差较大. 两个方面: 1.将各种先进理论引入到PS ...

最新文章

  1. Android_(消息提示)多种使用Toast的消息提示
  2. 【51nod - 1098】 最小方差(基础数学,公式化简,前缀和,积的前缀和)
  3. LinuxC高级编程——线程间同步
  4. 计算机组成原理——Cache与主存的地址映射
  5. dubbo原理_dubbo的底层原理
  6. 看云电子书归档 2016.4
  7. python 图像走势预测_在keras中对单一输入图像进行预测并返回预测结果操作
  8. mysql 特殊函数_mysql 的特殊函数
  9. java树的基本知识_Java数据结构和算法(二)树的基本操作
  10. 使用ImageMagick和Tesseract进行简单数字图像识别
  11. Django:查询结果新增一列、查询结果字段名称更改、多个字段模糊查询
  12. JAVA:实现解析纯真IP数据库
  13. java企业进销存管理系统_Java实例学习——企业进销存管理系统(1)
  14. 然爸读书笔记(2014-4)----史玉柱自述:我的营销心得
  15. setheader是什么意思_HTTP 请求头 响应头信息含义
  16. Labview2018视频教程(共51节)
  17. 知识图谱·概念与技术--第1章学习笔记--知识图谱概述--知识图谱的概念,与传统语义网络的区别
  18. 最新DOS启动盘制作全攻略
  19. JVM的GC算法详解(二)
  20. Open BMC开发系列(九)ipmi 入门

热门文章

  1. 蓝桥练习-算法训练 审美课
  2. 【终极方法】This method must return a result of type boolean
  3. 解题报告——2017年C/C++ A组第五题 字母组串(递归)
  4. 算法竞赛入门经典(第二版) | 例题5-4 反片语 (map+标准化)(UVa156,Ananagrams)
  5. 在c语言中i10是什么意思啊,2011年计算机二级考试C语言十套上机题
  6. native react 折线图_react native中使用echarts
  7. linux 显示器分辨率设置太小了,显示器不显示 如何在设置回来,当“显示设置”中的分辨率不可用时,如何使用xrandr设置自定义分辨率...
  8. linux递归创建文件夹_Python中并发请求创建文件夹带来的线程安全问题
  9. android studio开关按钮,Android studio实现滑动开关
  10. 国际导航网二开php源码下载,国际网址导航系统整站源码 v3.5.2