Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Other ImageJ Film Restoration macros.
#1
I've been working a bit on using ImageJ as a method for performing various film restoration methods. It is a work in progress and there are quite a few new ideas that I've yet to implement and the code is probably atrocious since I know next to nothing about javascript or imagej macros but what I have so far is:

Image Stabilization (not fully tested)
Color Matching (V2 has many more options)
Film Registration (Needs some fine tuning and batchmode for quicker processing)

I possibly might be able to implement in the future:

Grain Removal
Dirt Removal
16bit color image sequence input/output (using ffmpeg and avi import is probably limited to 8 bit for the time being at least)
Williarob has pitched a few ideas about handling of missing frames that I'm going to try to figure out as well.
Hoping to find a way to utilize more cores/threads for faster speed.

Macro for Stabilization
Code:
Dialog.create("Film Stabilization");
Dialog.addMessage("Stabilize Film Scan:")
Dialog.addChoice("Input File Type:", newArray("AVI", "Using FFmpeg", "Image Sequence"), "AVI");
Dialog.show()
TFT=Dialog.getChoice();
Targetpath = File.openDialog("Select File:");
outputtargetdir = getDirectory("Choose output folder for sprocket stabilized TIF image sequence:");
run(TFT+"...", "open=["+Targetpath+"] sort use");
rename("target");
wait(1000);
setLocation(0,0,360,240);
selectWindow("Log");
setLocation(0,241);
print("Stabilizing...Please Wait.");
run("Image Stabilizer", "output=["+outputtargetdir+"] transformation=Translation maximum_pyramid_levels=1 template_update_coefficient=0.90 maximum_iterations=200 error_tolerance=0.0000001");
print("\\Clear");
close("*");
call("java.lang.System.gc");
beep();
waitForUser("Image stabilization is finished.");

Macro for Color Matching
Code:
Dialog.create("Colormatching");
Dialog.addMessage("Match color of Target film to Source film:")
Dialog.addChoice("Save Target Output Image Sequence As:", newArray("tif", "bmp", "png", "jpeg"), "tif");
//Dialog.addChoice("Save Source Image Sequence As:", newArray("tif", "bmp", "png", "jpeg"), "tif");
Dialog.addString("Prefix text to Output Image Sequence:", "Target");
//Dialog.addString("Prefix text to Source Image Sequence:", "Source");
Dialog.addChoice("Target File Type:", newArray("AVI", "Using FFmpeg", "Image Sequence"), "AVI");
Dialog.addChoice("Source File Type:", newArray("AVI", "Using FFmpeg", "Image Sequence"), "AVI");
//Dialog.addCheckbox("Enable Colormatching", false);
//Dialog.addChoice("Colormatching Direction:", newArray("Source->Target", "Target->Source"), "Source->Target");
Dialog.show()
totype=Dialog.getChoice();
//sotype=Dialog.getChoice();
TPT=Dialog.getString();
SPT="source"//Dialog.getString();
TFT=Dialog.getChoice();
SFT=Dialog.getChoice();
//CM=Dialog.getCheckbox();
//CMD=Dialog.getChoice();
Targetpath = File.openDialog("Select Target File (This file will be colormatched to the source file:");
Sourcepath = File.openDialog("Select Source File:");
outputtargetdir = getDirectory("Choose output folder for color matched TARGET image sequence files:");
//outputsourcedir = getDirectory("Choose output folder for registered SOURCE image sequence files:");
outputlandmarkdir = getDirectory("Choose output folder for Landmark files:");
run(TFT+"...", "open=["+Targetpath+"] sort use");
rename("target");
slices=nSlices();
run(SFT+"...", "open=["+Sourcepath+"] sort use]");
rename("source");

