macro "Create 3D stack from image and height map" { macroL = "Image_plus_height_map_to_stack_v240220.ijm"; imageN = nImages; if (imageN<2) showMessageWithCancel("This macro requires an open height map image and an open texture image"); if (imageN>1){ /* workaround for issue with duplicate names for single open image */ imageList = removeDuplicatesInArray(getList("image.titles"), false); imageN = lengthOf(imageList); } infoColor = "#006db0"; /* Honolulu blue */ instructionColor = "#798541"; /* green_dark_modern (121, 133, 65) AKA Wasabi */ infoWarningColor = "#ff69b4"; /* pink_modern AKA hot pink */ infoFontSize = 12; /* Create initial dialog prompt to determine parameters */ Dialog.create("Image selection: " + macroL); Dialog.addRadioButtonGroup("Choose height map: ", imageList, imageN, 1, imageList[0]); Dialog.addRadioButtonGroup("Choose image for texture: ", imageList, imageN, 1, imageList[0]); Dialog.show(); heightMap = Dialog.getRadioButton(); textureImage = Dialog.getRadioButton(); setBatchMode(true); selectWindow(textureImage); imageDepth = bitDepth(); getDimensions(imageWidth, imageHeight, imageChannels, imageSlices, imageFrames); selectWindow(heightMap); mapDepth = bitDepth(); getDimensions(mapWidth, mapHeight, mapChannels, mapSlices, mapFrames); if (imageWidth!=mapWidth || imageHeight!=mapHeight) exit("The map and texture images are not the same size"); getVoxelSize(voxelWidth, voxelHeight, voxelDepth, voxelUnit); getStatistics(mapArea, mapMean, mapMin, mapMax, mapStd, mapHistogram); /* For 16-bit and 32-bit images, the bin width is (max-min)/256. */ if (mapDepth==24) exit("Color image cannot be used in " + macroL); Dialog.create("Parameter selection: " + macroL); Dialog.addNumber("Voxel width", voxelWidth, 3, 6, "units"); Dialog.addNumber("Voxel height", voxelHeight, 3, 6, "units"); Dialog.addNumber("Original voxel depth", voxelDepth, 3, 6, "units"); Dialog.addString("Voxel units", voxelUnit, 6); Dialog.addNumber("Minimum of height range", mapMin, 3, 6, "map intensity"); Dialog.addNumber("Maximum of height range", mapMax, 3, 6, "map intensity"); Dialog.addNumber("Number of slices used for height range", mapMax - mapMin, 0, 6, "slices"); Dialog.addCheckbox("Create solid object", false); Dialog.show(); voxelWidth = Dialog.getNumber(); voxelHeight = Dialog.getNumber(); voxelDepth = Dialog.getNumber(); voxelUnit = Dialog.getString(); mapMin = Dialog.getNumber(); mapMax = Dialog.getNumber(); sliceN = Dialog.getNumber(); makeSolid = Dialog.getCheckbox(); heightArray = newArray(); heightIncr = (mapMax - mapMin) / sliceN; for (i=0; i=0){ if (makeSolid){ for (i=0; i=value){ indexFound = i; i = lengthOf(array); } } return indexFound; } function removeDuplicatesInArray(array, sortFlag) { /* v230822-3: 1st version. Peter J. Lee FSU */ if (lengthOf(array)<=1) return array; else { if (!sortFlag) arrayOrder = Array.rankPositions(array); sortedArray = Array.sort(array); for (i=0; i