,一個選擇是使用im2col預處理圖像成塊,產生所有的鄰里一次。如果您需要多次訪問塊,這將特別有效。
鑑於圖像:
>> img = reshape(1:25,5,5)
img =
1 6 11 16 21
2 7 12 17 22
3 8 13 18 23
4 9 14 19 24
5 10 15 20 25
im2col
每個有效塊(這是很重要的......)轉換成一個矩陣的列:
C = im2col(img,[3,3])
C =
1 2 3 6 7 8 11 12 13
2 3 4 7 8 9 12 13 14
3 4 5 8 9 10 13 14 15
6 7 8 11 12 13 16 17 18
7 8 9 12 13 14 17 18 19
8 9 10 13 14 15 18 19 20
11 12 13 16 17 18 21 22 23
12 13 14 17 18 19 22 23 24
13 14 15 18 19 20 23 24 25
正如你所看到的, C
的第一列具有索引7
或img(2,2)
的鄰域值。下一個是索引8
或img(3,2)
,依此類推。抵消是因爲im2col
只給你有效的塊。如果這是你想要的,你只需要記住使用sub2ind在C
找到列號之前減去行/列標1
:
C_idx = sub2ind(size(img), 2-1, 2-1)
C_idx = 1
(如果你墊的圖像,指數和標有與原始圖像相同)
所以img(2,2)
附近的列索引是1
。
你實際上可以在這裏停下來。如果你申請的同一內核的所有查詢的街區,你可以只讓內核到行向量和繁殖,你要考慮這些C
列選擇:
kernel = ones(3)/9
kernel =
0.11111 0.11111 0.11111
0.11111 0.11111 0.11111
0.11111 0.11111 0.11111
kernel(:).' * C
ans =
7.0000 8.0000 9.0000 12.0000 13.0000 14.0000 17.0000 18.0000 19.0000
C_idx = [1:9]; % or randi(9, 1, 4), or any valid list of column numbers
k_vec = kernel(:).'; % turn kernel into a row vector
result = k_vec * C(:, C_idx);
result =
7.0000 8.0000 9.0000 12.0000 13.0000 14.0000 17.0000 18.0000 19.0000
如果您又不是高興的街區是列向量,真的希望他們是3×3塊,你可以重塑C
矩陣成3D矩陣:
D = reshape(C, 3, 3, []);
D =
ans(:,:,1) =
1 6 11
2 7 12
3 8 13
ans(:,:,2) =
2 7 12
3 8 13
4 9 14
ans(:,:,3) =
3 8 13
4 9 14
5 10 15
ans(:,:,4) =
6 11 16
7 12 17
8 13 18
ans(:,:,5) =
7 12 17
8 13 18
9 14 19
ans(:,:,6) =
8 13 18
9 14 19
10 15 20
ans(:,:,7) =
11 16 21
12 17 22
13 18 23
ans(:,:,8) =
12 17 22
13 18 23
14 19 24
ans(:,:,9) =
13 18 23
14 19 24
15 20 25
在這裏,您使用相同的指標,你之前使用列,但現在他們「重指數進入第三個層面,例如:
>> D(:, :, 1)
ans =
1 6 11
2 7 12
3 8 13
給你同一街區作爲C(:, 1)
。
您打算如何處理這些區塊?這聽起來很可疑,就像你試圖以艱難的方式進行卷積。 – beaker
關於卷積的'硬'方式你是對的。由於我有數千個不同的內核,'convn'將會非常昂貴。我使用的方法只考慮塊而不是整個圖像。 'convn(image,kernels)'會很耗時。也許你有一個建議? –
您應該首先使用'conv2'對基準解決方案進行基準測試。除非你的形象很大,而你只使用少量的社區,否則很難被打敗。 – beaker