Buades и соавт.определенно предназначен для использования гауссовых весов.Это ядро, если оно предназначено для приближения, дает очень грубое приближение.Вот как это выглядит в 1D для f=3
, f=10
и f=100
:
![kernels](https://i.stack.imgur.com/pJa19.png)
Я добавил ядро Гаусса для сравнения,Кроме того, гауссиан является совершенно изотропным, тогда как это приближение далеко от него (потому что оно состоит из квадратов).
И я нахожу это странным, потому что четыре вложенных цикла алгоритма NL означают, что ониспользуется не делается быстрее, используя это приближение по истинному гауссову.Квадрат разности патчей умножается на ядро, стоимость этой операции не зависит от того, как сгенерировано ядро или какие значения оно содержит.
Я бы предложил заменить make_kernel
чем-то вроде этого, который создает настоящее двумерное гауссовское ядро:
function kernel = make_kernel2(f)
x = linspace(-2,2,2*f+1);
kernel = exp(-0.5*x.^2);
kernel = kernel .* kernel.'; % requires newer MATLAB, otherwise use bsxfun
kernel = kernel / sum(kernel(:));
Я никогда раньше не видел этого конкретного приближения к гауссову (и я видел много).Как правило, гауссова свертка аппроксимируется повторяющимися применениями свертки с коробчатым ядром (говорят, что 3x достаточно для достаточно хорошего приближения, , но требуется больше, если производная должна быть вычислена после ).Недостатком этого подхода является невозможность повторного использования интегрального изображения, поскольку каждая свертка применяется к разному изображению (т.е. результат предыдущей свертки).Свертка с ядром блока может быть вычислена с использованием интегрального изображения, где выход для одного пикселя может быть вычислен путем сложения 4 значений плюс одно деление, независимо от размера блока.
img = imread('cameraman.tif');
out = imfilter(img,ones(3,3)/9);
out = imfilter(out,ones(3,3)/9);
out = imfilter(out,ones(3,3)/9);
Если вместо многократного применения свертки блоков вычислить несколько сверток блоков разных размеров, используя одно и то же интегральное изображение, и сложить результаты вместе, то получится свертка с ядром, о котором спрашивается в этом вопросе.Это было бы грубым приближением к гауссовскому и не изотропным, но это было бы очень дешевым для вычисления.(Демонстрационный код, приведенный ниже, не использует целостное изображение, это не предназначено для демонстрации времени, а только того, как выглядит результат.)
img = imread('cameraman.tif');
out = imfilter(img,ones(3,3)/9) / 3;
out = out + imfilter(img,ones(4,4)/16) / 3;
out = out + imfilter(img,ones(5,5)/25) / 3;
Могу поспорить, что это то, откуда пришло это ядро.Однако, создавая это ядро, а не применяя различные свертки отдельно и добавляя результаты, все преимущества скорости в этом методе не используются, оставляя только многие его отрицательные стороны.