var save_dir = "/home/moadeep/Fiji.app/temp/" //getDirectory("temp"); //if(save_dir=="") //exit("No temp directory available"); macro "Initialise [1]" { //open image to register print("Open follow up scan to register"); open(); sourceTitle = getTitle(); run("Duplicate...", "title=[Source Stack] duplicate range=1-2"); selectWindow(sourceTitle); close(); //get count mean in source image selectWindow("Source Stack"); getStatistics(area,mean); source_mean_ant = mean; setSlice(2); getStatistics(area,mean); source_mean_post = mean; setSlice(1); print("source anterior mean = "+source_mean_ant); print("source posterior mean = "+source_mean_post); //open up initial scan - this is the target image print("Open initial scan, this is the target"); open(); targetTitle = getTitle(); run("Duplicate...","title=[Target Stack] duplicate range=1-2"); run("Brightness/Contrast..."); run("Enhance Contrast", "saturated=0.35"); run("Fire"); selectWindow(targetTitle); close(); print("Registering "+ sourceTitle + " to " + targetTitle); //get count mean in target image selectWindow("Target Stack"); getStatistics(area, mean); template_mean_ant = mean; setSlice(2); getStatistics(area, mean); template_mean_post = mean; setSlice(1); //calculate correction factor to normalise counts ant_cor = template_mean_ant/source_mean_ant; post_cor = template_mean_post/source_mean_post; print("anterior scale correction = "+ant_cor); print("posterior scale correction = "+post_cor); //apply correction factor to source image selectWindow("Source Stack"); setSlice(1); run("Multiply...","value="+ant_cor+" slice"); setSlice(2); run("Multiply...","value="+post_cor+" slice"); setSlice(1); run("Fire"); run("Enhance Contrast", "saturated=0.35"); //duplicate source stack and create geometric mean ant + post selectWindow("Source Stack"); run("Duplicate...","title=[Source Duplicate] duplicate range=1-2"); setSlice(2); run("Flip Horizontally", "slice"); run("Z Project...", "start=1 stop=2 projection=[Average Intensity]"); rename("Source_Mean"); run("Enhance Contrast", "saturated=0.35"); run("Fire"); selectWindow("Source Duplicate"); close(); //Repeat for target stack selectWindow("Target Stack"); run("Duplicate...","title=[Target Duplicate] duplicate range=1-2"); setSlice(2); run("Flip Horizontally", "slice"); run("Z Project...", "start=1 stop=2 projection=[Average Intensity]"); rename("Target_Mean"); run("Enhance Contrast", "saturated=0.35"); run("Fire"); selectWindow("Target Duplicate"); close(); //Save Mean images for registration check later selectWindow("Source_Mean"); save(save_dir+"Source_Mean.tif"); selectWindow("Target_Mean"); save(save_dir+"Target_Mean.tif"); //Duplicate target image to store Target Mask selectWindow("Target_Mean"); run("Duplicate...", "title=[Target Mask] duplicate"); //Duplicate source image to store source mask selectWindow("Source_Mean"); run("Duplicate...", "title=[Source Mask] duplicate"); print("Do image pre-processing now before registering"); run("Tile"); } //Get deformation field from geometric mean image ant/post macro "Find Deformation Field [2]" { // Create basic dialog listRegistrationMode = newArray("Fast", "Accurate", "Mono"); listInitialDef = newArray("Very Coarse","Coarse","Fine","Very Fine"); listFinalDef = newArray("Very Coarse","Coarse","Fine","Very Fine","Super Fine"); listImgSub = newArray("0","1","2","3","4","5","6","7"); Dialog.create("Affine + Consistent Elastic 2D Registration"); Dialog.addMessage("********* bUnwarpJ options *********"); Dialog.addChoice("Registration Mode", listRegistrationMode, "Accurate"); Dialog.addChoice("Image_Subsample_Factor", listImgSub, "0"); Dialog.addChoice("Initial Deformation",listInitialDef, "Very Coarse"); Dialog.addChoice("Final Deformation",listFinalDef, "Very Fine"); Dialog.addNumber("Divergence Weight", 0.0); Dialog.addNumber("Curl Weight", 0.0); Dialog.addNumber("Landmark Weight",0.0); Dialog.addNumber("Image Weight", 1.0); Dialog.addNumber("Consistency Weight", 10.0); Dialog.addNumber("Stop Threshold", 0.01); Dialog.addCheckbox("Verbose",false); Dialog.addCheckbox("Save Transformations",true); Dialog.addMessage("*************MASK****************"); Dialog.addCheckbox("Source Mask?", true); Dialog.addCheckbox("Target Mask?", true); Dialog.addCheckbox("Use SIFT?", false); Dialog.addCheckbox("Use MOPS?", false); Dialog.show(); r=Dialog.getChoice; img_sub_factor = Dialog.getChoice; id=Dialog.getChoice; fd=Dialog.getChoice; dw=Dialog.getNumber; curlw=Dialog.getNumber; lw=Dialog.getNumber; iw=Dialog.getNumber; conw=Dialog.getNumber; st=Dialog.getNumber; verbosebool=Dialog.getCheckbox; strbool=Dialog.getCheckbox; source_maskbool=Dialog.getCheckbox; target_maskbool=Dialog.getCheckbox; sift_bool=Dialog.getCheckbox; mops_bool=Dialog.getCheckbox; if (id=="Very Coarse") {id="[Very Coarse]";} else if (id=="Very Fine") {id="[Very Fine]";} if (fd=="Very Coarse") {fd="[Very Coarse]";} else if (fd=="Very Fine") {fd="[Very Fine]";} else if (fd=="Super Fine") {fd="[Super Fine]";} if (verbosebool==1){verbose="verbose";} else {verbose="";} if (strbool==1){str="save_transformations";} else {str="";} //if source mask is required it must be created prior to executing this macro, threshold then create mask if(source_maskbool==0) //if no mask - set mask image to all white { selectWindow("Source Mask"); //Set mask to all white setForegroundColor(255, 255, 255); run("Select All"); run("Fill"); } if(target_maskbool==0) { selectWindow("Target Mask"); setForegroundColor(255, 255, 255); run("Select All"); run("Fill"); } //Register whole body mean image - this finds the deformation field for anterior scans sourceName = "Source_Mean"; targetName = "Target_Mean"; //Add source mask selectWindow("Source Mask"); run("Copy"); close(); selectWindow(sourceName); run("Add Slice"); run("Paste"); wait(1000); setSlice(1); //Add target mask selectWindow("Target Mask"); run("Copy"); close(); selectWindow(targetName); run("Add Slice"); run("Paste"); wait(1000); setSlice(1); if(sift_bool==1) { run("Extract SIFT Correspondences", "source_image="+sourceName+ " target_image="+targetName+" initial_gaussian_blur=2 steps_per_scale_octave=3 minimum_image_size=64 maximum_image_size=1024 feature_descriptor_size=4 feature_descriptor_orientation_bins=8 closest/next_closest_ratio=0.92 filter maximal_alignment_error=25 minimal_inlier_ratio=0.05 minimal_number_of_inliers=7 expected_transformation=Affine"); } if(mops_bool==1) { run("Extract MOPS Correspondences", "source_image="+sourceName+ " target_image="+targetName+" initial_gaussian_blur=2 steps_per_scale_octave=3 minimum_image_size=64 maximum_image_size=1024 feature_descriptor_size=4 feature_descriptor_orientation_bins=8 closest/next_closest_ratio=0.92 filter maximal_alignment_error=25 minimal_inlier_ratio=0.05 minimal_number_of_inliers=7 expected_transformation=Affine"); } wait(1000); run("Tile"); // Register with bUnwarpJ run("bUnwarpJ", "source_image=" + sourceName + " target_image=" + targetName + " registration=" + r + " initial_deformation=" + id + " final_deformation=" + fd + " divergence_weight=" + dw + " curl_weight=" + curlw + " landmark_weight="+ lw + " image_weight=" + iw + " consistency_weight=" + conw + " stop_threshold=" + st + " " + verbose + str); //wait for bUnwarpJ to finish //print out bUnwarpJ paramaters print("registration=" + r + " initial_deformation=" + id + " final_deformation=" + fd + " divergence_weight=" + dw + " curl_weight=" + curlw + " landmark_weight="+ lw + " image_weight=" + iw + " consistency_weight=" + conw + " stop_threshold=" + st + " " + verbose + str); // Wait bUnwarpJ to finish while (isOpen("Registered Target Image") != 1) { wait(1000); } wait(1500); print("Finished initial registration, deformation field is saved"); //Close inverse registration result selectWindow("Registered Target Image"); close(); run("Tile"); selectWindow(sourceName); close(); selectWindow(targetName); close(); File.rename("Source_Mean_direct_transf.txt", save_dir+"Source_Mean_direct_transf.txt"); File.delete("Target_Mean_inverse_transf.txt"); run("Tile"); } //Check goodness of registration macro "Check Registration [3]" { //apply saved transformation to source mean image call("bunwarpj.bUnwarpJ_.elasticTransformImageMacro", save_dir+"Target_Mean.tif", save_dir+"Source_Mean.tif", save_dir+"Source_Mean_direct_transf.txt", save_dir+"Registered_Source_Mean.tif"); open(save_dir+"Registered_Source_Mean.tif"); open(save_dir+"Target_Mean.tif"); selectWindow("Registered_Source_Mean.tif"); run("Brightness/Contrast..."); run("Enhance Contrast", "saturated=0.35"); run("Close"); imageCalculator("Difference create", "Target_Mean.tif","Registered_Source_Mean.tif"); run("Measure"); selectWindow("Target_Mean.tif"); run("Green"); run("RGB Color"); selectWindow("Registered_Source_Mean.tif"); run("Red"); run("RGB Color"); imageCalculator("Add create", "Target_Mean.tif","Registered_Source_Mean.tif"); rename("Merged Image"); selectWindow("Target_Mean.tif"); run("Add Slice"); selectWindow("Registered_Source_Mean.tif"); run("Copy"); close(); selectWindow("Target_Mean.tif"); run("Paste"); run("Add Slice"); selectWindow("Result of Target_Mean.tif"); run("Copy"); close(); selectWindow("Target_Mean.tif"); run("Paste"); run("Add Slice"); selectWindow("Merged Image"); run("Copy"); close(); selectWindow("Target_Mean.tif"); run("Paste"); File.delete("Source_Mean_direct_transf.txt"); } //This function calls the saved deformation field and applies it to the image to be registered macro "Register [4]" { //The load transformation macro in bUnwarp operates on images saved on file not open images //first stage is to save anterior/posterior images to /tmp directory for(i=1;i<3;i++) { saveSourceName = "TempSourceImage-"+i; saveTargetName = "TempTargetImage-"+i; selectWindow("Source Stack"); setSlice(i); run("Duplicate...", "title="+saveSourceName); //flip posterior image before saving if(i==2) run("Flip Horizontally"); save(save_dir+saveSourceName+".tif"); close(); selectWindow("Target Stack"); setSlice(i); run("Duplicate...", "title="+saveTargetName); save(save_dir+saveTargetName+".tif"); close(); } selectWindow("Target Stack"); setSlice(1); selectWindow("Source Stack"); setSlice(1); //register anterior image call("bunwarpj.bUnwarpJ_.elasticTransformImageMacro", save_dir+"TempTargetImage-1.tif", save_dir+"TempSourceImage-1.tif", save_dir+"Source_Mean_direct_transf.txt", save_dir+"Anterior.tif"); //register posterior image call("bunwarpj.bUnwarpJ_.elasticTransformImageMacro", save_dir+"TempTargetImage-2.tif", save_dir+"TempSourceImage-2.tif", save_dir+"Source_Mean_direct_transf.txt", save_dir+"Posterior.tif"); //close source stack and create registered source stack selectWindow("Source Stack"); run("Duplicate...","title=[Registered Source Stack] duplicate range=1-2"); open(save_dir+"Anterior.tif"); run("Copy"); close(); selectWindow("Registered Source Stack"); setSlice(1); run("Paste"); open(save_dir+"Posterior.tif"); run("Flip Horizontally"); run("Copy"); close(); selectWindow("Registered Source Stack"); setSlice(2); run("Paste"); setSlice(1); run("Brightness/Contrast..."); run("Enhance Contrast", "saturated=0.35"); run("Fire"); selectWindow("Source Stack"); close(); run("Tile"); } macro "Difference Image [5]" { } macro "Initial Check" { selectWindow("Source_Mean"); run("Duplicate...", "title=Source_Mean-1"); selectWindow("Target_Mean"); run("Duplicate...", "title=Target_Mean-1"); selectWindow("Source_Mean-1"); imageCalculator("Difference create", "Source_Mean-1","Target_Mean-1"); run("Measure"); selectWindow("Target_Mean-1"); run("Green"); run("RGB Color"); selectWindow("Source_Mean-1"); run("Red"); run("RGB Color"); imageCalculator("Add create", "Source_Mean-1","Target_Mean-1"); selectWindow("Source_Mean-1"); run("Add Slice"); selectWindow("Target_Mean-1"); run("Copy"); selectWindow("Source_Mean-1"); run("Paste"); selectWindow("Target_Mean-1"); close(); selectWindow("Source_Mean-1"); run("Add Slice"); selectWindow("Result of Source_Mean-1"); run("Copy"); selectWindow("Source_Mean-1"); run("Paste"); selectWindow("Result of Source_Mean-1"); close(); selectWindow("Source_Mean-1"); run("Add Slice"); selectWindow("Result of Source_Mean-1"); run("Copy"); selectWindow("Source_Mean-1"); run("Paste"); selectWindow("Result of Source_Mean-1"); close(); selectWindow("Source_Mean-1"); }