ImageJ 亮度和亮度一堆图像的对比

发布于 2024-10-07 20:07:42 字数 359 浏览 4 评论 0原文

我正在查看 ImageJ 中的图像数据集(一堆 .tif 图像,大约 130 帧),并且该数据集有问题。这是一系列显微镜图像,每一帧都是一个比前一帧高/低约 3-4 微米的平面。当我深入研究数据集时,光散射使背景变得更亮,因此样本的主要特征变得更暗。

然而,ImageJ 的亮度和对比度功能使用表示整个图像堆栈的直方图。当我在堆栈深处的图像上单击“自动”和“重置”时,产生的对比度非常完美:所有功能都照亮得非常好。然而,回到堆栈的开始,大多数功能已经饱和。

我尝试从堆栈中的各个点手动提取一些图像,并在亮度和亮度中执行自动->重置。单独对比每一个,然后将它们重新转换为一堆,看起来非常可靠。如何以编程方式(例如使用插件)对整个堆栈执行此操作?相关的API调用有哪些?

I'm looking through a dataset set of images in ImageJ (a stack of .tif images, about 130 frames), and I have a problem with the dataset. It's a series of microscope images, with each frame being a plane about 3-4 micrometers above/below the previous one. As I go deeper into the dataset, light scattering makes for a brighter background, so the main features of the specimen are dimmer.

However, ImageJ's brightness and contrast feature uses a histogram that represents the entire stack of images. When I click "Auto" and "Reset" on an image deep in the stack, the resulting contrast is perfect: all the features light up really well. However, then, back at the start of the stack, most of the features have become saturated.

I've tried manually extracting a few images from various points in the stack and performing Auto->Reset in Brightness & Contrast on each one individually and re-converting them to a stack afterwards, and it looks really solid. How can I do this programmatically (e.g. with a plugin) for the entire stack? What are the relevant API calls?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

懒的傷心 2024-10-14 20:07:42

开始编写此类脚本的一个好方法是使用 ImageJ 的宏记录器 - 您可以使用 Plugins > 来启动它。宏>记录...。对于此示例,我假设您已将 Record: 选项框切换为 JavaScript,但如果您更熟悉 ImageJ 宏语言或编写插件在 Java 中,其他之一可能是更好的选择。如果您随后打开图像并使用 Image >;堆栈>设置 Slice ... 并选择(例如)切片 20,您应该看到:

imp.setSlice(20);

... 出现在记录器中。现在,如果您运行 Image >调整>亮度/对比度...并选择自动,您应该在记录器中看到这相当于运行增强对比度并保持0.35%的饱和像素。正如您所指出的,这样做的问题在于,这会调整整个堆栈的最小值和最大值,而不仅仅是该切片的最小值和最大值。但是,您可以通过运行 Process > 来运行具有不同选项的 Enhance Contrast。增强对比度。 ImageJ 文档 wiki 上有关该选项的部分解释说,如果如果您想要更改像素值而不是设置堆栈的最小值和最大值,则需要选择“标准化”选项。如果我选择这样做,宏记录器会记录:

imp.setSlice(20);
IJ.run(imp, "Enhance Contrast", "saturated=0.35 normalize");

...并且您应该看到只有切片 20 已更改。然后,您可以将其包装在一个循环中,在每个切片上运行相同的增强功能:(

var imp = IJ.getImage();
var n = imp.getStackSize();

for( var i = 0; i < n; ++i) {
    imp.setSlice(i+1);
    IJ.run(imp, "Enhance Contrast", "saturated=4 normalize");
}

如果您使用的是 Fiji,则脚本编辑器(例如通过 File > New > Script)是一个试验此类脚本的简单方法。)

当然,使用归一化选项确实会导致像素值发生改变,这意味着在这种情况下您将丢失信息,因此我不会将生成的堆栈用于定量结果。

我希望这有一些用处。

