【问题标题】:Strange File Save Behavior with ImageJImageJ 的奇怪文件保存行为
【发布时间】:2015-06-04 18:49:04
【问题描述】:

我编写了一个 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;
    }
    }
}

【问题讨论】:

    标签: imagej


    【解决方案1】:

    不知道为什么我需要这样做,但在 saveAs() 之前添加 wait(100) 似乎可以解决问题

    【讨论】:

    • 这是由于运行 Merge Channelsrace condition。它必须在自己的线程上运行,所以有时它会在saveAs 之前完成,有时它不会。当你单步执行代码时,你总是给它时间来完成,所以你永远不会看到竞争条件出现。
    • wait(100) 不能保证始终有效(如果 Merge Channels 调用时间少于 100 毫秒,您可能会再次遇到此竞争条件)。在我的脑海中,最简单的事情就是投票IJ.macroRunning()。所以在你的run("Merge Channels..." ..) 行之后,放while(IJ.macroRunning()) { /* Wait for macro to end */ }。我相信那应该更安全。
    • @hinerm 谢谢。如果您想将此作为自己的答案,我将删除关于等待(100)的我的答案。最后一个问题,等待宏结束的语法是什么?会不会只是 'wait(run("Merge Channels ..."))' ?
    • 这种方式真的没办法使用wait()。在实际运行之前,您必须知道“合并通道”的运行时间,并将该值传递给wait()。所以你被卡住了 - 我在我的答案中放了示例语法。如果不清楚,请告诉我。
    • 有没有办法在基本的 imageJ 宏语言中应用这个?
    【解决方案2】:

    这种情况下的最佳做法是轮询IJ.macroRunning()。如果宏正在运行,此方法将返回 true。我建议使用最终会超时的辅助方法,例如:

    /** Run with default timeout of 30 seconds */
    public boolean waitForMacro() {
      return waitForMacro(30000);
    }
    
    /**
     * @return True if no macro was running. False if a macro runs for longer than
     *         the specified timeOut value.
     */
    public boolean waitForMacro(final long timeOut) {
        final long time = System.currentTimeMillis();
    
        while (IJ.macroRunning()) {
            // Time out after 30 seconds.
            if (System.currentTimeMillis() - time > timeOut) return false;
        }
    
        return true;
    }
    

    然后在您使用run()open()newImage() 时调用这些辅助方法之一。

    另一个可能需要更多工作但提供更强大解决方案的方向是使用ImageJ2。然后你可以用ThreadService 运行东西,这会给你一个Java Future,然后可以保证执行完成。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-08
      • 1970-01-01
      • 2017-08-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多