Высококачественная выходная мощность в соответствии с исходным размером изображения
Вступление
Фон: я сегментирую изображения, используя watershed
алгоритм в MATLAB. Что касается памяти и ограничений по времени, я предпочитаю выполнять эту сегментацию для субдискретизированных изображений, скажем, с коэффициентом изменения размера 0.45
,
Проблема: я не могу должным образом перемасштабировать вывод сегментации до исходного масштаба изображения, как для целей визуализации, так и для других этапов постобработки.
Минимальный рабочий пример
Например, у меня есть это изображение:
Я запускаю этот минимальный сценарий, и я получаю вывод сегментации водораздела L
он состоит из изображения метки, где каждый подключенный компонент имеет натуральное число, а границы между подключенными компонентами имеют нулевое значение:
im_orig = imread('kitty.jpg'); % Load image [530x530]
im_res = imresize(im_orig, 0.45); % Resize image [239x239]
im_res = rgb2gray(im_res); % Convert to grayscale
im_blur = imgaussfilt(im_res, 5); % Gaussian filtering
L = watershed(im_blur); % Watershed aglorithm
Теперь у меня есть L
который имеет такое же измерение im_res
, Как я могу использовать результат, сохраненный в L
на самом деле сегмент оригинала im_orig
изображение?
Неправильное решение
Первым подходом, который я попробовал, было изменение размера L
к первоначальному масштабу с помощью imresize
,
L_big = imresize(L, [size(im_orig,1), size(im_orig,2)]); % Upsample L
К сожалению, выборка из L
производит серию нежелательных артефактов. Это особенно теряет некоторые из основных нулей, которые представляют границы между сегментами изображения. Вот что я имею в виду:
figure; imagesc(imfuse(im_res, L == 0)); axis auto equal;
figure; imagesc(imfuse(im_orig, L_big == 0)); axis auto equal;
Я знаю, что это происходит из-за размытия, вызванного процессом масштабирования, но сейчас я не мог думать ни о чем другом, что могло бы преуспеть.
Единственный другой подход, о котором я подумал, связан с использованием математической морфологии, чтобы "увеличить" границы измененного изображения и затем увеличить выборку, но это все равно приведет к нежелательным артефактам.
TL; DR (или резюме)
Есть ли способ выполнить watershed
на уменьшенном изображении в MATLAB, а затем увеличьте результат до исходного изображения, сохраняя четкие границы области, выведенные алгоритмом? Это то, что я ищу, совершенно абсурдно?
3 ответа
Если вам нужны только границы сегмента водораздела после увеличения размера изображения, просто внесите эти небольшие изменения:
L_big = ~imresize(L==0, [size(im_orig,1), size(im_orig,2)]); % Upsample L
и вот результаты:
Вы можете использовать интерполяцию ближайшего соседа при изменении размера:
L_big = imresize(L, [size(im_orig,1), size(im_orig,2)],'nearest'); % Upsample L
Обычно, когда мы изменяем размеры изображений, мы помечаем место назначения, перебираем x, y и находим наилучший соответствующий пиксель в источнике. Здесь вы хотите сделать обратное. Выполните итерации по источнику в x, y и запишите в буфер назначения, причем 0 имеет приоритет (поэтому инициализируйте в 0xFF, затем не перезаписывайте любые нули другими значениями),
Вряд ли найдется функция, которая делает это в наборе инструментов, вам придется развернуть свою собственную.