自作ソフトでHDR写真。RAWデータから露出を変えて生成した3枚の写真から合成しています。もっとRAWデータで撮っておけばよかったかなとちょっとだけ思いました。
Olympus OM-D E-M5 + MZD 45mm, f1.8 自作のHDR画像生成ソフトで処理
関連記事
『【無料】ProcessingでHDR画像作成ソフトを自作【夏休みの宿題に最適】 - karaage. [からあげ]』
『Processingを使ってHDRフォト作成ソフト自作にチャレンジ 〜トーンマッピングの奥深い世界〜 - karaage. [からあげ]』
ソフト改良
自作ソフト、無駄な計算が多かったので見直して高速化しました。多分3倍くらいは早くなります。興味ある人は続きを読むをクリックして下さい
PImage img0; PImage img1; PImage img2; float lum; float lum_sum; int sum_numb; final int scope = 200; // 1 to picture width final int scope_speed = 20; // 1 to scope final int average_speed = 2; // 0 to picture width final float a = 0.27; final float gamma_u = 0.5; final float gamma_n = 1; final float gamma_o = 0.5; final float color_gain = 2.2; final float delta = 0.01; float[] lut_u = new float[256]; float[] lut_n = new float[256]; float[] lut_o = new float[256]; void setup() { size(10, 10); println("select under exposed photo."); String imgPath = selectInput(); img0 = loadImage(imgPath); println("select normal exposed photo."); imgPath = selectInput(); img1 = loadImage(imgPath); println("select over exposed photo."); imgPath = selectInput(); img2 = loadImage(imgPath); size(img0.width, img0.height); for (int i = 0; i < 256; i++){ lut_u[i] = 255*pow(((float)i/255),(1/gamma_u)); } for (int i = 0; i < 256; i++){ lut_n[i] = 255*pow(((float)i/255),(1/gamma_n)); } for (int i = 0; i < 256; i++){ lut_o[i] = 255*pow(((float)i/255),(1/gamma_o)); } } void draw(){ image(img0, 0, 0); // Making HDRImage----- float[] hdr_img_r = new float[img0.height*img0.width]; float[] hdr_img_g = new float[img0.height*img0.width]; float[] hdr_img_b = new float[img0.height*img0.width]; img0.loadPixels(); img1.loadPixels(); img2.loadPixels(); for(int i = 0; i < img0.width*img0.height; i++){ color tmp_color0 = img0.pixels[i]; color tmp_color1 = img1.pixels[i]; color tmp_color2 = img2.pixels[i]; hdr_img_r[i] = lut_u[(int)red(tmp_color0)] + lut_n[(int)red(tmp_color1)] + lut_o[(int)red(tmp_color2)]; hdr_img_g[i] = lut_u[(int)green(tmp_color0)] + lut_n[(int)green(tmp_color1)] + lut_o[(int)green(tmp_color2)]; hdr_img_b[i] = lut_u[(int)blue(tmp_color0)] + lut_n[(int)blue(tmp_color1)] + lut_o[(int)blue(tmp_color2)]; hdr_img_r[i] = hdr_img_r[i]/3*color_gain; hdr_img_g[i] = hdr_img_g[i]/3*color_gain; hdr_img_b[i] = hdr_img_b[i]/3*color_gain; } for(int y = 0; y < img0.height; y++){ for(int x = 0; x < img0.width; x++){ int pos = x + y*img0.width; color tmp_color = color(hdr_img_r[pos], hdr_img_g[pos], hdr_img_b[pos]); set(x, y, tmp_color); } } //----Making HDRImage //ToneMapping---- color[] tmp_img = new color[img0.height*img0.width]; int tmp = average_speed; float lum_sum_w = 0; float[] lum = new float[img0.height*img0.width]; float[] lum_local = new float[img0.height*img0.width]; float[] u = new float[img0.height*img0.width]; float[] v = new float[img0.height*img0.width]; for(int y = 0; y < img0.height; y++){ for(int x = 0; x < img0.width; x++){ int pos = x + y*img0.width; lum[pos] = 0.3*hdr_img_r[pos] + 0.59*hdr_img_g[pos] + 0.11*hdr_img_b[pos]; lum_local[pos] = log((0.3*hdr_img_r[pos] + 0.59*hdr_img_g[pos] + 0.11*hdr_img_b[pos])/256+delta); u[pos] = -0.17*hdr_img_r[pos] - 0.33*hdr_img_g[pos] + 0.5*hdr_img_b[pos]; v[pos] = 0.5*hdr_img_r[pos] -0.42*hdr_img_g[pos] - 0.08*hdr_img_b[pos]; } } for(int y = 0; y < img0.height; y++){ tmp = average_speed; for(int x = 0; x < img0.width; x++){ int pos = x + y*img0.width; lum_sum = 0; sum_numb = 0; tmp++; if(tmp > average_speed){ tmp = 0; for(int y_2 = y-scope; y_2 < y+scope; y_2 += scope_speed){ for(int x_2 = x-scope; x_2 < x+scope; x_2 += scope_speed){ if(y_2 >= 0 && y_2 < img0.height && x_2 >=0 && x_2 < img0.width){ if(sqrt((x_2-x)*(x_2-x)+(y_2-y)*(y_2-y)) <= scope){ sum_numb++; int pos_2 = x_2 + y_2*img0.width; lum_sum += lum_local[pos_2]; } } } } lum_sum_w = exp(lum_sum/(float)sum_numb); } float lum_w = lum[pos]/lum_sum_w*a; float r = lum_w + 1.4*v[pos]; float g = lum_w -0.34*u[pos] -0.71*v[pos]; float b = lum_w + 1.77*u[pos]; tmp_img[pos] = color(r,g,b); } } for(int y = 0; y < img0.height; y++){ for(int x = 0; x < img0.width; x++){ int pos = x + y*img0.width; set(x, y, tmp_img[pos]); } } } void keyPressed() { // save image if(key == 'p' || key == 'P') { save("screenshot.jpg"); println("screen saved."); } // exit if(key == ' ') { exit(); } }