//Search for first frame that contains enough detail for a good transform.
//If colormatching is true, this loop will also ask for user input to confirm cropping.
setBatchMode(true);
var done = false; // used to prematurely terminate loop
for (j=1; j<=slices && !done; j++) {
targetname=TPT+"-"+pad(j);
   sourcename=SPT+"-"+pad(j);
   selectWindow("target");
setSlice(j);
run("Make Substack...", "slices=" +j);
selectWindow("Substack ("+j+")");
   rename(targetname);
   selectWindow("source");
   setSlice(j);
   run("Make Substack...", "slices=" +j);
   selectWindow("Substack ("+j+")");
   rename(sourcename);
   getStatistics(area,mean);
run("Extract SIFT Correspondences", "source_image=["+sourcename+"] target_image=["+targetname+"] initial_gaussian_blur=1.60 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.2 minimal_number_of_inliers=30 expected_transformation=Affine");
   selectWindow(sourcename);
stype0=selectionType();
selectWindow(targetname);
stype1=selectionType();
   if (stype0 & stype1 == 10 && mean > 32) {
    done=true; //terminate the loop
   } else {
close(sourcename);
close(targetname);
   }
}
setBatchMode("exit and display");
//Save the initial transform.
selectWindow(sourcename);
saveAs("Selection", outputlandmarkdir + "source.roi");
selectWindow(targetname);
saveAs("Selection", outputlandmarkdir + "target.roi");
run("Landmark Correspondences", "source_image=["+sourcename+"] template_image=["+targetname+"] transformation_method=[Least Squares] alpha=1 mesh_resolution=32 transformation_class=Affine interpolate");
close(sourcename);
selectWindow("Transformed"+sourcename);
rename(sourcename);
imageCalculator("Multiply create", targetname,sourcename);
setTool("rectangle");
waitForUser("Cropping","Use the Rectangle tool to draw a selection inside the colored/white box\n to crop Target and Source to common active image area.\nMake the selection a bit smaller than the white box to account for gate weave, etc.\nPress OK when finished.\nThe macro will enter batch mode and exit when finished.");
saveAs("Selection", outputlandmarkdir + "cropping.roi");
selectWindow("target");
setSlice(1);
setLocation(0,0,360,240);
selectWindow("source");
setSlice(1);
setLocation(0,241,360,240);
selectWindow("Log");
setLocation(0,481);
close(targetname);
close(sourcename);
close("Result of "+targetname);
setBatchMode(true);
//Start Registration from beginning of clip using initial transform found above as anchor if needed.
//Saves last known good set of correspondences and uses them on frames that have none.
for (i=1; i<=slices; i++) {
showProgress(i,slices);
targetname1=TPT+"-"+pad(i);
sourcename1=SPT+"-"+pad(i);
selectWindow("target");
setSlice(i);
run("Make Substack...", "slices=" +i);
selectWindow("Substack ("+i+")");
rename(targetname1);
selectWindow("source");
setSlice(i);
run("Make Substack...", "slices=" +i);
selectWindow("Substack ("+i+")");
rename(sourcename1);
run("Extract SIFT Correspondences", "source_image=["+sourcename1+"] target_image=["+targetname1+"] initial_gaussian_blur=1.60 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=20 expected_transformation=Affine");
selectWindow(sourcename1);
stype2=selectionType();
selectWindow(targetname1);
stype3=selectionType();
if (stype2 & stype3 == 10) {
selectWindow(sourcename1);
saveAs("Selection", outputlandmarkdir + "source.roi");
selectWindow(targetname1);
saveAs("Selection", outputlandmarkdir + "target.roi");
    run("Landmark Correspondences", "source_image=["+sourcename1+"] template_image=["+targetname1+"] transformation_method=[Least Squares] alpha=1 mesh_resolution=32 transformation_class=Affine interpolate");
close(sourcename1);
selectWindow("Transformed"+sourcename1);
rename(sourcename1);
selectWindow(sourcename1);
open(outputlandmarkdir + "cropping.roi");
setBackgroundColor(0, 0, 0);
run("Clear Outside");
run("Select None");
selectWindow(targetname1);
open(outputlandmarkdir + "cropping.roi");
setBackgroundColor(0, 0, 0);
run("Clear Outside");
run("Select None");
selectWindow(targetname1);
run("Split Channels");
selectWindow(sourcename1);
run("Split Channels");
run("Concatenate...", "  title=red image1=["+sourcename1+" (red)] image2=["+targetname1+" (red)] image3=[-- None --]");
run("Concatenate...", "  title=green image1=["+sourcename1+" (green)] image2=["+targetname1+" (green)] image3=[-- None --]");
run("Concatenate...", "  title=blue image1=["+sourcename1+" (blue)] image2=["+targetname1+" (blue)] image3=[-- None --]");
selectWindow("red");
run("Bleach Correction", "correction=[Histogram Matching]");
selectWindow("green");
run("Bleach Correction", "correction=[Histogram Matching]");
selectWindow("blue");
run("Bleach Correction", "correction=[Histogram Matching]");
close("red");
close("green");
close("blue");
selectWindow("DUP_red");
run("Stack to Images");
selectWindow("DUP_green");
run("Stack to Images");
selectWindow("DUP_blue");
run("Stack to Images");
run("Concatenate...", "  title=newsource image1=DUP_red-0001 image2=DUP_green-0001 image3=DUP_blue-0001 image4=[-- None --]");
run("Concatenate...", "  title=newtarget image1=DUP_red-0002 image2=DUP_green-0002 image3=DUP_blue-0002 image4=[-- None --]");
selectWindow("newtarget");
run("Stack to RGB");
close("newtarget");
selectWindow("newsource");
run("Stack to RGB");
close("newsource");
selectWindow("newtarget (RGB)");
rename(targetname1);
saveAs(totype, outputtargetdir + targetname1);
close(targetname1+"."+totype);
selectWindow("newsource (RGB)");
rename(sourcename1);
//saveAs(sotype, outputsourcedir + sourcename1);
close(sourcename1);//+"."+sotype);
} else {
selectWindow(sourcename1);
open(outputlandmarkdir + "source.roi");
selectWindow(targetname1);
open(outputlandmarkdir + "target.roi");
run("Landmark Correspondences", "source_image=["+sourcename1+"] template_image=["+targetname1+"] transformation_method=[Least Squares] alpha=1 mesh_resolution=32 transformation_class=Affine interpolate");
close(sourcename1);
selectWindow("Transformed"+sourcename1);
rename(sourcename1);
selectWindow(sourcename1);
open(outputlandmarkdir + "cropping.roi");
setBackgroundColor(0, 0, 0);
run("Clear Outside");
run("Select None");
selectWindow(targetname1);
open(outputlandmarkdir + "cropping.roi");
setBackgroundColor(0, 0, 0);
run("Clear Outside");
run("Select None");
selectWindow(targetname1);
run("Split Channels");
selectWindow(sourcename1);
run("Split Channels");
run("Concatenate...", "  title=red image1=["+sourcename1+" (red)] image2=["+targetname1+" (red)] image3=[-- None --]");
run("Concatenate...", "  title=green image1=["+sourcename1+" (green)] image2=["+targetname1+" (green)] image3=[-- None --]");
run("Concatenate...", "  title=blue image1=["+sourcename1+" (blue)] image2=["+targetname1+" (blue)] image3=[-- None --]");
selectWindow("red");
run("Bleach Correction", "correction=[Histogram Matching]");
selectWindow("green");
run("Bleach Correction", "correction=[Histogram Matching]");
selectWindow("blue");
run("Bleach Correction", "correction=[Histogram Matching]");
close("red");
close("green");
close("blue");
selectWindow("DUP_red");
run("Stack to Images");
selectWindow("DUP_green");
run("Stack to Images");
selectWindow("DUP_blue");
run("Stack to Images");
run("Concatenate...", "  title=newsource image1=DUP_red-0001 image2=DUP_green-0001 image3=DUP_blue-0001 image4=[-- None --]");
run("Concatenate...", "  title=newtarget image1=DUP_red-0002 image2=DUP_green-0002 image3=DUP_blue-0002 image4=[-- None --]");
selectWindow("newtarget");
run("Stack to RGB");
close("newtarget");
selectWindow("newsource");
run("Stack to RGB");
close("newsource");
selectWindow("newtarget (RGB)");
rename(targetname1);
saveAs(totype, outputtargetdir + targetname1);
close(targetname1+"."+totype);
selectWindow("newsource (RGB)");
rename(sourcename1);
//saveAs(sotype, outputsourcedir + sourcename1);
close(sourcename1);//+"."+sotype);
}
print("\\Clear");
//run("Collect Garbage");
call("java.lang.System.gc");
}

