Документация Engee

mreconstruct

Оператор морфологической реконструкции служит для многократного применения определенного оператора до достижения устойчивости, то есть неизменности результата. Чаще всего применяются реконструкция по расширению и реконструкция по эрозии.

using ImageMorphology
using TestImages
using ImageBase
using ImageShow
using IndirectArrays #hide

img = Gray.(testimage("blob"))
nothing #hide

В отличие от других морфологических операторов, таких как erode, mreconstruct требует двух входных изображений. Одно из них — маркерное изображение, а другое — масочное. Обычно на основе изображения mask производится обучение, а на основе изображения marker — реконструкция. Основой для построения маркерного изображения могут быть следующие данные [1]:

  • знания об ожидаемом результате;

  • известные факты об изображении или физике объекта, который представлен на нем;

  • определенные преобразования масочного изображения;

  • другие графические данные, если они имеются (например, многоспектральные и многовременные изображения);

  • взаимодействие с пользователем (маркеры определяются вручную).

Возьмем в качестве примера реконструкцию по расширению: мы строим маркерное изображение на основе масочного, а затем многократно применяем marker = min.(dilate(marker), mask).

mask = img
marker = mask .- 0.3
mosaic(marker, mask; nrow=1)
1888771062

Следующая функция представляет собой примитивную реализацию этой идеи:

# Только для иллюстрации; на практике следует использовать `mreconstruct`
function my_reconstruct(marker, mask)
    # реконструкция по расширению
    # Для реконструкции по эрозии можно заменить `min` на `max`, а `dilate` на `erode`
    out = min.(mask, marker)
    has_changed = true
    while has_changed
        old = out
        out = min.(dilate(out), mask)
        has_changed = !(old == out)
    end
    return out
end

На следующей GIF-анимации показаны промежуточные результаты out каждой итерации. Слева показано фактическое значение оттенка серого, а справа — цветное значение для большей наглядности.

function my_reconstruct_outs(marker, mask) #hide
    out = min.(mask, marker) #hide
    outs = [out] #hide
    has_changed = true #hide
    n = 1 #hide
    while has_changed #hide
        old = out #hide
        out = min.(dilate(out), mask) #hide
        n % 4 == 1 && push!(outs, out) #hide
        has_changed = !(old == out) #hide
        n = n + 1 #hide
    end #hide
    return outs #hide
end #hide
function with_color(img, orders, colormap) #hide
    return IndirectArray([orders[img[i]] for i in CartesianIndices(img)], colormap) #hide
end #hide
outs = my_reconstruct_outs(marker, mask) #hide
orders = Dict(x => i for (i, x) in enumerate(sort(mapreduce(unique, union, outs)))) #hide
colormap = ImageCore.Colors.distinguishable_colors(length(orders)) #hide
gif = ImageShow.gif([mosaic(frame, with_color(frame, orders, colormap); nrow=1) for frame in outs]; fps=5) #hide
mreconstruct

Вот как происходит реконструкция и почему она так называется — изображение marker реконструируется с помощью опорного изображения mask, что помогает исследовать определенные свойства изображения mask. Например, если мы хотим исследовать только пятна (темные участки), следует применить реконструкцию по расширению.

Функция mreconstruct(op, marker, mask) в настоящее время поддерживает только dilate и erode в качестве op, то есть соответственно реконструкцию по расширению и по эрозии. Есть также псевдонимы underbuild и overbuild.

# реконструкция по расширению -- `underbuild`
out1 = mreconstruct(dilate, img .- 0.3, img)
# реконструкция по эрозии -- `overbuild`
out2 = mreconstruct(erode, img .+ 0.3, img)
mosaic(mask, out1, out2; nrow=1)
4038053876

По умолчанию используется структурирующий элемент прямоугольной формы. Как и в другие операторы, в mreconstruct можно передать именованный аргумент dims или позиционный аргумент se. Например:

mreconstruct(dilate, img .- 0.3, img; dims=1) # реконструкция по столбцу
mreconstruct(dilate, img .- 0.3, img, strel_diamond(img)) # СЭ ромбовидной формы
nothing #hide

Однако для универсального структурирующего элемента половинный размер (или радиус) должен быть не более 1 для каждого измерения. Это связано с тем, что алгоритм производит наращение до достижения устойчивости, поэтому СЭ с половинным размером больше 1 на практике не имеет значения.


Эта страница была создана с помощью DemoCards.jl и Literate.jl.


1. P. Soille. Morphological Image Analysis (Chapter 6.2.3). Berlin, Heidelberg: Springer Berlin Heidelberg, 2004. doi: 10.1007/978-3-662-05088-0.