直方图均衡算法及结合自动色阶的改进
直方图均衡,顾名思义,是处理影像灰度在统计直方图上分布问题,是一种图像增强算法。以图像某灰度值分布概率以及低于该值得所有值得分布概率之和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;}
直方图均衡算法及结合自动色阶的改进相关推荐
- 2017年深度学习优化算法最新进展:如何改进SGD和Adam方法?
2017年深度学习优化算法最新进展:如何改进SGD和Adam方法? 深度学习的基本目标,就是寻找一个泛化能力强的最小值,模型的快速性和可靠性也是一个加分点. 随机梯度下降(SGD)方法是1951年由R ...
- 亮度均匀性 matlab,求:亮度保持的夜景图像直方图均衡算法 matlab程序
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 求:亮度保持的夜景图像直方图均衡算法 matlab程序 我是大四学生,最近在做一个论文,头疼死了,不知道这个论文的程序怎么写.这里是matlab论坛 我想 ...
- 【排序算法】快速排序的分析改进
基本的快速排序 最基本的快速排序是由C.A.R.Hoare在1960年提出的,快速排序的算法是一种分治排序算法 它将数组划分为两个部分,然后分别对两个部分进行排序 快速每次对数组重新排序,选择一个基准 ...
- 智能优化算法——正余弦优化算法(SCA)及其改进策略
正余弦优化算法(SCA)及其改进策略 一.基本介绍 1. 背景 2. 算法简介 二.基本的SCA算法 1. 算法介绍 2. 算法步骤 三.算法分析 1. 正余弦分布 2. 算法实验结果 3. 算法优缺 ...
- 【智能优化算法】基于全局优化的改进鸡群算法求解单目标优化问题(ECSO)附matlab代码
1 简介 智能算法分为两种,一种是群体智能算法(swarmintelligencealgorithm),该算法大多模拟自然界中动植物的特有行为,并将其表达成数学语言,从而进行迭代寻优,如模拟蝙蝠回声定 ...
- 指定起终点的最短路算法-Dijkstra标号法及其改进
源代码来源于司守奎老师<数学建模与算法>,本人加了一些注释供大家参考: function [mydistance,mypath]=mydijkstra(a,sb,db); % 输入:a-邻 ...
- 数字图像处理:OpenCV直方图均衡算法研究及模拟实现
一.引言 在<数字图像处理:直方图均衡(Histogram Equalization)的原理及处理介绍 >(链接:https://blog.csdn.net/LaoYuanPython/a ...
- [matlab数字图像处理4]打开一幅过度曝光图像,拉伸其图像,观察图像变换,对图像直方图均衡算法
%任务:打开一幅过度曝光图像,拉伸其图像,观察图像变换,对图像直方图均衡算法: %本作业使用MATLAB2021A完成 clear; clc; close all f=imread("4.j ...
- 基本粒子群算法(PSO)的改进
基本PSO的改进 虽然粒子群在求解优化函数时,表现了较好的寻优能力:通过迭代寻优计算,能够迅速找到近似解: 但基本的PSO容易陷入局部最优,导致结果误差较大. 两个方面: 1.将各种先进理论引入到PS ...
最新文章
- Android_(消息提示)多种使用Toast的消息提示
- 【51nod - 1098】 最小方差(基础数学,公式化简,前缀和,积的前缀和)
- LinuxC高级编程——线程间同步
- 计算机组成原理——Cache与主存的地址映射
- dubbo原理_dubbo的底层原理
- 看云电子书归档 2016.4
- python 图像走势预测_在keras中对单一输入图像进行预测并返回预测结果操作
- mysql 特殊函数_mysql 的特殊函数
- java树的基本知识_Java数据结构和算法(二)树的基本操作
- 使用ImageMagick和Tesseract进行简单数字图像识别
- Django:查询结果新增一列、查询结果字段名称更改、多个字段模糊查询
- JAVA:实现解析纯真IP数据库
- java企业进销存管理系统_Java实例学习——企业进销存管理系统(1)
- 然爸读书笔记(2014-4)----史玉柱自述:我的营销心得
- setheader是什么意思_HTTP 请求头 响应头信息含义
- Labview2018视频教程(共51节)
- 知识图谱·概念与技术--第1章学习笔记--知识图谱概述--知识图谱的概念,与传统语义网络的区别
- 最新DOS启动盘制作全攻略
- JVM的GC算法详解(二)
- Open BMC开发系列(九)ipmi 入门
热门文章
- 蓝桥练习-算法训练 审美课
- 【终极方法】This method must return a result of type boolean
- 解题报告——2017年C/C++ A组第五题 字母组串(递归)
- 算法竞赛入门经典(第二版) | 例题5-4 反片语 (map+标准化)(UVa156,Ananagrams)
- 在c语言中i10是什么意思啊,2011年计算机二级考试C语言十套上机题
- native react 折线图_react native中使用echarts
- linux 显示器分辨率设置太小了,显示器不显示 如何在设置回来,当“显示设置”中的分辨率不可用时,如何使用xrandr设置自定义分辨率...
- linux递归创建文件夹_Python中并发请求创建文件夹带来的线程安全问题
- android studio开关按钮,Android studio实现滑动开关
- 国际导航网二开php源码下载,国际网址导航系统整站源码 v3.5.2