Я написал сценарий imageJ для цветного изображения и слияния ряда черно-белых изображений. Сценарий сохраняет как немигаемые цветные изображения, так и объединенные цветные изображения. Все работает красиво, когда я работаю в режиме отладки и просматриваю скрипт. Однако, когда я запускаю его по-настоящему, он иногда сохраняет пару оригинальных черных и белых вместо результирующего цветного изображения. Все объединенные изображения выглядят нормально.Strange File Save Behavior with ImageJ
Почему все работает нормально в режиме отладки, но не работает при регулярном использовании?
Ниже мой код:
// Choose the directory with the images
dir = getDirectory("Choose a Directory ");
// Get a list of everything in the directory
list = getFileList(dir);
// Determine if a composite directory exists. If not create one.
if (File.exists(dir+"/composite") == 0) {
File.makeDirectory(dir+"/composite")
}
// Determine if a colored directory exists. If not create one.
if (File.exists(dir+"/colored") == 0) {
File.makeDirectory(dir+"/colored")
}
// Close all files currently open to be safe
run("Close All");
// Setup options
setOption("display labels", true);
setBatchMode(false);
// Counter 1 keeps track of if you're on the first or second image of the tumor/vessel pair
count = 1;
// Counter 2 keeps track of the number of pairs in the folder
count2 = 1;
// Default Radio Button State
RadioButtonDefault = "Vessel";
// Set Default SatLevel for Contrast Adjustment
// The contrast adjustment does a histogram equalization. The Sat Level is a percentage of pixels that are allowed to saturate. A larger number means more pixels can saturate making the image appear brighter.
satLevelDefault = 2.0;
// For each image in the list
for (i=0; i<list.length; i++) {
// As long as the name doesn't end with/or .jpg
if (endsWith(list[i], ".tif")) {
// Define the full path to the filename
fn = list[i];
path = dir+list[i];
// Open the file
open(path);
// Create a dialog box but don't show it yet
Dialog.create("Image Type");
Dialog.addRadioButtonGroup("Type:", newArray("Vessel", "Tumor"), 1, 2, RadioButtonDefault)
Dialog.addNumber("Image Brightness Adjustment", satLevelDefault, 2, 4, "(applied only to vessel images)")
// If it's the first image of the pair ...
if (count == 1) {
// Show the dialog box
Dialog.show();
// Get the result and put it into a new variable and change the Default Radio Button State for the next time through
if (Dialog.getRadioButton=="Vessel") {
imgType = "Vessel";
RadioButtonDefault = "Tumor";
} else {
imgType = "Tumor";
RadioButtonDefault = "Vessel";
}
// If it's the second image of the pair
} else {
// And the first image was a vessel assume the next image is a tumor
if (imgType=="Vessel") {
imgType="Tumor";
// otherwise assume the next image is a vessel
} else {
imgType="Vessel";
}
}
// Check to see the result of the dialog box input
// If vessel do this
if (imgType=="Vessel") {
// Make image Red
run("Red");
// Adjust Brightness
run("Enhance Contrast...", "saturated="+Dialog.getNumber+" normalize");
// Strip the .tif off the existing filename to use for the new filename
fnNewVessel = replace(fn,"\\.tif","");
// Save as jpg
saveAs("Jpeg", dir+"/colored/"+ fnNewVessel+"_colored");
// Get the title of the image for the merge
vesselTitle = getTitle();
// Othersie do this ...
} else {
// Make green
run("Green");
// Strip the .tif off the existing filename to use for the new filename
fnNewTumor = replace(fn,"\\.tif","");
// Save as jpg
saveAs("Jpeg", dir+"/colored/"+ fnNewTumor+"_colored");
// Get the title of the image for the merge
tumorTitle = getTitle();
}
// If it's the second in the pair ...
if (count == 2) {
// Merge the two images
run("Merge Channels...", "c1="+vesselTitle+" c2="+tumorTitle+" create");
// Save as Jpg
saveAs("Jpeg", dir+"/composite/composite_"+count2);
// Reset the number within the pair counter
count = count-1;
// Increment the number of pairs counter
count2 = count2+1;
// Otherwise
} else {
// Increment the number within the pair counter
count += 1;
}
}
}
Это связано с [условиями гонки] (http://stackoverflow.com/questions/34510/what-is-a-race-condition) с запуском 'Merge Channels'. Он должен работать на своем потоке, поэтому иногда он заканчивается до 'saveAs', а иногда и нет. Когда вы переходите через код, вы всегда даете ему время, чтобы завершить, чтобы вы никогда не видели, что состояние гонки появляется. – hinerm
'wait (100)' не гарантируется, что он всегда будет работать (если вызов «Объединить каналы» занимает менее 100 мс, вы можете снова поразить это состояние гонки). В верхней части моей головы легче всего было бы опросить 'IJ.macroRunning()'. Итак, после вашего 'run (« Объединить каналы ... »..)' line, put 'while (IJ.macroRunning()) {/ * Дождаться завершения макроса * /}'. Полагаю, это должно быть безопаснее. – hinerm
@hinerm спасибо. Если вы хотите сделать это своим собственным ответом, я удалю шахту о выжидании (100). Последний вопрос: какой синтаксис ждет завершения макроса? Будет ли это просто «ждать (запустить (« Объединить каналы ... »))?? – agf1997