setBatchMode(false);
close("*");
//run("Collect Garbage");
call("java.lang.System.gc");
beep();
waitForUser("The color matching macro is finished.");

function pad(n) {
    str = toString(n);
    while (lengthOf(str)<6)
    str = "0" + str;
    return str;
}

Macro for Color Matching V2
Code:
Dialog.create("Fast Film Registration with optional Colormatching");
Dialog.addMessage("Register Source film to Target film")
Dialog.addChoice("Save Target Image Sequence As:", newArray("tif", "bmp", "png", "jpeg"), "tif");
Dialog.addChoice("Save Source Image Sequence As:", newArray("tif", "bmp", "png", "jpeg"), "tif");
Dialog.addString("Prefix text to Target Image Sequence:", "Target");
Dialog.addString("Prefix text to Source Image Sequence:", "Source");
Dialog.addChoice("Target File Type:", newArray("AVI", "Using FFmpeg", "Image Sequence"), "AVI");
Dialog.addChoice("Source File Type:", newArray("AVI", "Using FFmpeg", "Image Sequence"), "AVI");
Dialog.addCheckbox("Enable Colormatching", false);
Dialog.addChoice("Colormatching Direction:", newArray("Source->Target", "Target->Source"), "Source->Target");
Dialog.show()
totype=Dialog.getChoice();
sotype=Dialog.getChoice();
TPT=Dialog.getString();
SPT=Dialog.getString();
TFT=Dialog.getChoice();
SFT=Dialog.getChoice();
CM=Dialog.getCheckbox();
CMD=Dialog.getChoice();
Targetpath = File.openDialog("Select Target File");
Sourcepath = File.openDialog("Select Source File (this file will be deformed to match the Target File)");
outputtargetdir = getDirectory("Choose output folder for registered TARGET image sequence files:");
outputsourcedir = getDirectory("Choose output folder for registered SOURCE image sequence files:");
outputlandmarkdir = getDirectory("Choose output folder for Landmark files:");
run(TFT+"...", "open=["+Targetpath+"] sort use");
rename("target");
slices=nSlices();
run(SFT+"...", "open=["+Sourcepath+"] sort use]");
rename("source");

