Я пытаюсь украсить изображение. Я хочу знать, было ли это отменено или нет, если посмотреть на значение SNR. Теперь, как я могу оценить SNR изображения в Python?
SNR определяется по-разному, но я предполагаю, что для вашего приложения его точное определение не имеет значения. В общем, это отношение мощности сигнала и мощности шума. "Сила" здесь намеренно оставлена двусмысленной, часто используется мощность сигнала и шума, но амплитуда также жизнеспособна.
Предположим, что SNR - это мощность сигнала изображения, деленная на мощность шумового сигнала. Мощность шума - просто его дисперсия. Вы сравниваете изображение до и после шумоподавления, поэтому, по-видимому, мощность сигнала не изменяется. Мы можем игнорировать его и установить в 1. Теперь наше SNR просто определяется как 1/var(noise)
.
Итак, что вам нужно сделать, это оценить дисперсию шума и сравнить ее до и после шумоподавления. Вы хотите, чтобы эта дисперсия снизилась (по мере увеличения SNR).
В общем, нелегко оценить дисперсию шума изображения, если вы не знаете, как выглядит изображение без шума. Вы можете думать о шумовом изображении как
image = noiseless_image + noise.
Таким образом, дисперсия изображения - это дисперсия шума + дисперсия бесшумного изображения. Если вы не знаете последнего, вы не можете получить первое.
Но есть трюки. Самый простой способ, если вы хотите сделать небольшую ручную работу для каждого изображения, которое вы сравниваете, состоит в том, чтобы наметить плоскую область фона (обычно будет работать небольшая область неба). Очень важно, чтобы в этом регионе не было естественного изменения интенсивности. Теперь просто вычислите дисперсию пикселей внутри этого региона.
Для этой цели были опубликованы несколько полностью автоматических методов. Я знаю об этом Дж. Иммеркаре: "Оценка шумового шума", "Видение компьютера" и "Понимание изображения" 64 (2): 300-302, 1996. Библиотека DIPlib (я автор) имеет реализацию. Вы можете использовать его из Python следующим образом:
var = dip.EstimateNoiseVariance(img)
(с img
либо объект изображения из библиотеки, либо массив Numpy, либо любой другой объект, который предоставляет буфер). Но, поскольку пока еще не существует официального релиза версии библиотеки с привязками Python, вам нужно будет сама собрать и скомпилировать библиотеку, если вы хотите использовать эту реализацию. Но, учитывая, что это довольно простой метод, вы могли бы подумать о его реализации.
Вот псевдокод для метода:
mask = gradient magnitude of img
Apply Gaussian smoothing (sigma = 3) to mask
If the image has more than one channel:
mask = max over the channels
Compute the Otsu threshold value for mask
mask = pixels where mask < threshold
error = discrete Laplace of in: apply convolution with [1,-2,1;-2,4,-2;1,-2,1]
MSE = the mean square value of the pixels in error that fall within mask, on a per-channel basis
If the image has more than one channel:
MSE = mean over MSE values for each channel
variance = MSE / 36