在图像处理软件Photoshop中有一个自动对比度功能,可以一键调节图像亮度、对比度。比如,像下面这张由于曝光不足形成的非常暗的图像,只有图像中间比较亮一些的路面才能看到,其他地面上的物体几乎无法看见。

那么再来看一下使用Photoshop自动对比度之后效果。

一键操作后,图像上的大部分物体都体现出来了,调整后的亮度、对比度、饱和度等几乎不会给人失真的感觉,效果比手动调节亮度、对比度、或者曲线调整要好很多。实际上,这个功能的牛逼之处不止如此,再看另一张图。

这是一张受到雾霾干扰的图像,整体感觉就是非常朦胧,看不清地面物体。用自动对比度看看效果:

去雾效果杠杠的,完全就像是没有雾霾的天气拍出来的。 那么如此牛逼的功能是怎么实现的呢?其实原理还是比较简单,一般图像由RGB三个通道合成,每个通道由0~255数值来体现,如果是比较暗的图像,其RGB通道数值可能在比较低的范围内,比如第一张非常暗的图像,其RGB三个通道数值范围为(0~60),即最亮的地方才60的亮度值,离最大亮度255还差的远。

有了图像的各个通道数据,就可以在此基础上做些文章了,比如,可以直接将(0~60)映射到(0~255)。使用java编写代码测试一下,用ImageIO读取和写入图像,用bufferedImage对象获取图像RGB信息,然后对各个通道值进行处理。

代码如下:

// 自动对比度
public void autoContrast(BufferedImage image) {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);double r = (rgb >> 16) & 0xff;double g = (rgb >> 8) & 0xff;double b = rgb & 0xff;//进行转换r = getContrastByMaxMin(r);g = getContrastByMaxMin(g);b = getContrastByMaxMin(b);rgb = (255 & 0xff) << 24 | (clamp((int)r) & 0xff) << 16 | (clamp((int)g) & 0xff) << 8 | (clamp((int)b) & 0xff);image.setRGB(i, j, rgb);}}
}
//根据亮度最大最小值拉伸对比度
private double getContrastByMaxMin(double a) {if (a >= arr[0] && a <= arr[1]) {result = (a - arr[0]) * 255 / (arr[1] - arr[0]);}return result;
}

运行效果如下:

图像确实变亮了!但是仔细看看,效果似乎比Photoshop差一些,这是怎么回事?

其实,虽然获取到了各个通道的动态范围(0~60),但这只是最大最小值,而大部分数值范围可能在(10~50)之间,那么在进行拉伸的时候,很多值并没有拉伸到合适的数值上。那么Photoshop是怎么处理的呢?很简单!就是对上下范围进行裁切,Photoshop自动对比度是裁切掉上下范围各0.001%的像素,再得到需要进行映射的范围,对范围以外的数值直接映射到0或255。当然,要获得准确的裁切值,需要对各个通道值进行统计,即统计图像各个通道在(0~255)上分布概率。

代码如下:

// 自动对比度
public void autoContrast(BufferedImage image) {int width = image.getWidth();int height = image.getHeight();//计算图像强度分布频率Map<Integer,Double> map = getPDF(image);//获取最大最小强度int min = getMin(map);int max = getMax(map);int[] arr = new int[] {min,max};//进行对比度拉伸for(int i = 0; i < width; i++) {for(int j = 0; j < height; j++) {int rgb = image.getRGB(i, j);double r = (rgb >> 16) & 0xff;double g = (rgb >> 8) & 0xff;double b = rgb & 0xff;//进行转换r = getContrastByMaxMin(r, arr);g = getContrastByMaxMin(g, arr);b = getContrastByMaxMin(b, arr);rgb = (255 & 0xff) << 24 | (clamp((int)r) & 0xff) << 16 | (clamp((int)g) & 0xff) << 8 | (clamp((int)b) & 0xff);image.setRGB(i, j, rgb);}}
}//取出最小强度
private int getMin(Map<Integer, Double> map){double temp = 0.0;int result = 0;for(int i = 0; i < 256; i++) {double num = map.get(i);temp += num;if (temp >= 0.001) {result = i;break;}}return result;
}//取出最大强度
private int getMax(Map<Integer, Double> map){double temp = 0.0;int result = 0;for(int i = 255; i >= 0; i--) {double num = map.get(i);temp += num;if (temp >= 0.001) {result = i;break;}}return result;
}//根据亮度最大最小值拉伸对比度
private double getContrastByMaxMin(double a, int[] arr) {double result = 0.0;if (arr[0] == arr[1]) {result = arr[0];}if (a > arr[1]) {result = 255;}if (a < arr[0]) {result = 0;}if (a >= arr[0] && a <= arr[1]) {result = (a - arr[0]) * 255 / (arr[1] - arr[0]);}return result;
}/**
* 统计图像从0~255之间分布
*
* @return
*/
private Map<Integer, Double> getPDF(BufferedImage image) {Map<Integer, Double> map = new HashMap<>();int width = image.getWidth();int height = image.getHeight();double totalPixel = width * height;for (int i = 0; i < 256; i++) {map.put(i, 0.0);// 通过循环,往集合里面填充0~255个位置,初始值都为0
}//分别统计图像上0~255上分布总数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;map.put(r, map.get(r) + 1);map.put(g, map.get(g) + 1);map.put(b, map.get(b) + 1);}}//计算分布概率for(int i = 0; i < 256; i++) {double value = map.get(i);value = value / (3 * totalPixel);map.put(i, value);}return map;
}
// 判断a,r,g,b值,大于256返回256,小于0则返回0,0到256之间则直接返回原始值
private int clamp(int rgb) {if (rgb > 255)return 255;if (rgb < 0)return 0;return rgb;
}

