ImageJ Яркость и контрастность по стопке изображений - PullRequest
6 голосов
/ 17 декабря 2010

Я просматриваю набор изображений из набора изображений в ImageJ (стопку изображений .tif, около 130 кадров), и у меня возникла проблема с набором данных. Это серия микроскопических изображений, где каждый кадр представляет собой плоскость примерно на 3-4 микрометра выше / ниже предыдущего. По мере того как я углубляюсь в набор данных, рассеяние света создает более яркий фон, поэтому основные характеристики образца тусклее.

Однако функция яркости и контрастности ImageJ использует гистограмму, которая представляет весь стек изображений. Когда я нажимаю «Авто» и «Сброс» на изображении глубоко в стеке, результирующий контраст получается идеальным: все функции очень хорошо освещаются. Однако тогда, в начале стека, большинство функций стали насыщенными.

Я попытался вручную извлечь несколько изображений из различных точек в стеке и выполнить Авто-> Сброс яркости и контраста для каждого из них по отдельности и впоследствии преобразовать их в стопку, и это выглядит действительно солидно. Как я могу сделать это программно (например, с помощью плагина) для всего стека? Каковы соответствующие вызовы API?

Ответы [ 3 ]

4 голосов
/ 04 января 2011

Хороший способ начать писать такой скрипт - использовать макро-рекордер ImageJ - вы можете начать это с Plugins > Macros > Record .... В этом примере я предполагаю, что вы переключили опцию Record: на JavaScript, но если вы более знакомы с языком макросов ImageJ или написанием плагинов в Java, один из других может быть лучшим выбором , Если вы затем откроете свое изображение и используете Image > Stacks > Set Slice ... и выберите (скажем) срез 20, вы должны увидеть:

imp.setSlice(20);

... появляются в диктофоне. Теперь, если вы запустите Image > Adjust > Brightness/Contrast... и выберете Auto, вы увидите в рекордере, что это эквивалентно запуску Enhance Contrast с сохранением 0,35% насыщенных пикселей. Проблема с этим, как вы заметили, заключается в том, что при этом настраиваются минимальные и максимальные значения для всего стека, а не только этот фрагмент. Тем не менее, вы можете запустить Enhance Contrast с другими параметрами, запустив Process > Enhance Contrast. В разделе об этой опции на вики-документации ImageJ объясняется, что если вы хотите изменить значения пикселей, а не устанавливать минимальные и максимальные значения для стека, вам необходимо выбрать параметр «Нормализация». Если я решу вместо этого сделать это, то рекордер макросов запишет:

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

(Если вы используете Фиджи, тогда Script Editor (например, через File > New > Script) - это простой способ экспериментировать с такими скриптами.)

Конечно, использование параметра нормализации приводит к изменению значений пикселей, что в данном случае означает, что вы теряете информацию, поэтому я не буду использовать полученный стек для количественных результатов.

Надеюсь, это пригодится.

1 голос
/ 30 сентября 2011

Вы также можете использовать CellProfiler для обработки изображений.Даже если CP не может сделать именно то, что вы пытаетесь сделать напрямую, вы на самом деле можете запускать команды ImageJ, плагины и макросы из CP.

Самое простое, вы можете создать конвейер CP, который просто имеетLoadImages и RunImageJ.

0 голосов
/ 04 мая 2017

Принятый ответ является лучшим для вопроса ОП, но небольшой вариант - если вы хотите изменить яркость / контрастность как функцию срезов ваших конкретных данных.

В моем случае я хотелиметь пороговый эффект, но пороговое значение менялось в каждом срезе стека.Я пошел на несколько разных срезов и вручную нашел пороговое значение.Затем я нашел приблизительную функцию для порогового значения (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");
}
...