//Search for first frame that contains enough detail for a good transform.
//If colormatching is true, this loop will also ask for user input to confirm cropping.
setBatchMode(true);
var done = false; // used to prematurely terminate loop
for (j=1; j<=slices && !done; j++) {
targetname=TPT+"-"+pad(j);
   sourcename=SPT+"-"+pad(j);
   selectWindow("target");
setSlice(j);
run("Make Substack...", "slices=" +j);
selectWindow("Substack ("+j+")");
   rename(targetname);
   selectWindow("source");
   setSlice(j);
   run("Make Substack...", "slices=" +j);
   selectWindow("Substack ("+j+")");
   rename(sourcename);
   getStatistics(area,mean);
run("Extract SIFT Correspondences", "source_image=["+sourcename+"] target_image=["+targetname+"] initial_gaussian_blur=1.60 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.2 minimal_number_of_inliers=30 expected_transformation=Affine");
   selectWindow(sourcename);
stype0=selectionType();
selectWindow(targetname);
stype1=selectionType();
   if (stype0 & stype1 == 10 && mean > 32) {
    done=true; //terminate the loop
   } else {
close(sourcename);
close(targetname);
   }
}
setBatchMode("exit and display");
//Save the initial transform.
selectWindow(sourcename);
saveAs("Selection", outputlandmarkdir + "source.roi");
selectWindow(targetname);
saveAs("Selection", outputlandmarkdir + "target.roi");
run("Landmark Correspondences", "source_image=["+sourcename+"] template_image=["+targetname+"] transformation_method=[Least Squares] alpha=1 mesh_resolution=32 transformation_class=Affine interpolate");
close(sourcename);
selectWindow("Transformed"+sourcename);
rename(sourcename);
imageCalculator("Multiply create", targetname,sourcename);
setTool("rectangle");
waitForUser("Cropping","Use the Rectangle tool to draw a selection inside the white box\n to crop Target and Source to common active image area.\nMake the selection a bit smaller than the white box to account for gate weave, etc.\nPress OK when finished.\nThe macro will enter batch mode and exit when finished.");
saveAs("Selection", outputlandmarkdir + "cropping.roi");
selectWindow("target");
setSlice(1);
setLocation(0,0,360,240);
selectWindow("source");
setSlice(1);
setLocation(0,241,360,240);
selectWindow("Log");
setLocation(0,481);
close(targetname);
close(sourcename);
close("Result of "+targetname);
setBatchMode(true);
//Start Registration from beginning of clip using initial transform found above as anchor if needed.
//Saves last known good set of correspondences and uses them on frames that have none.
for (i=1; i<=slices; i++) {
showProgress(i,slices);
targetname1=TPT+"-"+pad(i);
sourcename1=SPT+"-"+pad(i);
selectWindow("target");
setSlice(i);
run("Make Substack...", "slices=" +i);
selectWindow("Substack ("+i+")");
rename(targetname1);
selectWindow("source");
setSlice(i);
run("Make Substack...", "slices=" +i);
selectWindow("Substack ("+i+")");
rename(sourcename1);
run("Extract SIFT Correspondences", "source_image=["+sourcename1+"] target_image=["+targetname1+"] initial_gaussian_blur=1.60 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=20 expected_transformation=Affine");
selectWindow(sourcename1);
stype2=selectionType();
selectWindow(targetname1);
stype3=selectionType();
if (stype2 & stype3 == 10) {
selectWindow(sourcename1);
saveAs("Selection", outputlandmarkdir + "source.roi");
selectWindow(targetname1);
saveAs("Selection", outputlandmarkdir + "target.roi");
    run("Landmark Correspondences", "source_image=["+sourcename1+"] template_image=["+targetname1+"] transformation_method=[Least Squares] alpha=1 mesh_resolution=32 transformation_class=Affine interpolate");
close(sourcename1);
selectWindow("Transformed"+sourcename1);
rename(sourcename1);
if (CM==false){
selectWindow(sourcename1);
open(outputlandmarkdir + "cropping.roi");
setBackgroundColor(0, 0, 0);
run("Clear Outside");
run("Select None");
saveAs(sotype, outputsourcedir + sourcename1);
close(sourcename1+"."+sotype);
selectWindow(targetname1);
open(outputlandmarkdir + "cropping.roi");
setBackgroundColor(0, 0, 0);
run("Clear Outside");
run("Select None");
saveAs(totype, outputtargetdir + targetname1);
close(targetname1+"."+totype);
} else if (CM==true && CMD=="Source->Target") {
selectWindow(sourcename1);
open(outputlandmarkdir + "cropping.roi");
setBackgroundColor(0, 0, 0);
run("Clear Outside");
run("Select None");
selectWindow(targetname1);
open(outputlandmarkdir + "cropping.roi");
setBackgroundColor(0, 0, 0);
run("Clear Outside");
run("Select None");
selectWindow(targetname1);
run("Split Channels");
selectWindow(sourcename1);
run("Split Channels");
run("Concatenate...", "  title=red image1=["+targetname1+" (red)] image2=["+sourcename1+" (red)] image3=[-- None --]");
run("Concatenate...", "  title=green image1=["+targetname1+" (green)] image2=["+sourcename1+" (green)] image3=[-- None --]");
run("Concatenate...", "  title=blue image1=["+targetname1+" (blue)] image2=["+sourcename1+" (blue)] image3=[-- None --]");
selectWindow("red");
run("Bleach Correction", "correction=[Histogram Matching]");
selectWindow("green");
run("Bleach Correction", "correction=[Histogram Matching]");
selectWindow("blue");
run("Bleach Correction", "correction=[Histogram Matching]");
close("red");
close("green");
close("blue");
selectWindow("DUP_red");
run("Stack to Images");
selectWindow("DUP_green");
run("Stack to Images");
selectWindow("DUP_blue");
run("Stack to Images");
run("Concatenate...", "  title=newtarget image1=DUP_red-0001 image2=DUP_green-0001 image3=DUP_blue-0001 image4=[-- None --]");
run("Concatenate...", "  title=newsource image1=DUP_red-0002 image2=DUP_green-0002 image3=DUP_blue-0002 image4=[-- None --]");
selectWindow("newtarget");
run("Stack to RGB");
close("newtarget");
selectWindow("newsource");
run("Stack to RGB");
close("newsource");
selectWindow("newtarget (RGB)");
rename(targetname1);
saveAs(totype, outputtargetdir + targetname1);
close(targetname1+"."+totype);
selectWindow("newsource (RGB)");
rename(sourcename1);
saveAs(sotype, outputsourcedir + sourcename1);
close(sourcename1+"."+sotype);// if (CM==true && CMD=="Target->Source")
} else {
selectWindow(sourcename1);
open(outputlandmarkdir + "cropping.roi");
setBackgroundColor(0, 0, 0);
run("Clear Outside");
run("Select None");
selectWindow(targetname1);
open(outputlandmarkdir + "cropping.roi");
setBackgroundColor(0, 0, 0);
run("Clear Outside");
run("Select None");
selectWindow(targetname1);
run("Split Channels");
selectWindow(sourcename1);
run("Split Channels");
run("Concatenate...", "  title=red image1=["+sourcename1+" (red)] image2=["+targetname1+" (red)] image3=[-- None --]");
run("Concatenate...", "  title=green image1=["+sourcename1+" (green)] image2=["+targetname1+" (green)] image3=[-- None --]");
run("Concatenate...", "  title=blue image1=["+sourcename1+" (blue)] image2=["+targetname1+" (blue)] image3=[-- None --]");
selectWindow("red");
run("Bleach Correction", "correction=[Histogram Matching]");
selectWindow("green");
run("Bleach Correction", "correction=[Histogram Matching]");
selectWindow("blue");
run("Bleach Correction", "correction=[Histogram Matching]");
close("red");
close("green");
close("blue");
selectWindow("DUP_red");
run("Stack to Images");
selectWindow("DUP_green");
run("Stack to Images");
selectWindow("DUP_blue");
run("Stack to Images");
run("Concatenate...", "  title=newsource image1=DUP_red-0001 image2=DUP_green-0001 image3=DUP_blue-0001 image4=[-- None --]");
run("Concatenate...", "  title=newtarget image1=DUP_red-0002 image2=DUP_green-0002 image3=DUP_blue-0002 image4=[-- None --]");
selectWindow("newtarget");
run("Stack to RGB");
close("newtarget");
selectWindow("newsource");
run("Stack to RGB");
close("newsource");
selectWindow("newtarget (RGB)");
rename(targetname1);
saveAs(totype, outputtargetdir + targetname1);
close(targetname1+"."+totype);
selectWindow("newsource (RGB)");
rename(sourcename1);
saveAs(sotype, outputsourcedir + sourcename1);
close(sourcename1+"."+sotype);
}
} else {
selectWindow(sourcename1);
open(outputlandmarkdir + "source.roi");
selectWindow(targetname1);
open(outputlandmarkdir + "target.roi");
run("Landmark Correspondences", "source_image=["+sourcename1+"] template_image=["+targetname1+"] transformation_method=[Least Squares] alpha=1 mesh_resolution=32 transformation_class=Affine interpolate");
close(sourcename1);
selectWindow("Transformed"+sourcename1);
rename(sourcename1);
if (CM==false){
selectWindow(sourcename1);
open(outputlandmarkdir + "cropping.roi");
setBackgroundColor(0, 0, 0);
run("Clear Outside");
run("Select None");
saveAs(sotype, outputsourcedir + sourcename1);
close(sourcename1+"."+sotype);
selectWindow(targetname1);
open(outputlandmarkdir + "cropping.roi");
setBackgroundColor(0, 0, 0);
run("Clear Outside");
run("Select None");
saveAs(totype, outputtargetdir + targetname1);
close(targetname1+"."+totype);
} else if (CM==true && CMD=="Source->Target") {
selectWindow(sourcename1);
open(outputlandmarkdir + "cropping.roi");
setBackgroundColor(0, 0, 0);
run("Clear Outside");
run("Select None");
selectWindow(targetname1);
open(outputlandmarkdir + "cropping.roi");
setBackgroundColor(0, 0, 0);
run("Clear Outside");
run("Select None");
selectWindow(targetname1);
run("Split Channels");
selectWindow(sourcename1);
run("Split Channels");
run("Concatenate...", "  title=red image1=["+targetname1+" (red)] image2=["+sourcename1+" (red)] image3=[-- None --]");
run("Concatenate...", "  title=green image1=["+targetname1+" (green)] image2=["+sourcename1+" (green)] image3=[-- None --]");
run("Concatenate...", "  title=blue image1=["+targetname1+" (blue)] image2=["+sourcename1+" (blue)] image3=[-- None --]");
selectWindow("red");
run("Bleach Correction", "correction=[Histogram Matching]");
selectWindow("green");
run("Bleach Correction", "correction=[Histogram Matching]");
selectWindow("blue");
run("Bleach Correction", "correction=[Histogram Matching]");
close("red");
close("green");
close("blue");
selectWindow("DUP_red");
run("Stack to Images");
selectWindow("DUP_green");
run("Stack to Images");
selectWindow("DUP_blue");
run("Stack to Images");
run("Concatenate...", "  title=newtarget image1=DUP_red-0001 image2=DUP_green-0001 image3=DUP_blue-0001 image4=[-- None --]");
run("Concatenate...", "  title=newsource image1=DUP_red-0002 image2=DUP_green-0002 image3=DUP_blue-0002 image4=[-- None --]");
selectWindow("newtarget");
run("Stack to RGB");
close("newtarget");
selectWindow("newsource");
run("Stack to RGB");
close("newsource");
selectWindow("newtarget (RGB)");
rename(targetname1);
saveAs(totype, outputtargetdir + targetname1);
close(targetname1+"."+totype);
selectWindow("newsource (RGB)");
rename(sourcename1);
saveAs(sotype, outputsourcedir + sourcename1);
close(sourcename1+"."+sotype);//if (CM==true && CMD=="Target->Source")
} else {
selectWindow(sourcename1);
open(outputlandmarkdir + "cropping.roi");
setBackgroundColor(0, 0, 0);
run("Clear Outside");
run("Select None");
selectWindow(targetname1);
open(outputlandmarkdir + "cropping.roi");
setBackgroundColor(0, 0, 0);
run("Clear Outside");
run("Select None");
selectWindow(targetname1);
run("Split Channels");
selectWindow(sourcename1);
run("Split Channels");
run("Concatenate...", "  title=red image1=["+sourcename1+" (red)] image2=["+targetname1+" (red)] image3=[-- None --]");
run("Concatenate...", "  title=green image1=["+sourcename1+" (green)] image2=["+targetname1+" (green)] image3=[-- None --]");
run("Concatenate...", "  title=blue image1=["+sourcename1+" (blue)] image2=["+targetname1+" (blue)] image3=[-- None --]");
selectWindow("red");
run("Bleach Correction", "correction=[Histogram Matching]");
selectWindow("green");
run("Bleach Correction", "correction=[Histogram Matching]");
selectWindow("blue");
run("Bleach Correction", "correction=[Histogram Matching]");
close("red");
close("green");
close("blue");
selectWindow("DUP_red");
run("Stack to Images");
selectWindow("DUP_green");
run("Stack to Images");
selectWindow("DUP_blue");
run("Stack to Images");
run("Concatenate...", "  title=newsource image1=DUP_red-0001 image2=DUP_green-0001 image3=DUP_blue-0001 image4=[-- None --]");
run("Concatenate...", "  title=newtarget image1=DUP_red-0002 image2=DUP_green-0002 image3=DUP_blue-0002 image4=[-- None --]");
selectWindow("newtarget");
run("Stack to RGB");
close("newtarget");
selectWindow("newsource");
run("Stack to RGB");
close("newsource");
selectWindow("newtarget (RGB)");
rename(targetname1);
saveAs(totype, outputtargetdir + targetname1);
close(targetname1+"."+totype);
selectWindow("newsource (RGB)");
rename(sourcename1);
saveAs(sotype, outputsourcedir + sourcename1);
close(sourcename1+"."+sotype);
}
}
print("\\Clear");
//run("Collect Garbage");
call("java.lang.System.gc");
}