A good way to start to write such a script is to use ImageJ's macro recorder - you can start this with Plugins > Macros > Record .... For this example, I'm assuming that you've switched the Record: option box to JavaScript, but if you're more familiar with the ImageJ macro language or writing plugins in Java one of the others might be a better choice. If you then open your image and use Image > Stacks > Set Slice ... and select (say) slice 20, you should see:

imp.setSlice(20);

... appear in the recorder. Now if you run Image > Adjust > Brightness/Contrast... and select Auto, you should see in the recorder that that's the equivalent of running Enhance Contrast keeping 0.35% saturated pixels. The problem with this, as you've noted, is that this adjusts the minimum and maximum values for the entire stack rather than just that that slice. However, you can run Enhance Contrast with different options by running Process > Enhance Contrast. The section on that option on the ImageJ documentation wiki explains that if you want to change the pixel values rather than setting the minimum and maximum for the stack, you need to select the "Normalize" option. If I choose to do that instead, the macro recorder records:

imp.setSlice(20);
IJ.run(imp, "Enhance Contrast", "saturated=0.35 normalize");

... and you should see that only slice 20 has been altered. You can then wrap that in a loop that runs the same enhancement on every slice with:

var imp = IJ.getImage();
var n = imp.getStackSize();

for( var i = 0; i < n; ++i) {
    imp.setSlice(i+1);
    IJ.run(imp, "Enhance Contrast", "saturated=4 normalize");
}

(If you're using Fiji, then the Script Editor (e.g. via File > New > Script) is an easy way to experiment with such scripts.)

Of course, using the normalize option does result in the pixel values being altered, which means in this case that you're losing information, so I wouldn't use the resulting stack for quantitative results.

I hope that's of some use.

万水千山粽是情ミ 2024-10-14 20:07:42

您还可以考虑使用 CellProfiler 来处理图像。即使 CP 无法直接执行您想要执行的操作,您实际上也可以从 CP 运行 ImageJ 命令、插件和宏。

最简单的是,您可以创建一个仅包含 LoadImages 和 RunImageJ 的 CP 管道。

You might also consider using CellProfiler to process the images. Even if CP can't do exactly what you're trying to do directly, you can actually run ImageJ commands, plugins and macros from CP.

At the very simplest, you could create a CP pipeline that just has LoadImages and RunImageJ.

半枫 2024-10-14 20:07:42

接受的答案对于OP的问题来说是最好的,但是一个小的变体是如果您想根据特定数据的切片来更改亮度/对比度。

就我而言,我希望具有阈值效应,但阈值在堆栈的每个切片中都在变化。我去了几个不同的切片并手动找到了阈值。然后,我找到了阈值 (Tv) 的近似函数作为切片的函数,如下所示:

Tv=4000/s-17

因此,然后我的脚本变为:

importClass(Packages.ij.IJ);

var imp = IJ.getImage();
var n = imp.getStackSize();
var miny,maxy;

for( var i = 1; i < n+1; ++i) {
    imp.setSlice(i);
    miny=parseInt(4000/i-17);
    maxy=miny+5;
    IJ.setMinAndMax(imp, miny, maxy);
    IJ.run(imp, "Apply LUT", "slice");
}

The accepted answer is the best for the OP's question, but a small variant is if you want to change the brightness/contrast as a function of the slices of your specific data.

In my case I wanted to have a threshold effect but the threshold value was changing in each slice of the stack. I went to a few different slices and manually found the threshold value. I then found an approximate function for Threshold value (Tv) as a function of the slice (s) as follows:

Tv=4000/s-17

Therefore, Then my script becomes:

importClass(Packages.ij.IJ);

var imp = IJ.getImage();
var n = imp.getStackSize();
var miny,maxy;

for( var i = 1; i < n+1; ++i) {
    imp.setSlice(i);
    miny=parseInt(4000/i-17);
    maxy=miny+5;
    IJ.setMinAndMax(imp, miny, maxy);
    IJ.run(imp, "Apply LUT", "slice");
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文