3

Я пытаюсь получить некоторые данные о функции MATLAB conv2. Предположим, что у нас есть изображение I размеров 5 x 5 и ядро ​​K, то есть 3 x 3.Как выполняется полная свертка с использованием функции conv2 MATLAB?

conv2(I,K) вернет матрицу 7 x 7. Какие дополнительные операции выполняются, о которых я не знаю? Я могу полностью понять, как conv2(I,K,'valid') и conv2(I,K,'same') работает с математической точки зрения. Однако операция по умолчанию возвращает большую матрицу. Кто-нибудь знает, что он на самом деле делает?

ответ

12

Если вы знаете, как работает флаг 'valid 'и флаг 'same', то это далеко не так, чтобы перейти к опции по умолчанию, которая является опцией 'full'. Когда вы перемещаете ядро ​​по изображению/матрице, как только по крайней мере один элемент из ядра касается какого-либо элемента из изображения/матрицы, это считается допустимым выходом. Вывод операции продиктован центром, где ядро ​​есть, когда есть допустимый вывод. Например, посмотрите на следующие 5 х 5 изображения I ниже с примером 3 х 3 ядра K:

I = [1 2 3 4 5 ]  K = [1 0 1] 
    [6 7 8 9 10]   [1 0 1] 
    [11 12 13 14 15]   [1 0 1] 
    [16 17 18 19 20] 
    [21 22 23 24 25] 

Следует заметить, что цифры не так важны, но они используются для иллюстрации. Также обратите внимание, что ядро ​​симметрично, и поэтому выполнение вращения на 180 градусов приводит к тому же ядру. Это необходимо для свертки, прежде чем мы начнем. В конфигурации 'full' мы перемещаем ядро ​​слева вверху слева вверху слева направо, вплоть до нижнего. Выход первого элемента в выходной матрице происходит, когда в правом нижнем углу ядра затрагивает левый верхний угол изображения/матрицы:

[1  0 1] 
[1 `0` 1] 
[1 0 [1*1] 2 3 4 5]  
     [6 7 8 9 10]  
     [11 12 13 14 15]  
     [16 17 18 19 20] 
     [21 22 23 24 25] 

Обратите внимание, что центр ядра, как мы подметать по изображению это место, где нам нужно выводить изображение, обозначенное символами ``. Помните, что для вычисления свертки здесь мы находим взвешенную и элементарную сумму произведений между каждым элементом в ядре и где она касается матрицы/изображения.

Обратите внимание, что для любых элементов ядра, которые находятся за пределами границ, мы игнорируем, и поэтому выход просто расположен в нижней правой части ядра и левом верхнем углу изображения, и мы умножаем эти элементы вместе. Выходной сигнал - 1*1 = 1. Теперь давайте перейдем к следующему элементу, который является 1 справа:

[ 1  0 1] 
    [ 1 `0` 1] 
    [1 [0*1] [2*1] 3 4 5 ]  
    [6  7  8 9 10]  
    [11 12 13 14 15]  
    [16 17 18 19 20] 
    [21 22 23 24 25] 

Примечание, где центр, а также какие элементы ядро ​​касается матрицы. Таким образом, выход 0*1 + 2*1 = 2. Вы продолжаете это до тех пор, пока не попадете в конец этой строки, где нижняя левая часть ядра коснется верхнего правого изображения. Затем вы переходите к следующей строке, повторяете развертку по всем столбцам и продолжаете до самого конца, пока верхняя левая часть ядра не коснется нижней правой части изображения/матрицы.

Вот еще несколько примеров, чтобы убедиться в правильности теории. Давайте точку, где ядро ​​касается в правом верхнем углу изображения/матрицы

    [ 1 0 1] 
       [ 1 `0` 1] 
    [1 2 3 4 [5*1]] 0 1] 
    [6 7 8 9 10]   
    [11 12 13 14 15]   
    [16 17 18 19 20] 
    [21 22 23 24 25] 

