Как выполнить 2D свертку, используя 1D свертку?
Предположим,
u = [1 2 1 3 ; 1 2 1 3 ; 1 2 1 3];
v = [2 0 1 ; 2 0 1 ; 2 0 1];
Я хочу добиться
w = conv2(u, v); % [2 4 3 8 1 3 ; 4 8 6 16 2 6 ; 6 12 9 24 3 9 ; 4 8 6 16 2 6 ; 2 4 3 8 1 3]
И, предположим, я не хочу использовать conv2()
,
Используя Matlab, я обнаружил, что
w1 = conv([1 2 1 3], [2 0 1]) % [2 4 3 8 1 3]
w2 = conv([1 2 1 3], [2 0 1]) % [2 4 3 8 1 3]
w3 = conv([1 2 1 3], [2 0 1]) % [2 4 3 8 1 3]
Итак, мы получаем:
w123 = [w1 ; w2 ; w3] % [2 4 3 8 1 3 ; 2 4 3 8 1 3 ; 2 4 3 8 1 3];
Используя Matlab, я также обнаружил, что
x = [2 ; 2 ; 2]
y = [1 ; 1 ; 1]
z = conv(x, y); % [2 ; 4 ; 6 ; 4 ; 2];
x = [4 ; 4 ; 4]
y = [1 ; 1 ; 1]
z = conv(x, y); % [4 ; 8 ; 12 ; 8 ; 4];
x = [3 ; 3 ; 3]
y = [1 ; 1 ; 1]
z = conv(x, y); % [3 ; 6 ; 9 ; 6 ; 3];
x = [8 ; 8 ; 8]
y = [1 ; 1 ; 1]
z = conv(x, y); % [8 ; 16 ; 24 ; 16 ; 8];
x = [1 ; 1 ; 1]
y = [1 ; 1 ; 1]
z = conv(x, y); % [1 ; 2 ; 3 ; 2 ; 1];
x = [3 ; 3 ; 3]
y = [1 ; 1 ; 1]
z = conv(x, y); % [3 ; 6 ; 9 ; 6 ; 3];
Это означает, что если мы выполним 1D свертку на каждом ряду u
с ядром [2 0 1]
, а затем применить 1D свертку на каждом столбце с ядром [1; 1; 1]
, мы получаем:
2 4 3 8 1 3
4 8 6 16 2 6
6 12 9 24 3 9
4 8 6 16 2 6
2 4 3 8 1 3
Итак, мой вопрос, где это [1 ; 1 ; 1]
родом из?
И, самое главное, что произойдет, если строки не совпадают?
2 ответа
Причина того, что ваши 1D свертки объединяются, чтобы дать вам те же результаты, что и 2D свертка, заключается в том, что ваш фильтр отделим. Стив Эддинс обсудил разделимые свертки в своем блоге MATLAB здесь.
Ваш фильтр отделим, потому что:
[1;1;1] * [2,0,1] =
2 0 1
2 0 1
2 0 1
Но в целом не все 2D-фильтры являются разделимыми, и только те из них, которые можно превратить в отдельные одномерные свертки.
Я полагаю, потому что ваша матрица v
это один и тот же ряд 3 раза. Поэтому вы можете просто использовать 2-ую свертку с [1 1 1]
над колоннами