setBatchMode(false);
close("*");
//run("Collect Garbage");
call("java.lang.System.gc");
beep();
waitForUser("The registration macro is finished.");

function pad(n) {
    str = toString(n);
    while (lengthOf(str)<6)
    str = "0" + str;
    return str;
}

Macro for Film Registration
Code:
Dialog.create("Register Film");
Dialog.addMessage("Register Source film to Target film")
Dialog.addChoice("Save Image Sequence As:", newArray("tif", "bmp", "png", "jpeg"));
Dialog.show()
type=Dialog.getChoice();
Targetpath = File.openDialog("Select Target File");
Sourcepath = File.openDialog("Select Source File (this file will be registered to the Target File)");
outputsourcedir = getDirectory("Choose output folder for SOURCE file:");
outputlandmarkdir = getDirectory("Choose output folder for Landmark files:");
run("Using FFmpeg...", "open=[" +Targetpath+ "]");
rename("target");
slices=nSlices();
run("Using FFmpeg...", "open=[" +Sourcepath+ "]");
rename("source");

//Search for first frame that contains enough detail for a good transform.
var done = false; // used to prematurely terminate loop
for (j=1; j<=slices && !done; j++) {
targetname="target-"+pad(j);
   sourcename="source-"+pad(j);
   selectWindow("target");
setSlice(j);
run("Make Substack...", "slices=" +j);
selectWindow("Substack ("+j+")");
   rename(targetname);
   selectWindow("source");
   setSlice(j);
   run("Make Substack...", "slices=" +j);
   selectWindow("Substack ("+j+")");
   rename(sourcename);
   run("Extract SIFT Correspondences", "source_image=["+sourcename+"] target_image=["+targetname+"] initial_gaussian_blur=1.60 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.2 minimal_number_of_inliers=100 expected_transformation=Affine");
   selectWindow(sourcename);
stype0=selectionType();
selectWindow(targetname);
stype1=selectionType();
   if (stype0 & stype1 == 10) {
    done=true; //terminate the loop
   }
else {
   close(sourcename);
   close(targetname);
   }
}
//Save the initial transform.
selectWindow(sourcename);
saveAs("Selection", outputlandmarkdir + "source.roi");
//Roi.setName(source);
//roiManager("add"); //index 0
selectWindow(targetname);
saveAs("Selection", outputlandmarkdir + "target.roi");
//Roi.setName(target);
//roiManager("add"); //index 1
run("Landmark Correspondences", "source_image=["+sourcename+"] template_image=["+targetname+"] transformation_method=[Least Squares] alpha=1 mesh_resolution=32 transformation_class=Affine interpolate");
close(sourcename);
selectWindow("Transformed"+sourcename);
rename(sourcename);
run("Extract SIFT Correspondences", "source_image=["+sourcename+"] target_image=["+targetname+"] initial_gaussian_blur=1.60 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=50 expected_transformation=Affine");
selectWindow(sourcename);
saveAs("Selection", outputlandmarkdir + "newsource.roi");
//Roi.setName(newsource);
//roiManager("add"); //index 2
selectWindow(targetname);
saveAs("Selection", outputlandmarkdir + "newtarget.roi");
//Roi.setName(newtarget);
//roiManager("add"); //index 3
run("bUnwarpJ", "source_image=["+sourcename+"] target_image=["+targetname+"] registration=Mono image_subsample_factor=0 initial_deformation=Coarse final_deformation=Fine divergence_weight=0 curl_weight=0 landmark_weight=1 image_weight=0 consistency_weight=0 stop_threshold=0.01");
selectWindow("target");
setSlice(1);
selectWindow("source");
setSlice(1);
close("Registered Source Image");
close(targetname);
close(sourcename);