Помните, что мы игнорируем все места, где ядро ​​не трогают изображение/матрица. Выход в этом случае будет просто 5, а также обратите внимание, где находится выходное местоположение.Вот еще один пример:

 [1  2 3 4 5 ] 
    [6  7 8 9 10]   
    [11  12 13 14 15]   
    [16  17 18 19 20] 
[1 0 [[21*1] 22 23 24 25] 
[1 `0` 1] 
[1 0 1] 

Это место находится в нижнем левом углу изображения/матрицы, а выход здесь будет просто 21*1. Еще один, чтобы быть уверенным:

[1 2 3 4 5]  
    [6 7 8 9 10]   
    [11 12 13 14 [1*15]] 0 1] 
    [16 17 18 19 [1*20]] `0` 1] 
    [21 22 23 24 [1*25]] 0 1] 

Это место немного сложнее. Ядро полностью перекрывает изображение/матрицу по первому столбцу, поэтому выход равен 1*15 + 1*20 + 1*25 = 60. Также обратите внимание, что выходное положение находится на третьей последней строке, потому что еще есть еще две строки фильтрации. Тот, где первые две строки ядра касаются нижних последних двух строк изображения/матрицы, и где первая строка ядра касается нижней нижней строки изображения/матрицы.

Следовательно, конечная матрица вывода будет выглядеть примерно так.

[1 2 * * * * 5 ] 
[* * * * * * * ] 
[* * * * * * * ] 
[* * * * * * * ] 
[* * * * * * 60] 
[* * * * * * *] 
[21 * * * * * *] 

Элементы, отмеченные как * неизвестны, поскольку я не рассчитали тех, но суть в том, чтобы заметить, что конечный размер матрицы. В частности, обратите внимание, где расположены выходные позиции, где нам нужно записать в матрицу для первых двух случаев, которые вы видите выше. Именно по этой причине вы получаете большую матрицу - для размещения результатов, когда ядро ​​не полностью содержится в самой картине/матрице, но все же выполняет действительные операции. Как вы можете видеть, вам понадобятся две дополнительные строки: 1 для верхней и 1 для нижней и два дополнительных столбца: 1 для левой и 1 для правой. В результате получается выходная матрица (5 + 2) x (5 + 2) = 7 x 7. В общем случае, если размер ядра нечетный, вывод, который вы получаете от использования 'full' 2D свертка, как правило, (rows + 2*floor(kernel_rows/2)) x (cols + 2*floor(kernel_cols/2)), где rows и cols - это строки и столбцы изображения/матрицы для фильтрации, а kernel_rows и kernel_cols - это строки и столбцы ядра.

Если вы хотите посмотреть, что на самом деле производит MATLAB, мы можем. Использование входного изображения/матрицы и ядро ​​я определил ранее, это то, что мы получаем:

>> I = reshape(1:25,5,5).'; %' 
>> K = [1 0 1; 1 0 1; 1 0 1]; 
>> out = conv2(I,K) 

out = 

    `1` `2` 4  6  8  4 `5` 
    7  9 18 22 26 13 15 
    18 21 42 48 54 27 30 
    33 36 72 78 84 42 45 
    48 51 102 108 114 57 `60` 
    37 39 78 82 86 43 45 
    `21` 22 44 46 48 24 25 

Обратите внимание, что я пометил расчеты примеров, которые мы сделали в выходе MATLAB с `` символов. Это согласуется с расчетами.

Теперь ваш вопрос в том, как 'valid' и 'same' фактор во всем этом. Где 'valid' и 'same' входят просто усеченные версии 'full' свертки. 'same' дает вам выходной размер такого же размера, что и фильтруемое изображение/матрица, и 'valid' дает вам такой вывод, что вы предоставляете только выходы, где ядро ​​было , полностью содержащееся внутри изображения/матрицы. Каждый раз, когда ядро ​​выходит за пределы по отношению к изображению/матрице, мы не включаем эти выходы как часть окончательного вывода. Проще говоря, 'valid' и 'same' используйте 'full' результат, но удалите некоторые части границы результата, чтобы облегчить выбор, который вы выберете.