简体   繁体   English

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

[英]ImageJ Brightness & Contrast over a stack of images

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. 我正在查看ImageJ中的数据集图像集(一堆.tif图像,大约130帧),我对数据集有疑问。 It's a series of microscope images, with each frame being a plane about 3-4 micrometers above/below the previous one. 这是一系列显微镜图像,每个框架是一个平面,比前一个框架高出/低于3-4微米。 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. 但是,ImageJ的亮度和对比度功能使用直方图来表示整个图像堆栈。 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 (eg with a plugin) for the entire stack? 如何以编程方式(例如使用插件)为整个堆栈执行此操作? What are the relevant API calls? 什么是相关的API调用?

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 ... . 开始编写这样一个脚本的好方法是使用ImageJ的宏录制器 - 您可以使用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. 对于此示例,我假设您已将Record:选项框切换为JavaScript ,但如果您更熟悉ImageJ宏语言或使用Java编写插件,则其他一个可能是更好的选择。 If you then open your image and use Image > Stacks > Set Slice ... and select (say) slice 20, you should see: 如果然后打开图像并使用Image > Stacks > Set Slice ...并选择(比如说)切片20,您应该看到:

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. 现在,如果您运行Image > Adjust > Brightness/Contrast...并选择Auto ,您应该在录像机中看到,这相当于运行Enhance Contrast保持0.35%饱和像素。 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 . 但是,您可以运行Enhance Contrast通过运行带有不同的选择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. ImageJ文档维基上有关该选项的部分解释了如果要更改像素值而不是设置堆栈的最小值和最大值,则需要选择“标准化”选项。 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. ......你应该看到只有切片20被改变了。 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 (eg via File > New > Script ) is an easy way to experiment with such scripts.) (如果您使用斐济,那么脚本编辑器(例如通过File > New > Script )是一种简单的方法来试验这些脚本。)

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. 当然,使用normalize选项会导致像素值被更改,这意味着在这种情况下您将丢失信息,因此我不会将结果堆栈用于定量结果。

I hope that's of some use. 我希望有一些用处。

You might also consider using CellProfiler to process the images. 您也可以考虑使用CellProfiler来处理图像。 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. 即使CP无法直接执行您要执行的操作,您实际上也可以从CP运行ImageJ命令,插件和宏。

At the very simplest, you could create a CP pipeline that just has LoadImages and RunImageJ. 最简单的方法是,您可以创建一个只有LoadImages和RunImageJ的CP管道。

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. 对于OP的问题,接受的答案是最好的,但如果您想根据特定数据的切片更改亮度/对比度,则可以使用一个小变体。

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)的近似函数作为切片的函数,如下所示:

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");
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM