【问题标题】:ImageJ (plugin Java): auto threshold method doesn't workImageJ(插件Java):自动阈值方法不起作用
【发布时间】:2015-09-07 23:12:18
【问题描述】:

我尝试将 Java 插件写入 ImageJ,应该:

  • 加载图像(24 位)。
  • 做一些预处理操作。
  • 用多种方法对图像进行阈值处理。
  • 做一些其他的操作。

阈值操作有问题。我的部分代码如下所示:

Opener opener = new Opener();
ImagePlus imp = opener.openImage(source);
// Preprocessing
IJ.run("Threshold..." , method);
// Other operations e.g. "open", "outline" etc.
IJ.saveAs(destination);

我的目标是通过各种方法(例如“Default”、“Huang”、“Intermodes”、“IsoData”、“Li”等)获得二值化图像。 我可以获得二值化图像的唯一方法是运行:

IJ.run(imp, "8-bit", "");
IJ.run(imp, "Make Binary", "");

但是,我只用一种方法二值化了图像。 如何通过运行Java代码(ImageJ插件)做自动阈值?

【问题讨论】:

  • 这不能回答问题:也许你应该 openImaj (openimaj.org) 试一试。有一些关于阈值的方法。

标签: java image-processing imagej


【解决方案1】:

Threshold dialog 中的自动阈值方法都是处理单通道(8 位或 16 位)图像的算法。在Color Threshold 对话框中,它们专门应用于 24 位彩色图像的 亮度 通道。

要在 Java 中重现这一点,请使用以下代码:

IJ.run(imp, "HSB Stack", "");
imp.setSlice(3);
IJ.setAutoThreshold(imp, "Triangle dark");
Prefs.blackBackground = true;
IJ.run(imp, "Convert to Mask", "only");

(将图像转换为 8 位无非就是使用 Brightness 通道,丢弃色相和饱和度信息。除非你真的使用 Color Threshold 中的其他滑块 对话框,您也可以在应用阈值之前将图像转换为 8 位。)

【讨论】:

  • 您的代码看起来是正确的,但是当我更改方法(例如 method=IsoData、method=Huang 等)时,我总是得到结果,因为我使用“默认”方法。
  • 代码缺少IJ.setAutoThreshold 调用。我相应地编辑了我的答案。显然,在“转换为掩码”对话框中选择的方法被忽略了,这可能是一个错误:您可以通过菜单中的 Help > Report a bug 报告此问题。
【解决方案2】:

您似乎错误地使用了IJ.run 方法。第一个参数是一个包含 ImageJ 命令的字符串,第二个参数是一个包含此命令选项的字符串。来自文档:

public static void run(java.lang.String 命令, java.lang.String 选项)

运行一个 ImageJ 命令,带有传递给 GenericDialog 和 OpenDialog 类。不返回,直到 命令已完成执行。要生成 run() 调用,请启动 记录器(插件/宏/记录)并从 ImageJ 菜单运行命令 吧。

您还可以使用 GUI 录制宏,Plugins->Macros->Record...将录制模式设置为 Java,并选择所需的方法和阈值。你会得到这样的东西:

// Color Thresholder 1.49i
// Autogenerated macro, single images only!
min=newArray(3);
max=newArray(3);
filter=newArray(3);
a=getTitle();
run("HSB Stack");
run("Convert Stack to Images");
selectWindow("Hue");
rename("0");
selectWindow("Saturation");
rename("1");
selectWindow("Brightness");
rename("2");
min[0]=139;
max[0]=254;
filter[0]="pass";
min[1]=48;
max[1]=110;
filter[1]="pass";
min[2]=189;
max[2]=255;
filter[2]="pass";
for (i=0;i<3;i++){
  selectWindow(""+i);
  setThreshold(min[i], max[i]);
  run("Convert to Mask");
  if (filter[i]=="stop")  run("Invert");
}
imageCalculator("AND create", "0","1");
imageCalculator("AND create", "Result of 0","2");
for (i=0;i<3;i++){
  selectWindow(""+i);
  close();
}
selectWindow("Result of 0");
close();
selectWindow("Result of Result of 0");
rename(a);
// Colour Thresholding-----------------

【讨论】:

  • 注意,Threshold Color插件记录的代码是宏代码,不是Java。但是,如果先将 RGB 图像转换为 8 位,或者通过 Image > Color > Split Channels 拆分通道,则可以使用刻录机获取有效的 Java 代码。
  • @JanEglinger 你说得对,上面的代码不是 Java 代码——在这种情况下它没有用。如果我将图像更改为 8 位,我会丢失部分信息。如果我拆分频道怎么办?我可以像使用 24 位图像一样有效地进行二值化吗?
  • Ortomala Lokni - 我的代码(修改后)来自“插件->宏->记录...”。记录的阈值方法是:"//IJ.run("Threshold...");"。正如您在开头看到的那样,有“//”(Java 注释符号)——可能是因为在“阈值颜色”窗口中没有“确定”或“应用”之类的选项。我不知道什么是 24 位图像的正确阈值命令形式。
  • @JanEglinger 我按照您的建议拆分了频道。我在 8 位图像上使用阈值方法时正在查看宏记录。有 Java 方法:"IJ.setAutoThreshold(imp, "Li dark")" 它适用于 8 位图像。我正在寻找 24 位图像的类似方法。
  • @trojek 如果您将记录模式设置为Java,您将获得有效的Java 代码。我的答案中的代码是有效的 java 代码。所有方法都是IJ class 的静态方法。你只需要像这样进行静态导入:import static ij.IJ.*
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-08
  • 2010-11-13
  • 2018-06-04
  • 2016-01-21
  • 1970-01-01
相关资源
最近更新 更多