/* Title: INTEGRATING MACROS Version: 1.0 Date: June 30, 2014 Author: Todd R. Hanneken, thanneken@stmarytx.edu, thanneke@uchicago.edu Description: The major ImageJ macros used in the Integrating Spectral and Reflectance Transformation Imaging (RTI) Project (2013-2014), a Phase of the Jubilees Palimpsest Project, supported by the National Endowment for the Humanities, Office of Digital Humanities. http://palimpsest.stmarytx.edu/ About: This file includes 4 macros and 5 supporting functions. Method 18 is the major macro essential for the products of the project. It can be invoked by loading this file and pressing "8". Method 16 is the first draft and is replaced by Method 18 in all ways except the excision of the reflective hemispheres. Method 17 is an additional experiment in an interactive script designed to focus PCA pseudocolor processing on a small, user selected region of interest. It is not part of the proposed activities of the project. Method 19 builds on method 17 to generate a series of small images, each offset by one pixel from the previous. The images can be combined into a video that pans across the frame. It is not part of the proposed activities of the project. All the macros are tailored to the objects and filepaths of the Integrating Spectral and RTI Project. It may be freely used on other projects, but the macros must be edited significantly to work on additional objects. Doing so requires basic familiarity with the ImageJ Macro language, which resembles JavaScript and is well documented. One may also check back to the project website or contact the author directly to inquire if a more open-ended version has been developed. */ function cropObject() { if (processType == "Ball") { if (object == "Mask") makeRectangle(791, 480, 759, 732); else if (object=="Sold") makeRectangle(264, 3900, 1044, 948); else if (object == "Pal1") makeRectangle(5626, 4510, 719, 716); else if (object == "Ant2") makeRectangle(191, 5114, 941, 945); else if (object == "Pal3") makeRectangle(1796, 4555, 772, 741); else if (object == "Ant3") makeRectangle(121, 129, 972, 943); else if (object == "Pal2") makeRectangle(5284, 5085, 802, 816); else exit("Area not defined for object"); } else { if (object == "Mask") makeRectangle(250, 1635, 7656, 2028); else if (object == "Sold") makeRectangle(1236, 168, 2880, 4728); //else if (object == "Pal1") makeRectangle(1304, 252, 5424, 3952); //full page, including some black background else if (object == "Pal1") makeRectangle(2940, 848, 3040, 2376); //detail on text else if (object == "Ant2") makeRectangle(1116, 1176, 5564, 3952); else if (object == "Pal3") makeRectangle(1596, 350, 5444, 3952); else if (object == "Ant3") makeRectangle(0, 1275, 8176, 4857); else if (object == "Pal2") makeRectangle(1256, 576, 5536, 4128); else exit("Area not defined for object"); } run("Crop"); } function rotateObject() { if (object == "Mask") run("Rotate 90 Degrees Right"); else if (object == "Sold") run("Rotate... ", "angle=180 grid=1 interpolation=Bilinear"); else if (object == "Pal1") run("Rotate 90 Degrees Left"); else if (object == "Ant2") run("Rotate 90 Degrees Left"); else if (object == "Pal3") run("Rotate 90 Degrees Left"); else if (object == "Pal2") run("Rotate... ", "angle=-92 grid=1 interpolation=Bilinear"); } function enhanceObject() { if (object == "Pal3") makeRectangle(4428,1989,1000,1000); //924,1686 else if (object == "Pal1") makeRectangle(3000, 888, 2992, 2272); //else if (object == "Mask") makeRectangle(250, 1635, 7656, 2028); //complete object including exposed wood and black background else if (object == "Mask") makeRectangle(1206,1900,3096,1500); //more focused region of interest //else if (object == "Sold") makeRectangle(1266, 168, 2850, 4728); //whole object with background else if (object == "Sold") makeRectangle(1662,468,1884,2430); //only terracotta else if (object == "Ant2") makeRectangle(1260, 1422, 5304, 3576); else if (object == "Ant3") makeRectangle(0, 1520, 8176, 4612); else exit("Rectangle for enhanceObject not yet defined"); run("Enhance Contrast...", "saturated=0.4"); run("8-bit"); run("Select None"); if (object == "Pal3") run("Invert"); } function enhanceMacbeth() { if (object == "Mask") makeRectangle(2058, 1230, 1770, 302); else if (object == "Sold") makeRectangle(4506, 2245, 312, 1798); else if (object == "Pal1") makeRectangle(3691, 4382, 1705, 310); else if (object == "Pal3") makeRectangle(4117, 4549, 1608, 172); else if (object == "Ant2") makeRectangle(6826, 3050, 304, 1790); else if (object == "Ant3") makeRectangle(2096, 48, 6016, 552); else exit("Macbeth chart area not defined for object"); run("Enhance Contrast...", "saturated=0.4"); run("Select None"); } function selectPCAFocus() { if (object == "Pal1") makeRectangle(3378, 1296, 828, 810); else if (object == "Mask") makeRectangle(1206,1900,3096,1500); else if (object == "Sold") makeRectangle(1662,468,1884,2430); else if (object == "Ant2") makeRectangle(1260, 1422, 5304, 3576); //same as enhance object, but could set more narrowly if one wanted to study just the text, for example else if (object == "Ant3") makeRectangle(144, 1616, 7960, 4392); //else if (object == "Pal3") makeRectangle(3726, 1970, 1977, 1084); //difficult text only //else if (object == "Pal3") makeRectangle(4428,1989,1000,1000); //same as enhance else if (object == "Pal3") makeRectangle(1596, 350, 5444, 3952); //same as crop else exit("Rectangle for selectPCAFocus not yet defined"); } macro "Method 16 [6]" { //Method 16 designed to encompass all objects and processes setBatchMode(true); Dialog.create("Confirm information"); Dialog.addMessage("Confirm the following"); Dialog.addString("General Project Path: ", File.separator+"home"+File.separator+"faculty"+File.separator+"thanneken"+File.separator+"Integrating"+File.separator, 20); var objects = newArray("Mask", "Sold", "Pal1", "Ant2", "Pal3", "Ant3", "Pal2"); Dialog.addRadioButtonGroup("Object: ", objects, 4, 2, "Sold"); var processTypes = newArray("Ball", "Acca", "Accb", "Pcaa", "Pcab", "Pcac","Pcad","Pcae", "Pcaf", "Pcag","Suva","Igua"); Dialog.addRadioButtonGroup("Processing: ", processTypes,4,3,"Ball"); /* Ball creates two files, one under 45-capture process based on the flash reflection in the shiny ball, the other under 324-capture process based on the visible led reflection in the shiny ball Acca is the 45 capture process, accurate color using a* and b* channels from eureka lights and L from flash at 35 angles Accb is the 324 capture process, accurate color generated from 7 visible magic flashlight illuminations at each of 35 angles Pcaa is the 45 capture process, Todd's PCA pseudocolor generated fromY=Flash Cb=Pc2 Cr=Pc3 from eureka lights Pcab is the 45 capture process, Roger's PCA pseudocolor in LAB from Eureka lights with Flash as L for each angle Pcac is the 324 capture process, Roger's PCA pseudocolor generated at each angle using global stats (based on Eureka00) Pcad is the 324 capture process, Roger's PCA pseudocolor generated at each angle using local stats Pcae is the 324 capture process, Todd's PCA pseudocolor generated from Y=localPc0 Cb=localPc1 Cr=localPc3 from global stats Pcaf is the 324 capture process, Todd's PCA pseudocolor generated from Y=localPc0 Cb=localPc1 Cr=localPc2 from local stats Pcag is the 324 capture process, Y=localAvgL Cb=localPc2 Cr=localPc3 from global stats Suva is Simply UltraViolet, normalized separately at each angle to 0.1% saturation Igua is Infrared-529-Ultraviolet mapped to RGB, normalized separately at each angle to 0.1% saturation */ Dialog.addString("Start Direction: ", "1",2); Dialog.addString("Direction Count: ","1",2); Dialog.show(); var pathRoot = Dialog.getString(); var object = Dialog.getRadioButton(); var processType = Dialog.getRadioButton(); var startDirection = Dialog.getString(); var directions = Dialog.getString(); getDateAndTime(year, month, dayOfWeek, dayOfMonth, hour, minute, second, msec); year = toString(year); if (month < 9) month = "0" + toString(++month); else month = toString(++month); if (dayOfMonth < 10) dayOfMonth = "0" + toString(dayOfMonth); else dayOfMonth = toString(dayOfMonth); if (object == "Mask") captureDate = "20130722"; else if (object == "Sold") captureDate = "20130723"; else if (object == "Pal1") captureDate = "20130725"; else if (object == "Ant2") captureDate = "20130724"; else if (object == "Pal3") captureDate = "20130726"; else if (object == "Ant3") captureDate = "20130726"; else if (object == "Pal2") captureDate = "20130725"; if (processType == "Ball") { if (!File.exists(pathRoot+"Process"+File.separator+"45CaptureProcess"+File.separator+object+File.separator+processType)) File.makeDirectory(pathRoot+"Process"+File.separator+"45CaptureProcess"+File.separator+object+File.separator+processType); if (!File.exists(pathRoot+"Process"+File.separator+"45CaptureProcess"+File.separator+object+File.separator+processType+File.separator+"jpeg-exports")) File.makeDirectory(pathRoot+"Process"+File.separator+"45CaptureProcess"+File.separator+object+File.separator+processType+File.separator+"jpeg-exports"); for (direction=startDirection; direction <= directions; direction++) { if (direction < 10) angle = "0" + toString(direction); else angle = toString(direction); if (object == "Sold") angle = replace(angle,"01","01b"); //exception if (object == "Pal3") { if (angle == "02") open(pathRoot+"Capture"+File.separator+"Processed"+File.separator+captureDate+"-"+object+"-"+angle+"-Capt-01-50m"+File.separator+captureDate+"-"+object+"-"+angle+"-Capt-01-50m_011.tif"); else open(pathRoot+"Capture"+File.separator+"Processed"+File.separator+captureDate+"-"+object+"-"+angle+"-Capt-01-50m"+File.separator+captureDate+"-"+object+"-"+angle+"-Capt-01-50m+FLA-_011.tif"); } else if (object == "Ant3") open (pathRoot+"Capture"+File.separator+"Processed"+File.separator+captureDate+"-"+object+"-"+angle+"-Capt-01-50m"+File.separator+captureDate+"-"+object+"-"+angle+"-Capt-01-50m_001.tif"); else if (object == "Pal2") open (pathRoot+"Capture"+File.separator+"Processed"+File.separator+captureDate+"-"+object+"-AB-Capt-01-50m"+File.separator+captureDate+"-"+object+"-AB-Capt-01-50m_0"+angle+".tif"); else open(pathRoot+"Capture"+File.separator+"Processed"+File.separator+captureDate+"-"+object+"-"+angle+"-Capt-01-50m"+File.separator+captureDate+"-"+object+"-"+angle+"-Capt-01-50m+FLA_011.tif"); cropObject(); rotateObject(); saveAs("jpeg", pathRoot+"Process"+File.separator+"45CaptureProcess"+File.separator+object+File.separator+processType+File.separator+"jpeg-exports"+File.separator+year+month+dayOfMonth+"-"+object+"-"+angle+"-"+processType+"-03-50m-Fla.jpg"); close(); if (object == "Mask" ||object == "Sold" || object == "Pal1"|| object == "Ant2" || object == "Pal3") //skip objects for which Magic Flashlight not used, create shiny ball from visible led for others { if (object == "Pal3") open(pathRoot+"Capture"+File.separator+"Processed"+File.separator+captureDate+"-"+object+"-"+angle+"-Capt-01-50m"+File.separator+captureDate+"-"+object+"-"+angle+"-Capt-01-50m+507-_004.tif"); else open(pathRoot+"Capture"+File.separator+"Processed"+File.separator+captureDate+"-"+object+"-"+angle+"-Capt-01-50m"+File.separator+captureDate+"-"+object+"-"+angle+"-Capt-01-50m+507_004.tif"); cropObject(); rotateObject(); if (!File.exists(pathRoot+"Process"+File.separator+"324CaptureProcess"+File.separator+object+File.separator+processType)) File.makeDirectory(pathRoot+"Process"+File.separator+"324CaptureProcess"+File.separator+object+File.separator+processType); if (!File.exists(pathRoot+"Process"+File.separator+"324CaptureProcess"+File.separator+object+File.separator+processType+File.separator+"jpeg-exports")) File.makeDirectory(pathRoot+"Process"+File.separator+"324CaptureProcess"+File.separator+object+File.separator+processType+File.separator+"jpeg-exports"); saveAs("jpeg", pathRoot+"Process"+File.separator+"324CaptureProcess"+File.separator+object+File.separator+processType+File.separator+"jpeg-exports"+File.separator+year+month+dayOfMonth+"-"+object+"-"+angle+"-"+processType+"-03-50m-507.jpg"); close(); } } } else if (processType == "Acca") //Acca is the 45 capture process, accurate color using a* and b* channels from eureka lights and L from flash at 35 angles { if (object=="Mask") open (pathRoot+"Process"+File.separator+"9CaptureProcess"+File.separator+"Mask"+File.separator+"20130722-Mask-00-Capt-01-50m_PSC.tif"); else if (object=="Sold") open (pathRoot+"Process"+File.separator+"9CaptureProcess"+File.separator+"Sold"+File.separator+"20130723-Sold-00-Capt-01-50m_PSC.tif"); else if (object=="Ant2") open (pathRoot+"Process"+File.separator+"9CaptureProcess"+File.separator+"Ant2"+File.separator+"20130724-Ant2-00-Capt-01-50m_PSC.tif"); else print("Accurate Color from Eureka Lights not available for object "+object+"."); if (!File.exists(pathRoot+"Process"+File.separator+"45CaptureProcess"+File.separator+object+File.separator+processType)) File.makeDirectory(pathRoot+"Process"+File.separator+"45CaptureProcess"+File.separator+object+File.separator+processType); if (!File.exists(pathRoot+"Process"+File.separator+"45CaptureProcess"+File.separator+object+File.separator+processType+File.separator+"jpeg-exports")) File.makeDirectory(pathRoot+"Process"+File.separator+"45CaptureProcess"+File.separator+object+File.separator+processType+File.separator+"jpeg-exports"); lpFile = File.open(pathRoot+"Process"+File.separator+"45CaptureProcess"+File.separator+object+File.separator+processType+File.separator+year+month+dayOfMonth+"-"+object+"-99-"+processType+"-04-50m.txt"); print(lpFile,"35\n"); cropObject(); rename("Non-Standard LAB"); run("RGB Shifted32NonCom"); rename("LAB Stack"); close("Non-Standard LAB"); run("Stack to Images"); close("R-scale"); for (direction=startDirection; direction <= directions; direction++) { if (direction < 10) { angle = "0" + toString(direction); } else { angle = toString(direction); } if (object == "Sold") angle = replace(angle,"01","01b"); //exception open(pathRoot+"Capture"+File.separator+"Processed"+File.separator+captureDate+"-"+object+"-"+angle+"-Capt-01-50m"+File.separator+captureDate+"-"+object+"-"+angle+"-Capt-01-50m+FLA_011.tif"); cropObject(); rename("Flash"+angle); run("32-bit"); if (object=="Mask") multiplier = 0.003; else if (object=="Sold") multiplier = 0.0025; else if (object=="Ant2") multiplier = 0.003; //formerly 0.002 but visualize normals showed diminished results run("Multiply...", "value="+multiplier); multiplierString = toString(multiplier); multiplierString = replace(multiplierString,"0\\.",""); setMinAndMax(0, 100); run("Concatenate...", " title=[LAB] keep image1=Flash"+angle+" image2=G-shift image3=B-shift image4=[-- None --]"); run("CIE L*a*b* stack to RGB"); rotateObject(); saveAs("jpeg", pathRoot+"Process"+File.separator+"45CaptureProcess"+File.separator+object+File.separator+processType+File.separator+"jpeg-exports"+File.separator+year+month+dayOfMonth+"-"+object+"-"+angle+"-"+processType+"-03-50m-"+multiplierString+".jpg"); print(lpFile,pathRoot+"Process"+File.separator+"45CaptureProcess"+File.separator+object+File.separator+processType+File.separator+"jpeg-exports"+File.separator+year+month+dayOfMonth+"-"+object+"-"+angle+"-"+processType+"-03-50m-"+multiplierString+".jpg\n"); close(); close("LAB"); close("Flash"+angle); call("java.lang.System.gc"); } close("?-shift"); } else if (processType == "Accb") { print("Accb not yet written"); } else if (processType == "Pcaa") //Pcaa is the 45 capture process, Todd's PCA pseudocolor generated fromY=Flash Cb=Pc2 Cr=Pc3 from eureka lights { if (!File.exists(pathRoot+"Process"+File.separator+"45CaptureProcess"+File.separator+object+File.separator+processType)) File.makeDirectory(pathRoot+"Process"+File.separator+"45CaptureProcess"+File.separator+object+File.separator+processType); if (!File.exists(pathRoot+"Process"+File.separator+"45CaptureProcess"+File.separator+object+File.separator+processType+File.separator+"jpeg-exports")) File.makeDirectory(pathRoot+"Process"+File.separator+"45CaptureProcess"+File.separator+object+File.separator+processType+File.separator+"jpeg-exports"); if (object == "Pal1") objectFS = "PAL1"; else if (object == "Pal3") objectFS = "PAL3"; else objectFS = object; if (object=="Mask") open(pathRoot+"Process"+File.separator+"9CaptureProcess"+File.separator+object+File.separator+captureDate+"-"+object+"-00-Capt-01-50m_bands01-12_RF_cal_PCA_region_PC2_imglin2.tif"); else if (object == "Pal3") open(pathRoot+"Process"+File.separator+"20130913-Easton"+File.separator+objectFS+"-00"+File.separator+"PCA"+File.separator+"PAL3-00_bands01-09_cal_textblock_without-rubric_stats_PCA_1.img.tif"); else open(pathRoot+"Process"+File.separator+"9CaptureProcess"+File.separator+object+File.separator+captureDate+"-"+object+"-00-Capt-01-50m_12bands_cal_figure_stats_PC2_roi.tif"); enhanceObject(); cropObject(); rename("PCA2"); if (object=="Mask") open(pathRoot+"Process"+File.separator+"9CaptureProcess"+File.separator+object+File.separator+captureDate+"-"+object+"-00-Capt-01-50m_bands01-12_RF_cal_PCA_region_PC3_imglin2.tif"); else if (object == "Pal3") open(pathRoot+"Process"+File.separator+"20130913-Easton"+File.separator+objectFS+"-00"+File.separator+"PCA"+File.separator+"PAL3-00_bands01-09_cal_textblock_without-rubric_stats_PCA_3.img.tif"); else open(pathRoot+"Process"+File.separator+"9CaptureProcess"+File.separator+object+File.separator+captureDate+"-"+object+"-00-Capt-01-50m_12bands_cal_figure_stats_PC3_roi.tif"); enhanceObject(); cropObject(); rename("PCA3"); for (direction=startDirection; direction <= directions; direction++) { if (direction < 10) { angle = "0" + toString(direction); } else { angle = toString(direction); } if (object == "Sold") angle = replace(angle,"01","01b"); //exception //open(pathRoot+"Capture"+File.separator+"Processed"+File.separator+captureDate+"-"+objectFS+"-"+angle+"-Capt-01-50m"+File.separator+captureDate+"-"+objectFS+"-"+angle+"-Capt-01-50m+FLA-_011.tif"); //hyphen in FLA-_011 varies open(pathRoot+"Capture"+File.separator+"Processed"+File.separator+captureDate+"-"+objectFS+"-"+angle+"-Capt-01-50m"+File.separator+captureDate+"-"+objectFS+"-"+angle+"-Capt-01-50m+WHI-_010.tif"); //White enhanceObject(); cropObject(); rename("Flash"+angle); run("Concatenate...", " title=[YCC] keep image1=Flash"+angle+" image2=PCA2 image3=PCA3 image4=[-- None --]"); run("YCbCr stack to RGB"); rotateObject(); saveAs("jpeg", pathRoot+"Process"+File.separator+"45CaptureProcess"+File.separator+object+File.separator+processType+File.separator+"jpeg-exports"+File.separator+year+month+dayOfMonth+"-"+object+"-"+angle+"-"+processType+"-03-50m-WHI.jpg"); //White close(); close("YCC"); close("Flash"+angle); } close("PCA?"); } else if (processType == "Pcab") //Pcab is the 45 capture process, Roger's PCA pseudocolor in LAB from Eureka lights with Flash as L for each angle { print("Pcab not yet written: don't have Eurekalight Pseudocolor"); } else if (processType == "Pcac") //Pcac is the 324 capture process, Roger's PCA pseudocolor generated at each angle using global stats (based on Eureka00) { //question about RL00... means the red channel is luminance based on what? ... eureka lights! if (!File.exists(pathRoot+"Process"+File.separator+"324CaptureProcess"+File.separator+object+File.separator+processType)) File.makeDirectory(pathRoot+"Process"+File.separator+"324CaptureProcess"+File.separator+object+File.separator+processType); if (!File.exists(pathRoot+"Process"+File.separator+"324CaptureProcess"+File.separator+object+File.separator+processType+File.separator+"jpeg-exports")) File.makeDirectory(pathRoot+"Process"+File.separator+"324CaptureProcess"+File.separator+object+File.separator+processType+File.separator+"jpeg-exports"); for (direction=startDirection; direction <= directions; direction++) { if (direction < 10) { angle = "0" + toString(direction); } else { angle = toString(direction); } if (object == "Sold") angle = replace(angle,"01","01b"); //exception if (object == "Sold") angle = replace(angle,"04","04a"); //exception open(pathRoot+"Process"+File.separator+"324CaptureProcess"+File.separator+object+File.separator+"PCAPseudocolor-Eureka00_stats-RGB"+File.separator+captureDate+"-"+object+"-"+angle+"-Capt-01-50m_RL00_GPC2_BPC3_roi.tif"); cropObject(); rotateObject(); saveAs("jpeg",pathRoot+"Process"+File.separator+"324CaptureProcess"+File.separator+object+File.separator+processType+File.separator+"jpeg-exports"+File.separator+year+month+dayOfMonth+"-"+object+"-"+angle+"-"+processType+"-03-50m.jpg"); close(); } } else if (processType == "Pcad") //Pcad is the 324 capture process, Roger's PCA pseudocolor generated at each angle using local stats { print("Pcad not yet written: don't have local stats"); } else if (processType == "Pcae") //Pcae is the 324 capture process, Todd's PCA pseudocolor generated from Y=localPc1 Cb=localPc2 Cr=localPc3 from global stats { if (!File.exists(pathRoot+"Process"+File.separator+"324CaptureProcess"+File.separator+object+File.separator+processType)) File.makeDirectory(pathRoot+"Process"+File.separator+"324CaptureProcess"+File.separator+object+File.separator+processType); if (!File.exists(pathRoot+"Process"+File.separator+"324CaptureProcess"+File.separator+object+File.separator+processType+File.separator+"jpeg-exports")) File.makeDirectory(pathRoot+"Process"+File.separator+"324CaptureProcess"+File.separator+object+File.separator+processType+File.separator+"jpeg-exports"); for (direction=startDirection; direction <= directions; direction++) { if (direction < 10) { angle = "0" + toString(direction); } else { angle = toString(direction); } if (object == "Sold") angle = replace(angle,"01","01b"); //exception if (object == "Pal1") objectFS = "PAL1"; else if (object == "Pal3") objectFS = "PAL3"; else objectFS = object; //Y = Pc0 open(pathRoot+"Process"+File.separator+"20130913-Easton"+File.separator+objectFS+"-"+angle+File.separator+"PCA"+File.separator+"Global"+File.separator+objectFS+"-"+angle+"_bands01-09_cal_textblock_without-rubric_stats_global_PCA_0.img.tif"); if (object == "Pal3") makeRectangle(4428,1989,924,1686); run("Enhance Contrast...", "saturated=0.4 normalize"); run("8-bit"); cropObject(); if (getPixel(4338,1584) < 128) run("Invert"); //standardize light text on dark for Pal3 rename("Y"); //Cb = Pc1 open(pathRoot+"Process"+File.separator+"20130913-Easton"+File.separator+objectFS+"-"+angle+File.separator+"PCA"+File.separator+"Global"+File.separator+objectFS+"-"+angle+"_bands01-09_cal_textblock_without-rubric_stats_global_PCA_1.img.tif"); if (object == "Pal3") makeRectangle(4428,1989,924,1686); run("Enhance Contrast...", "saturated=0.4 normalize"); run("8-bit"); cropObject(); if (getPixel(4338,1584) < 128) run("Invert"); //standardize light text on dark for Pal3 rename("Cb"); //Cr = Pc2 open(pathRoot+"Process"+File.separator+"20130913-Easton"+File.separator+objectFS+"-"+angle+File.separator+"PCA"+File.separator+"Global"+File.separator+objectFS+"-"+angle+"_bands01-09_cal_textblock_without-rubric_stats_global_PCA_2.img.tif"); if (object == "Pal3") makeRectangle(4428,1989,924,1686); run("Enhance Contrast...", "saturated=0.4 normalize"); run("8-bit"); cropObject(); if (getPixel(4338,1584) < 128) run("Invert"); //standardize light text on dark for Pal3 rename("Cr"); //Concatenate, convert, and save run("Concatenate...", " title=[YCC] image1=Y image2=Cb image3=Cr image4=[-- None --]"); run("YCbCr stack to RGB"); rotateObject(); saveAs("jpeg", pathRoot+"Process"+File.separator+"324CaptureProcess"+File.separator+object+File.separator+processType+File.separator+"jpeg-exports"+File.separator+year+month+dayOfMonth+"-"+object+"-"+angle+"-"+processType+"-03-50m-LightText-012.jpg"); //light text variant close("YCC"); } } else if (processType == "Pcaf") //Pcaf is the 324 capture process, Todd's PCA pseudocolor generated from Y=localPc0 Cb=localPc1 Cr=localPc2 from local stats { if (!File.exists(pathRoot+"Process"+File.separator+"324CaptureProcess"+File.separator+object+File.separator+processType)) File.makeDirectory(pathRoot+"Process"+File.separator+"324CaptureProcess"+File.separator+object+File.separator+processType); if (!File.exists(pathRoot+"Process"+File.separator+"324CaptureProcess"+File.separator+object+File.separator+processType+File.separator+"jpeg-exports")) File.makeDirectory(pathRoot+"Process"+File.separator+"324CaptureProcess"+File.separator+object+File.separator+processType+File.separator+"jpeg-exports"); for (direction=startDirection; direction <= directions; direction++) { if (direction < 10) { angle = "0" + toString(direction); } else { angle = toString(direction); } if (object == "Sold") angle = replace(angle,"01","01b"); //exception if (object == "Pal1") objectFS = "PAL1"; else if (object == "Pal3") objectFS = "PAL3"; else objectFS = object; //Y = Pc0 open(pathRoot+"Process"+File.separator+"20130913-Easton"+File.separator+objectFS+"-"+angle+File.separator+"PCA"+File.separator+"Individual"+File.separator+objectFS+"-"+angle+"_bands01-09_cal_textblock_without-rubric_stats_individual_PCA_0.img.tif"); enhanceObject(); cropObject(); if (getPixel(4338,1584) < 128) run("Invert"); //standardize light text on dark for Pal3 rename("Y"); //Cb = Pc1 open(pathRoot+"Process"+File.separator+"20130913-Easton"+File.separator+objectFS+"-"+angle+File.separator+"PCA"+File.separator+"Individual"+File.separator+objectFS+"-"+angle+"_bands01-09_cal_textblock_without-rubric_stats_individual_PCA_1.img.tif"); if (object == "Pal3") makeRectangle(4428,1989,924,1686); run("Enhance Contrast...", "saturated=0.4 normalize"); run("8-bit"); cropObject(); if (getPixel(4338,1584) < 128) run("Invert"); //standardize light text on dark for Pal3 rename("Cb"); //Cr = Pc2 open(pathRoot+"Process"+File.separator+"20130913-Easton"+File.separator+objectFS+"-"+angle+File.separator+"PCA"+File.separator+"Individual"+File.separator+objectFS+"-"+angle+"_bands01-09_cal_textblock_without-rubric_stats_individual_PCA_2.img.tif"); if (object == "Pal3") makeRectangle(4428,1989,924,1686); run("Enhance Contrast...", "saturated=0.4 normalize"); run("8-bit"); cropObject(); if (getPixel(4338,1584) < 128) run("Invert"); //standardize light text on dark for Pal3 rename("Cr"); //Concatenate, convert, and save run("Concatenate...", " title=[YCC] image1=Y image2=Cb image3=Cr image4=[-- None --]"); run("YCbCr stack to RGB"); rotateObject(); saveAs("jpeg", pathRoot+"Process"+File.separator+"324CaptureProcess"+File.separator+object+File.separator+processType+File.separator+"jpeg-exports"+File.separator+year+month+dayOfMonth+"-"+object+"-"+angle+"-"+processType+"-03-50m-LightText.jpg"); //light text variant close("YCC"); } } else if (processType == "Pcag") //Pcag is the 324 capture process, Y=localAvgL Cb=localPc2 Cr=localPc3 from local global { if (!File.exists(pathRoot+"Process"+File.separator+"324CaptureProcess"+File.separator+object+File.separator+processType)) File.makeDirectory(pathRoot+"Process"+File.separator+"324CaptureProcess"+File.separator+object+File.separator+processType); if (!File.exists(pathRoot+"Process"+File.separator+"324CaptureProcess"+File.separator+object+File.separator+processType+File.separator+"jpeg-exports")) File.makeDirectory(pathRoot+"Process"+File.separator+"324CaptureProcess"+File.separator+object+File.separator+processType+File.separator+"jpeg-exports"); for (direction=startDirection; direction <= directions; direction++) { if (direction < 10) { angle = "0" + toString(direction); } else { angle = toString(direction); } if (object == "Sold") angle = replace(angle,"01","01b"); //exception //calculate luminance from average intensity of nine bands, normalized imageSequenceArg = "open="+pathRoot+"Capture"+File.separator+"Processed"+File.separator+captureDate+"-"+object+"-"+angle+"-Capt-01-50m"+File.separator+captureDate+"-"+object+"-"+angle+"-Capt-01-50m+446_002.tif number=9 starting=1 increment=1 scale=100 file=(\\+[0-9]) sort use"; run("Image Sequence...", imageSequenceArg); cropObject(); run("Z Project...", "start=1 stop=9 projection=[Average Intensity]"); close(captureDate+"-"+object+"-"+angle+"-Capt-01-50m"); run("Enhance Contrast...", "saturated=0.4 normalize"); run("8-bit"); rename("Y"); //use pc2 as Cb open(pathRoot+"Process"+File.separator+"324CaptureProcess"+File.separator+object+File.separator+"PCA"+File.separator+captureDate+"-"+object+"-"+angle+"-Capt-01-50m_cal_figure_stats_PC2_roi.tif"); cropObject(); run("8-bit"); rename("Cb"); //use pc3 as Cr open(pathRoot+"Process"+File.separator+"324CaptureProcess"+File.separator+object+File.separator+"PCA"+File.separator+captureDate+"-"+object+"-"+angle+"-Capt-01-50m_cal_figure_stats_PC3_roi.tif"); cropObject(); run("8-bit"); rename("Cr"); //combine run("Concatenate...", " title=[YCC] image1=Y image2=Cb image3=Cr image4=[-- None --]"); run("YCbCr stack to RGB"); rotateObject(); saveAs("jpeg", pathRoot+"Process"+File.separator+"324CaptureProcess"+File.separator+object+File.separator+processType+File.separator+"jpeg-exports"+File.separator+year+month+dayOfMonth+"-"+object+"-"+angle+"-"+processType+"-03-50m.jpg"); close("YCC"); } } else if (processType == "Suva") //Suva is Simply UltraViolet, normalized separately at each angle to 0.1% saturation { if (!File.exists(pathRoot+"Process"+File.separator+"324CaptureProcess"+File.separator+object+File.separator+processType)) File.makeDirectory(pathRoot+"Process"+File.separator+"324CaptureProcess"+File.separator+object+File.separator+processType); if (!File.exists(pathRoot+"Process"+File.separator+"324CaptureProcess"+File.separator+object+File.separator+processType+File.separator+"jpeg-exports")) File.makeDirectory(pathRoot+"Process"+File.separator+"324CaptureProcess"+File.separator+object+File.separator+processType+File.separator+"jpeg-exports"); for (direction=startDirection; direction <= directions; direction++) { if (direction < 10) { angle = "0" + toString(direction); } else { angle = toString(direction); } if (object == "Sold") angle = replace(angle,"01","01b"); //exception open(pathRoot+"Capture"+File.separator+"Processed"+File.separator+captureDate+"-"+object+"-"+angle+"-Capt-01-50m"+File.separator+captureDate+"-"+object+"-"+angle+"-Capt-01-50m+393_001.tif"); cropObject(); run("Enhance Contrast...", "saturated=0.1 normalize"); run("8-bit"); rotateObject(); rename("Ruv"); run("Duplicate...", "title=Guv"); run("Duplicate...", "title=Buv"); run("Concatenate...", " title=[RGB] image1=Ruv image2=Guv image3=Buv image4=[-- None --]"); run("Stack to RGB"); saveAs("jpeg", pathRoot+"Process"+File.separator+"324CaptureProcess"+File.separator+object+File.separator+processType+File.separator+"jpeg-exports"+File.separator+year+month+dayOfMonth+"-"+object+"-"+angle+"-"+processType+"-03-50m.jpg"); close(); } } else if (processType == "Igua") //Igua is Infrared-529-Ultraviolet mapped to RGB, normalized separately at each angle to 0.1% saturation { if (!File.exists(pathRoot+"Process"+File.separator+"324CaptureProcess"+File.separator+object+File.separator+processType)) File.makeDirectory(pathRoot+"Process"+File.separator+"324CaptureProcess"+File.separator+object+File.separator+processType); if (!File.exists(pathRoot+"Process"+File.separator+"324CaptureProcess"+File.separator+object+File.separator+processType+File.separator+"jpeg-exports")) File.makeDirectory(pathRoot+"Process"+File.separator+"324CaptureProcess"+File.separator+object+File.separator+processType+File.separator+"jpeg-exports"); for (direction=startDirection; direction <= directions; direction++) { if (direction < 10) { angle = "0" + toString(direction); } else { angle = toString(direction); } if (object == "Sold") angle = replace(angle,"01","01b"); //exception if (object == "Pal1") objectFS = "PAL1"; if (object == "Pal3") objectFS = "PAL3"; else objectFS = object; //IR open(pathRoot+"Capture"+File.separator+"Processed"+File.separator+captureDate+"-"+objectFS+"-"+angle+"-Capt-01-50m"+File.separator+captureDate+"-"+objectFS+"-"+angle+"-Capt-01-50m+830-_009.tif"); enhanceObject(); cropObject(); //run("Enhance Contrast...", "saturated=0.1 normalize"); //run("8-bit"); rename("IR"); //G = 529 open(pathRoot+"Capture"+File.separator+"Processed"+File.separator+captureDate+"-"+objectFS+"-"+angle+"-Capt-01-50m"+File.separator+captureDate+"-"+objectFS+"-"+angle+"-Capt-01-50m+529-_005.tif"); enhanceObject(); cropObject(); //run("Enhance Contrast...", "saturated=0.1 normalize"); //run("8-bit"); rename("G"); //UV open(pathRoot+"Capture"+File.separator+"Processed"+File.separator+captureDate+"-"+objectFS+"-"+angle+"-Capt-01-50m"+File.separator+captureDate+"-"+objectFS+"-"+angle+"-Capt-01-50m+393-_001.tif"); enhanceObject(); cropObject(); //run("Enhance Contrast...", "saturated=0.1 normalize"); //run("8-bit"); rename("UV"); run("Concatenate...", " title=[RGB] image1=IR image2=G image3=UV image4=[-- None --]"); run("Stack to RGB"); rotateObject(); saveAs("jpeg", pathRoot+"Process"+File.separator+"324CaptureProcess"+File.separator+object+File.separator+processType+File.separator+"jpeg-exports"+File.separator+year+month+dayOfMonth+"-"+object+"-"+angle+"-"+processType+"-03-50m-n.jpg"); close(); } } setBatchMode(false); } macro "Method 17 [7]" { //prompt user for object setBatchMode(true); Dialog.create("Confirm information"); Dialog.addMessage("Confirm the following"); Dialog.addString("General Project Path: ", File.separator+"home"+File.separator+"faculty"+File.separator+"thanneken"+File.separator+"Projects"+File.separator+"Integrating"+File.separator, 40); var objects = newArray("Mask", "Sold", "Pal1", "Ant2", "Pal3", "Ant3", "Pal2"); Dialog.addRadioButtonGroup("Object: ", objects, 4, 2, "Pal3"); Dialog.addString("Start Direction: ", "1",2); Dialog.addString("Direction Count: ","5",2); Dialog.show(); var pathRoot = Dialog.getString(); var object = Dialog.getRadioButton(); var startDirection = Dialog.getString(); var directions = Dialog.getString(); //dates getDateAndTime(year, month, dayOfWeek, dayOfMonth, hour, minute, second, msec); year = toString(year); if (month < 9) month = "0" + toString(++month); else month = toString(++month); if (dayOfMonth < 10) dayOfMonth = "0" + toString(dayOfMonth); else dayOfMonth = toString(dayOfMonth); if (object == "Mask") captureDate = "20130722"; else if (object == "Sold") captureDate = "20130723"; else if (object == "Pal1") captureDate = "20130725"; else if (object == "Ant2") captureDate = "20130724"; else if (object == "Pal3") captureDate = "20130726"; else if (object == "Ant3") captureDate = "20130726"; else if (object == "Pal2") captureDate = "20130725"; //prompt user for roi if (!isOpen("Preview")) { open (pathRoot+"Curated"+File.separator+object+File.separator+"Capt"+File.separator+captureDate+"-"+object+"-393-01-Capt-01-50m-001.tif"); rename("Preview"); rotateObject(); run("Enhance Contrast...", "saturated=0.4 normalize"); setBatchMode(false); //there is a better way with newer versions of imagej waitForUser("Select ROI", "Select a Region of Interest (ROI) in the preview image"); } getSelectionBounds(x, y, width, height); setBatchMode(true); //there is a better way with newer versions of imagej //prompt user for process, and contrast enhancement Dialog.create("Select Process"); Dialog.addMessage("What would you like to do with this region of interest?"); var processes = newArray("35xUV","35x9"); Dialog.addRadioButtonGroup("Process: ", processes, 1, 2, "35xUV"); Dialog.addCheckbox("Enhance",true) Dialog.show(); var process = Dialog.getRadioButton(); var enhance = Dialog.getCheckbox(); //35xflash if (process == "35xUV") { for (direction=startDirection; direction <= directions; direction++) { if (direction < 10) { angle = "0" + toString(direction); } else { angle = toString(direction); } open (pathRoot+"Curated"+File.separator+object+File.separator+"Capt"+File.separator+captureDate+"-"+object+"-393-"+angle+"-Capt-01-50m-001.tif"); makeRectangle(getWidth()-y-height, x, height, width); run("Crop"); if (enhance) run("Enhance Contrast...", "saturated=0.4 normalize"); } } //35x9 else if (process == "35x9") { fileList = getFileList(pathRoot+"Curated"+File.separator+object+File.separator+"Capt"); for (i=0;i