Разглаживание изображения
Я пытаюсь удалить изображение в Python, но столкнулся с некоторыми проблемами. Вот что я пробовал, но имейте в виду, что я не эксперт по этой теме. В соответствии с моим пониманием, если вы знаете функцию разброса точек, вы должны иметь возможность просто размыть изображение, выполнив деконволюцию. Тем не менее, это, похоже, не работает, и я не знаю, делаю ли я что-то глупое или просто не правильно понимаю вещи. В книге по вычислительной физике Марка Ньюмана (с использованием Python) он затрагивает эту тему в задаче 7.9. В этой задаче он предоставляет изображение, которое он намеренно размыл, используя функцию рассеяния точки Гаусса (psf), и цель задачи состоит в том, чтобы размыть изображение, используя гауссову. Это достигается путем деления 2D-БПФ размытого изображения на 2D-БПФ PSF, а затем выполняется обратное преобразование. Это работает достаточно хорошо.
Чтобы расширить эту проблему, я хотел размыть реальное изображение, полученное с помощью камеры, которая была намеренно не в фокусе. Поэтому я установил камеру и сделал два набора снимков. Первый набор фотографий был в фокусе. Первая была очень маленькой светодиодной лампой в полностью затемненной комнате, а вторая - листком бумаги с текстом (с использованием вспышки). Затем, не меняя расстояния или что-либо еще, я изменил настройку фокусировки на камере, чтобы текст был очень не в фокусе. Затем я сделал снимок текста с помощью вспышки и сделал второй снимок светодиода (без вспышки). Вот размытые изображения.
Теперь, насколько я понимаю, изображение размытого точечного источника света должно быть функцией разброса точек, и поэтому я должен быть в состоянии использовать ее для размытия своего изображения. Проблема в том, что когда я делаю это, я получаю изображение, которое выглядит как шум. После небольшого исследования кажется, что шум может быть большой проблемой при использовании методов деконволюции. Однако, учитывая, что я измерил то, что я считаю точной функцией разброса точек, я удивлен, что шум будет проблемой здесь.
Одна вещь, которую я попробовал, состояла в том, чтобы заменить небольшие значения (меньше, чем epsilon) в преобразовании psf либо на 1, либо на epsilon, и я попробовал это с огромным диапазоном значений для epsilon. Это дало изображение, которое было не просто шумом, но и не размытой версией изображения; это выглядит как странная, размытая версия исходного (не размытого) изображения. Вот изображение из моей программы (вы можете игнорировать значение сигмы, которое не использовалось в этой программе).
Я полагаю, что имею дело с проблемой шума, но я не знаю почему, и я не знаю, что с этим делать. Любой совет будет высоко ценится (учитывая, что я не эксперт в этой области).
Обратите внимание, что я намеренно не опубликовал код, потому что я думаю, что это несколько не имеет значения в данный момент. Но я был бы счастлив сделать это, если кто-то думает, что это будет полезно. Я не думаю, что это проблема программирования, потому что я использовал ту же технику, и она отлично работает, когда у меня есть известная функция разброса точек (например, когда я делю БПФ исходного изображения в фокусе на БПФ вне -фокусировать изображение, а затем обратное преобразование). Я просто не понимаю, почему я не могу использовать свою экспериментально измеренную функцию разброса точек.
1 ответ
Проблема, которую вы пытались решить, к сожалению, сложнее, чем вы могли ожидать. Позвольте мне объяснить это в четырех частях. В первом разделе предполагается, что вы знакомы с преобразованием Фурье.
- Почему вы не можете решить эту проблему с помощью простой деконволюции.
- Описание того, как можно выполнить размытие изображения.
- Деконволюция по БПФ и почему это плохая идея
- Альтернативный метод для деконволюции
Но сначала немного обозначений:
Я использую I для представления изображения и K для представления ядра свертки. I * K - свертка образа I с ядром K. F (I) - (n-мерное) преобразование Фурье изображения I, а F (K) - преобразование Фурье ядра K свертки (это также называется функцией рассеяния точки, или PSF). Точно так же Fi - обратное преобразование Фурье.
Почему вы не можете решить эту проблему с помощью простой деконволюции:
Вы правы, когда говорите, что мы можем восстановить размытое изображение Ib = I * K, разделив преобразование Фурье Ib на преобразование Фурье K. Тем не менее, размытие линзы не является сверточной операцией размытия. Это модифицированная операция сверточного размытия, где ядро размытия K зависит от расстояния до объекта, который вы сфотографировали. Таким образом, ядро меняется от пикселя к пикселю.
Вы можете подумать, что это не проблема с вашим изображением, так как вы измерили правильное ядро в положении изображения. Однако это может быть не так, поскольку часть изображения, которая находится далеко, может влиять на ту часть изображения, которая находится близко. Один из способов решения этой проблемы - обрезать изображение так, чтобы видна была только бумага.
Почему деконволюция с помощью БПФ - плохая идея:
Теорема о свертке утверждает, что I * K = Fi (F (I) F (K)). Эта теорема приводит к разумному предположению, что если у нас есть изображение, Ib = I * K, которое размыто ядром свертки K, то мы можем восстановить размытое изображение, вычисляя I = (F (Ib) / F (K)),
Прежде чем мы рассмотрим, почему это плохая идея, я хочу понять, что означает теорема о свертке. Когда мы сворачиваем изображение с ядром, то это то же самое, что брать частотные компоненты изображения и умножать его поэлементно на частотные компоненты ядра.
Теперь позвольте мне объяснить, почему трудно деконвертировать изображение с помощью БПФ. Размытие по умолчанию удаляет высокочастотную информацию. Таким образом, высокие частоты К должны стремиться к нулю. Причина этого заключается в том, что высокочастотная информация I теряется, когда она размыта - таким образом, высокочастотные компоненты Ib должны стремиться к нулю. Для этого высокочастотные компоненты K также должны стремиться к нулю.
В результате того, что высокочастотные составляющие K почти равны нулю, мы видим, что высокочастотные составляющие Ib значительно усиливаются (так как мы почти делим на ноль) при деконволюции с БПФ. Это не проблема в бесшумном корпусе.
В шумном случае, однако, это проблема. Причина этого заключается в том, что шум по определению является высокочастотной информацией. Поэтому, когда мы пытаемся деконволюировать Ib, шум усиливается почти до бесконечности. Это причина того, что деконволюция БПФ - плохая идея.
Кроме того, необходимо рассмотреть, как алгоритм свертки на основе БПФ работает с граничными условиями. Обычно, когда мы сворачиваем изображения, разрешение несколько уменьшается. Это нежелательное поведение, поэтому мы вводим граничные условия, которые определяют пиксельные значения пикселей за пределами изображения. Примером таких граничных условий являются
- Пиксели вне изображения имеют то же значение, что и ближайший пиксель внутри изображения
- Пиксели вне изображения имеют постоянное значение (например, 0)
- Изображение является частью периодического сигнала, поэтому строка пикселей над самой верхней строкой равна нижней строке пикселей.
Конечное граничное условие часто имеет смысл для одномерных сигналов. Однако для изображений это не имеет большого смысла. К сожалению, теорема о свертке указывает, что используются периодические граничные условия.
В дополнение к этому, кажется, что метод инверсии на основе БПФ значительно более чувствителен к ошибочным ядрам, чем итерационные методы (например, градиентный спуск и FISTA).
Альтернативный метод для деконволюции
Может показаться, что теперь вся надежда потеряна, поскольку все изображения зашумлены, а деконволюция увеличит шум. Однако это не так, поскольку у нас есть итерационные методы для деконволюции. Позвольте мне начать с показа простейшего итеративного метода.
Пусть || Я ||² будет квадратом суммы всех моих пикселей. Решение уравнения
Ib = I * K
по отношению к I тогда эквивалентно решению следующей задачи оптимизации:
min L (I) = min || I * K - Ib ||²
по отношению к мне. Это может быть сделано с использованием градиентного спуска, так как градиент L определяется как
DL = Q * (I * K - Ib)
где Q - это ядро, которое вы получаете путем транспонирования K (это также называется согласованным фильтром в литературе по обработке сигналов).
Таким образом, вы можете получить следующий итерационный алгоритм, который будет размыть изображение.
from scipy.ndimage import convolve
blurred_image = # Load image
kernel = # Load kernel/psf
learning_rate = # You need to find this yourself, do a logarithmic line search. Small rate will always converge, but slowly. Start with 0.4 and divide by 2 every time it fails.
maxit = 100
def loss(image):
return np.sum(convolve(image, kernel) - blurred_image)
def gradient(image):
return convolve(convolve(image, kernel) - blurred_image)
deblurred = blurred_image.copy()
for _ in range(maxit):
deblurred -= learning_rate*gradient(image)
Вышеуказанный метод, возможно, является самым простым из итерационных алгоритмов деконволюции. Они используются на практике с помощью так называемых регуляризованных алгоритмов деконволюции. Эти алгоритмы работают, сначала определяя функцию, которая измеряет количество шума в изображении, например, TV (I) (общее изменение I). Затем процедура оптимизации выполняется на L (I) + wTV (I). Если вас интересуют такие алгоритмы, я рекомендую прочитать статью FISTA Амира Бека и Марка Тебулля. Бумага довольно трудоемкая, но вам не нужно понимать большую ее часть - только о том, как реализовать алгоритм удаления размышлений на телевидении.
В дополнение к использованию регуляризатора, мы используем ускоренные методы, чтобы минимизировать потери L (I). Одним из таких примеров является ускоренный градиентный спуск Нестерова. См. Адаптивный перезапуск для ускоренных градиентных схем. Автор Brendan O'Donoghue, Emmanuel Candes, для получения информации о таких методах.
Описание того, как можно выполнить размытие изображения.
- Обрежьте изображение так, чтобы все находилось на одинаковом расстоянии от камеры.
- Найдите ядро свертки так же, как вы делали это сейчас (сначала протестируйте алгоритм деконволюции на синтетически размытых изображениях)
- Реализуйте итерационный метод для вычисления деконволюции
- Разверните изображение.