高动态范围图像HDR
生活随笔
收集整理的這篇文章主要介紹了
高动态范围图像HDR
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
? ? ? ??HDR(High Dynamic Range,高動態范圍),由于目前無論是相機還是顯示器,對圖像亮度范圍都限定在0~255之間,即256個亮度級別,但在自然界中,刺眼的陽光和微弱的星光,可能有成千上萬倍的亮度差異。如果要在同一張照片上同時呈現兩個亮度差異較大的物體,那么實際情況是,要么其中一個亮度過低,或者另一個過曝。根據不同應用場景,HDR有不同處理方式。
? ? ? ??其中一種方法為,采用不同曝光參數(ISO、快門速度)拍攝同一場景照片,對每張照片相同位置像素值求和,計算平均值,再將均值賦值給對應像素;另一種類似的處理方法為,相機采用較為平衡的曝光參數拍攝一張照片,根據這張照片分別按照亮度增強一定比例和亮度降低一定比例生成兩張影像,將三張影像按照前面一種方法進行處理。
? ? ? ??當然在實際處理同一位置拍攝多張影像進行HDR時,需要考慮抖動等外界因素造成的圖像錯位,需要引入特征提取與匹配及裁剪影像。
? ? ? ??簡單的demo實現代碼:
public class Hdr {/*** HDR實現 不同曝光參數的幾張照片實現影像畫質增強* * @param images* @return*/public BufferedImage hdrByImages(BufferedImage[] images) {int width = images[0].getWidth();int height = images[0].getHeight();BufferedImage resultImage = new BufferedImage(width, height, images[0].getType());int length = width * height;int pics = images.length;int[] tempR = new int[length];int[] tempG = new int[length];int[] tempB = new int[length];// 取出每張照片對應位置像素值for (int i = 0; i < width; i++) {for (int j = 0; j < height; j++) {int index = i * height + j;for (int k = 0; k < pics; k++) {int rgb = images[k].getRGB(i, j);tempR[index] += (rgb >> 16) & 0xff;tempG[index] += (rgb >> 8) & 0xff;tempB[index] += rgb & 0xff;}}}// 求取均值,將均值作為最終結果輸出for (int i = 0; i < width; i++) {for (int j = 0; j < height; j++) {int index = i * height + j;int r = tempR[index] / pics;int g = tempG[index] / pics;int b = tempB[index] / pics;int rgb = (255 & 0xff) << 24 | (r & 0xff) << 16 | (g & 0xff) << 8 | (b & 0xff);resultImage.setRGB(i, j, rgb);}}return resultImage;}/*** 用一張照片進行HDR計算* * @param image* @param lightParam* 提高亮度參數* @param darkParam* 降低亮度參數* @return*/public BufferedImage hdrByimage(BufferedImage image, double lightParam, double darkParam) {BufferedImage[] images = new BufferedImage[3];images[0] = image;images[1] = brightnessAdjustment(image, lightParam);images[2] = brightnessAdjustment(image, darkParam);BufferedImage result = hdrByImages(images);return result;}// 亮度調整public BufferedImage brightnessAdjustment(BufferedImage image, double param) {BufferedImage resultImage = new BufferedImage(image.getWidth(), image.getHeight(), image.getType());double R, G, B;for (int i = 0; i < image.getWidth(); i++) {for (int j = 0; j < image.getHeight(); j++) {int rgb = image.getRGB(i, j);R = (((rgb >> 16) & 0xff) * param);G = (((rgb >> 8) & 0xff) * param);B = ((rgb & 0xff) * param);rgb = ((255 & 0xff) << 24) | ((clamp((int) R) & 0xff) << 16) | ((clamp((int) G) & 0xff) << 8)| ((clamp((int) B) & 0xff));resultImage.setRGB(i, j, rgb);}}return resultImage;}private int clamp(int i) {if (i > 255) {return 255;}if (i < 0) {return 0;} else {return i;}}// 讀取文件夾下多張影像public BufferedImage[] readImages(File input) throws Exception {String[] files = input.list();BufferedImage[] images = new BufferedImage[files.length];for (int i = 0; i < files.length; i++) {String in = files[i];File file = new File(input.toString() + "/" + in);images[i] = ImageIO.read(file);}return images;}//測試public static void main(String[] args) throws Exception {File input = new File("C:/Users/admin/Desktop/test/HDR");BufferedImage[] images = new Hdr().readImages(input);BufferedImage result = new Hdr().hdrByImages(images);File output = new File("C:/Users/admin/Desktop/test/HDR/result.jpg");ImageIO.write(result, "jpg", output);} }三張不同曝光參數的測試圖像:
運行結果:
?
總結
以上是生活随笔為你收集整理的高动态范围图像HDR的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 图像马赛克原理及实现
- 下一篇: java图像处理,彩色图像转灰度图的几种