再看效果:

是不是跟Photoshop一毛一样!

java图像处理之自动对比度相关推荐

  1. Java图像处理方面的工具库和开发包

    Java图像处理类库Java Image Filters Java Image Filters 是由 Jhlabs 开发的一组用来处理 Java 图像的类库,提供各种常用的图像处理效果,例如反转色.扭 ...

  2. java图像处理-(指定区域内)灰度化、透明化(alpha通道)处理

    java图像处理-(指定区域内)灰度化.透明化(alpha通道)处理 2016年07月25日 21:23:16 阅读数:3944 近日在一家小公司实习,老板要求我写一个图形编辑器,其中涉及到用java ...

  3. java毕业设计——基于java+图像处理技术的医学图像处理系统设计与实现(毕业论文+程序源码)——医学图像处理系统

    基于java+图像处理技术的医学图像处理系统设计与实现(毕业论文+程序源码) 大家好,今天给大家介绍基于java+图像处理技术的医学图像处理系统设计与实现,文章末尾附有本毕业设计的论文和源码下载地址哦 ...

  4. Java图像处理--------RGB调色面板

    Java图像处理--------RGB调色面板 一:概述 因为我们知道颜色是由R.G.B.三种颜色所组成的,那么我们只需要更改这三个的数值.我们就可以实现一个简单的调色面板:以下是代码演示: 二:代码 ...

  5. Java 图像处理教程(人脸检测,添加水印,图像颜色转换)

    Java 图像处理教程(人脸检测,添加水印,图像颜色转换) 文章目录 Java 图像处理教程(人脸检测,添加水印,图像颜色转换) 1:图片的读和写 2:彩色图像转换成灰度图像 3:彩色图像转换成负图像 ...

  6. java imageio处理图像_Linux geoserver调优之Java图像处理优化(原生JAI和ImageIO和java默认库相互转换)...

    注:geoserver 版本 Linux geoserver2.15.0    安装 :bin方式安装(内嵌jetty,非war安装) 一.geoserver调优之Java图像处理优化 1.原生JAI ...

  7. OpenCV3.2 Java图像处理视频学习教程-贾志刚-专题视频课程

    OpenCV3.2 Java图像处理视频学习教程-2434人已学习 课程介绍         OpenCV3.2 Java图像处理视频培训课程:基于OpenCV新版本3.2.0详细讲述Java Ope ...

  8. JAVA图像处理——高斯模糊

    JAVA图像处理--高斯模糊 高斯模糊: 高斯模糊简单的说就是让图像的像素点取周围的像素点的平均,达到令图片模糊的效果. 当然,简单的取平均值是不太好的,因为一般与像素点距离近的像素点他们的颜色更接近 ...

  9. 自动色阶算法C语言,Photoshop图像处理算法—自动对比度跟自动色调(自动色阶)...

    Photoshop图像处理算法-自动对比度和自动色调(自动色阶) 1.原理部分 2.程序部分(matlab) 自动色调 clc;clear;close all; img=imread('IMG_095 ...

最新文章

  1. 清华大学施路平:双脑驱动的人工通用智能
  2. Spark Streaming 执行流程
  3. 获取数据 - 下载附件解压附件 - Python代码
  4. 玩转算法第七章-二叉树与递归
  5. 速来领取!降本增效的车间管理大屏,车间主任看了都拍手称好
  6. MATLAB中如何让分度值小点,实验6 干涉的matlab模拟.doc
  7. DllRegisterServer的调用失败的问题解决方法
  8. svm图片多分类python代码_[OpenCV随笔]-OpenCV3.x中SVM多分类使用(代码篇)
  9. 软考 系统架构设计师考试大纲
  10. 以太坊-区块链开发入门
  11. html表格 超链接无效,excel表格超链接失效怎么处理
  12. 中国银行软件中心信息技术岗(北京 )面试
  13. 网页制作中的超链接怎么做
  14. MVC.Net: 解决Attempted to access an unloaded appdomain的问题
  15. Go测试开发(二) 多线程简单斗地主
  16. 基于JSP同城校友网的设计与实现
  17. java毕业设计在线水果超市Mybatis+系统+数据库+调试部署
  18. 单片机--矩阵键盘实验
  19. DeepDive安装学习
  20. 模板学堂丨Zabbix监控告警大屏

热门文章

  1. JavaScript的运动 —— 缓冲运动及其应用篇
  2. 通俗易懂,java8 .stream().map().collect()用法
  3. 【传智播客】Javaweb程序设计任务教程 黑马程序员 课后答案【合集】
  4. 一段CyclicBarrier代码
  5. java运行时异常的特点是什么_Java运行时异常和非运行时异常
  6. c语言编译不了什么情况,c语言编译没错但是无法运行
  7. 抽象工厂模式_设计模式系列—抽象工厂模式
  8. Java中的DatagramPacket与DatagramSocket的初步
  9. Android 判断应用 第一次启动
  10. jsonp跨域读取cookie