赤å¤ç·åç
ãã¡ãã£ã¨åã«ã2000円で美し過ぎる赤外線写真を撮れるデジタル一眼カメラ用フィルタを自作ãã§ãèªä½ãã赤å¤ç·ãã£ã«ã¿ã使ã£ã¦èµ¤å¤ç·åçãã¨ãã¾ããããã®ã¨ãã赤å¤ç·åçã¨ã«ã©ã¼åçãå å·¥ãã¦åæãããã©ã«ã¹ã»ã«ã©ã¼ãªãã¬ã¿ããæ¹æ³ãããã¨ããã®ã§è©¦ãã¦ã¿ããã¨ã«ãã¾ããããããã§ã¿ãç¾ãã赤å¤ç·åçã®ä¸ã«ããã®æè¡ã使ã£ãåçãããããã§ãã
ãã©ã«ã¹ã»ã«ã©ã¼ã£ã¦ãªããããã»ãï¼
ãè¡æåçã§ä½¿ããããããæè¡ã¿ããã§ãããå®ã¯ã¤ãã¤ã詳ããäºã¯ãããã¾ããã§ãããåçã¯ã風景の簡易赤外線写真ãã¨ãããµã¤ãã®ã赤外カラー合成画像ãã¨ããã¨ãããããããããã§ãã
ãå³ã«ããã¨ä¸å³ã®ãããªæãã§ãã
ãæ®éã«æ®ã£ãã«ã©ã¼åçã¨ãã¢ãã¯ãã§æ®å½±ãã赤å¤ç·åçãç¨æããã°ãããããã«ç°¡åãªç»åå¦çãã¦ç»ååæããã°ã§ãã¦ãã¾ãããã§ããã
ãã©ã«ã¹ã»ã«ã©ã¼ãã¤ãã£ã¦ã¿ããï¼
ããããæ©éã¤ãããã¨ãã¦ããµã¨æ°ã¥ãã¾ãããRGBã®è²äº¤æãRGBã®ã¬ãã«èª¿æ´ãç»ååæãåºæ¥ãç»åå¦çã½ããæå¤ã«æã£ã¦ãªããWindowsã ã¨JTrimã§å ¨é¨ã§ãã¦ãã¾ãã¿ãããªã®ã§ãããMacã ã¨JTrimã«ç¸å½ããã½ãããè¦å½ãããªãã®ã§ããæ¢ããããGIMPã¨ãpixelmatorã¨ãã£ãã½ãã使ãã°ã§ããããªã®ã§ãããããªéãã½ããããã¤ã使ã£ã¦å å·¥ããã®ã¯ããããããã¨ã«å¯¾ãã¦å¤§ããéãã§ããã¾ã¹ãã¼ããããªããªã¼ã¨æã£ã¦æ©ãã§ã¾ãããæ©ãã æ«ããそういや最近Processingで顔認識を使って写真をアヘ顔にするソフトをつくったなãã¨æãåºããããªããã°ã¤ããã°ãããããï¼ãã¨ããDo it myselfç²¾ç¥ã§ã½ããèªä½ãã¦ã¿ããã¨ã«ãã¾ããã
ã½ããéçº
ãä»åããã¢ãé¡èªåçæã½ãããã¤ãã£ãã¨ãã¨åæ§Processingã使ã£ã¦ã½ããã¤ãããã¨ã«ãã¾ãããå®éã«ããã°ã©ã ããã¨ãäºæ³ãããªãã£ãè¦é£ãé£ç¶ãã¦è¥²ãæ¥ãã»ã»ã»ã¨ãããã¨ããªãè²ã
Webã§èª¿ã¹ãªããçµãã ããµã¯ã£ã¨1æéç¨ã§å®æãã¦ãã¾ãã¾ãããProcessingæ§ã
ã§ããã
ããã ãåºæ¥ä¸ãã£ãæåã®ç»åãç©è¶³ããªãã£ãã®ã§ãã¦ã¹ã®åãã¨ãç°¡åãªæä½ã§ç»è³ªã調æ´ã§ããããã«ãã¾ããã
ä½ä¾
ãã½ãã使ç¨ããä½ä¾ã§ãã被åä½ãé©å½ã§ã¤ãã¤ãã§ãããã¡ãã£ã¨ããã£ã½ããªã£ã¦ããã®ã§ã¯ãªãã§ããããï¼
å
ç»åï¼èµ¤å¤ç·ã¢ãã¯ãï¼
ã½ã¼ã¹ã³ã¼ã
ããã¿ã¾ãããç¹ã«è§£èª¬ã¯ç¡ãã½ã¼ã¹ãã¿æ¸ããã¦çµããã¾ããããã¾ããã°ã©ã åãããªã人ã§ãç解ããããããã«ãããã¨ã¯ã©ã¹ã¨ãã¤ãã£ã¦ã¾ããï¼ã¹ãå¥ã«ã¯ã©ã¹ããããªãã¨ããããªããããªããã ãããã£ï¼ï¼ãè¦è¾ãã§ãããé ã«èªãã°ãããã¨æãã®ã§èå³ãã人ã¯è¦ã¦ä¸ããããã©ã«ã¹ã»ã«ã©ã¼ãã¨ã«ããã¤ãããã°ããã¨ãã人ã¯ãProcessingã¤ã³ã¹ãã¼ã«ãã¦ãã½ã¼ã¹ã³ã¼ãã³ãããã¦å®è¡ããã°ã§ããã¯ãã§ããç¹ã«ã½ã¼ã¹ãå¼ãå¿ è¦ã¯ããã¾ãããMacã§ãã試ãã¦ã¾ããããå¤åWindowsã§ãåããã¨ã
PImage img; PImage img_tmp; PImage img_IR; PImage img_IR_tmp; int mode; void setup() { size(100, 100); println("select normal(color) photo."); String imgPath = selectInput(); img = loadImage(imgPath); println("select IR monoochrome photo."); imgPath = selectInput(); img_IR = loadImage(imgPath); size(img.width, img.height); mode = 0; noStroke(); background(0); img_tmp = createImage(img.width, img.height, RGB); img_IR_tmp = createImage(img_IR.width, img_IR.height, RGB); } void draw() { float color_phase = mouseX / (float)img.width * 360; float color_gain = mouseY / (float)img.height * 5; img.loadPixels(); colorMode(HSB, 360, 100, 100); for (int y = 0; y < img.height; y++) { for (int x = 0; x < img.width; x++) { int index = y * img.width + x; int pixel = img.pixels[index]; img_tmp.pixels[index] = color(hue(pixel)+color_phase, saturation(pixel), brightness(pixel)); } } img_tmp.updatePixels(); img_tmp.loadPixels(); colorMode(RGB, 256); for (int y = 0; y < img.height; y++) { for (int x = 0; x < img.width; x++) { int index = y * img.width + x; int pixel = img_tmp.pixels[index]; switch(mode){ case 0: img_tmp.pixels[index] = color(0, green(pixel), blue(pixel)); break; case 1: img_tmp.pixels[index] = color(red(pixel), 0, blue(pixel)); break; default: img_tmp.pixels[index] = color(red(pixel), green(pixel), 0); break; } } } img_tmp.updatePixels(); img_IR.loadPixels(); colorMode(RGB, 256); for (int y = 0; y < img_IR.height; y++) { for (int x = 0; x < img_IR.width; x++) { int index = y * img_IR.width + x; int pixel = img_IR.pixels[index]; switch(mode){ case 0: img_IR_tmp.pixels[index] = color(red(pixel), 0, 0); break; case 1: img_IR_tmp.pixels[index] = color(0, green(pixel), 0); break; default: img_IR_tmp.pixels[index] = color(0, 0, blue(pixel)); break; } } } img_IR_tmp.updatePixels(); img_tmp.loadPixels(); img_IR_tmp.loadPixels(); colorMode(RGB, 256); for (int y = 0; y < img_IR.height; y++) { for (int x = 0; x < img_IR.width; x++) { int index = y * img_IR.width + x; int img_pix = img_tmp.pixels[index]; int img_IR_pix = img_IR_tmp.pixels[index]; float r, g, b; switch(mode){ case 0: r = min(red(img_pix) + color_gain*red(img_IR_pix), 255); g = min(green(img_pix) + green(img_IR_pix), 255); b = min(blue(img_pix) + blue(img_IR_pix), 255); break; case 1: r = min(red(img_pix) + red(img_IR_pix), 255); g = min(green(img_pix) + color_gain*green(img_IR_pix), 255); b = min(blue(img_pix) + blue(img_IR_pix), 255); break; default: r = min(red(img_pix) + red(img_IR_pix), 255); g = min(green(img_pix) + green(img_IR_pix), 255); b = min(blue(img_pix) + color_gain*blue(img_IR_pix), 255); break; } img_IR_tmp.pixels[index] = color(r, g, b); } } img_IR_tmp.updatePixels(); image(img_IR_tmp, 0, 0); } void keyPressed() { // save image if(key == 'p' || key == 'P') { save("screenshot.jpg"); println("screen saved."); } // exit if(key == ' ') { exit(); } // red mode if(key == 'r' || key == 'R') { mode = 0; } // green mode if(key == 'g' || key == 'G') { mode = 1; } // blue mode if(key == 'b' || key == 'B') { mode = 2; } }
ããã°ã©ã 使ãæ¹
ãå®è¡ããã¨ããã¡ã¤ã«é¸æã®ãã¤ã¢ãã°ãåºã¦ããã®ã§ãæåã«ã«ã©ã¼ç»åãé¸æãã¦ä¸ãããé¸æããå¾ãã¾ããã¤ã¢ãã°ãåºã¦ããã®ã§ã次ã«èµ¤å¤ç·ã¢ãã¯ãç»åãé¸æãã¦ä¸ãããããã¨åæããããã©ã«ã¹ã»ã«ã©ã¼ç»åãåºã¦ããã¯ãã§ãã
ããã¦ã¹ãå·¦å³ã«åããäºã§è²ç¸ï¼è²åãã¿ãããªãã®ï¼ã®èª¿ç¯ããã¦ã¹ãä¸ä¸ã«åãããã¨ã§åæãã赤å¤ç·åçã®ã²ã¤ã³ã調æ´ãããã¨ãã§ããã®ã§ãããæãã®ç»åã«ãªãã¾ã§èª¿æ´ãã¦ã¿ã¦ä¸ããã
ãã¾ãããã¼ãã¼ãã®Rãæ¼ãã¨èµ¤ã強調ãGãæ¼ãã¨ç·ã強調ãBãæ¼ãã¨éã強調ããã¢ã¼ãã«åãæ¿ããã¾ããç»åãä¿åãããã¨ãã¯Pãæ¼ãã¨ããã°ã©ã ã¨åããã©ã«ãã«ãscreenshot.jpgãã¨ãããã¡ã¤ã«ãä¿åããã¾ããã¹ãã¼ã¹ãã¿ã³ã§çµäºãã¾ãã
ãããã¡ã¢ãªã¨ã©ã¼ãåºãããç°å¢è¨å®ã§æ大ã¡ã¢ãªãå¢ããã¦ããããç»åãã¡ã¤ã«ãå°ãããã¦ãã£ã¦ä¸ããã
ã¾ã¨ã
ãProcessing使ã£ã¦ã«ã©ã¼èµ¤å¤ç·åçãçæããã½ãããä½ã£ããâæè§ä½ã£ãã®ã§ãè²ã ãªè¢«åä½ã§è©¦ãã¦ã¿ããããªã¨æãã¾ããããã¦æãã¤ãããã¨ãããå®ç¾åºæ¥ãProcessingåéãããï¼ç»åå¦çã¯ä¸æ¦ããã§ä¸åºåãã«ãã¦ã次ã¯ç©çã·ãã¥ã¬ã¼ã¿ã§ãä½ã£ã¦ã¿ããããªã¨æãã¾ããã§ã¯ã¾ãã¼