//Start Registration from beginning of clip using initial transform found above as anchor if needed.
for (i=1; i<=slices; i++) {
showProgress(i,slices);
targetname1="target-"+pad(i);
sourcename1="source-"+pad(i);
selectWindow("target");
setSlice(i);
run("Make Substack...", "slices=" +i);
selectWindow("Substack ("+i+")");
rename(targetname1);
selectWindow("source");
setSlice(i);
run("Make Substack...", "slices=" +i);
selectWindow("Substack ("+i+")");
rename(sourcename1);
run("Extract SIFT Correspondences", "source_image=["+sourcename1+"] target_image=["+targetname1+"] initial_gaussian_blur=1.60 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=50 expected_transformation=Affine");
selectWindow(sourcename1);
stype2=selectionType();
selectWindow(targetname1);
stype3=selectionType();
if (stype2 & stype3 == 10) {
selectWindow(sourcename1);
print("save source roi");
saveAs("Selection", outputlandmarkdir + "source.roi");
selectWindow(targetname1);
print("save target roi");
saveAs("Selection", outputlandmarkdir + "target.roi");
    run("Landmark Correspondences", "source_image=["+sourcename1+"] template_image=["+targetname1+"] transformation_method=[Least Squares] alpha=1 mesh_resolution=32 transformation_class=Affine interpolate");
close(sourcename1);
selectWindow("Transformed"+sourcename1);
rename(sourcename1);
run("Extract SIFT Correspondences", "source_image=["+sourcename1+"] target_image=["+targetname1+"] initial_gaussian_blur=1.60 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=10 expected_transformation=Affine");
selectWindow(sourcename1);
print("save newsource roi");
saveAs("Selection", outputlandmarkdir + "newsource.roi");
selectWindow(targetname1);
print("save newtarget roi");
saveAs("Selection", outputlandmarkdir + "newtarget.roi");
run("bUnwarpJ", "source_image=["+sourcename1+"] target_image=["+targetname1+"] registration=Mono image_subsample_factor=0 initial_deformation=Coarse final_deformation=Fine divergence_weight=0 curl_weight=0 landmark_weight=1 image_weight=0 consistency_weight=0 stop_threshold=0.01");
selectWindow("Registered Source Image");
run("Stack to Images");
close("Warped Source Mask");
close("Target Image");
close(sourcename1);
selectWindow("Registered Source Image");
saveAs(type, outputsourcedir + sourcename1);
close();
close(targetname1);
}
else {
roiManager("Open", outputlandmarkdir + "source.roi");
roiManager("Open", outputlandmarkdir + "target.roi");
selectWindow(sourcename1);
roiManager("select",0);
selectWindow(targetname1);
roiManager("select",1);
run("Landmark Correspondences", "source_image=["+sourcename1+"] template_image=["+targetname1+"] transformation_method=[Least Squares] alpha=1 mesh_resolution=32 transformation_class=Affine interpolate");
close(sourcename1);
selectWindow("Transformed"+sourcename1);
rename(sourcename1);
//run("Extract SIFT Correspondences", "source_image=["+sourcename1+"] target_image=["+targetname1+"] initial_gaussian_blur=0.60 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");
roiManager("reset");
roiManager("Open", outputlandmarkdir + "newsource.roi");
roiManager("Open", outputlandmarkdir + "newtarget.roi");
selectWindow(sourcename1);
roiManager("select",0);
selectWindow(targetname1);
roiManager("select",1);
run("bUnwarpJ", "source_image=["+sourcename1+"] target_image=["+targetname1+"] registration=Mono image_subsample_factor=0 initial_deformation=Coarse final_deformation=Fine divergence_weight=0 curl_weight=0 landmark_weight=1 image_weight=0 consistency_weight=0 stop_threshold=0.01");
selectWindow("Registered Source Image");
run("Stack to Images");
close("Warped Source Mask");
close("Target Image");
close(sourcename1);
selectWindow("Registered Source Image");
saveAs(type, outputsourcedir + sourcename1);
close();
close(targetname1);
close("ROI Manager");
}
print("\\Clear");
//run("Collect Garbage");
call("java.lang.System.gc");
}

//setBatchMode(false);
close("Roi Manager");
close("*");
//run("Collect Garbage");
call("java.lang.System.gc");
beep();
waitForUser("The registration macro is finished.");

function pad(n) {
    str = toString(n);
    while (lengthOf(str)<6)
    str = "0" + str;
    return str;
}

I've packaged all of this into a custom imagej zip. It relies on an existing java installation and if it can't find javaw, it will ask you where it is located. You can't download vanilla imagej packages and then use these macros as there are some custom plugins I've drawn from the interwebs that aren't a part of a normal installation.

Extract the ImageJ folder to the root of your C drive and run the executable to get it up and running.

Plugin tutorial link
I have changed the names of the plugins and such but you should get the idea.
The numbered plugins are the macros I've made. The rest are the plugins that the macros require to run.

Custom Imagej zip

I will keep this first post up to date with changes.
Reply
Thanks given by: PDB , williarob


Forum Jump:


Users browsing this thread: 1 Guest(s)