日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java图像处理之自动对比度

發布時間:2024/1/23 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java图像处理之自动对比度 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

? ? ? ??在圖像處理軟件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图像处理之自动对比度的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。