Ich implementiere derzeit die filter2
MATLAB-Funktion in R, die eine Methode für 2D-Faltung ist. Ich habe mich für die 2D-Faltungsarbeit entschieden, aber wie die "gültige" Option in filter2 funktioniert, ist mir nicht ganz klar.Implementierung der MATLAB-Filter2-Funktion in R
Die MATLAB-Funktion ist hier beschrieben: http://se.mathworks.com/help/matlab/ref/filter2.html
Meine Implementierung:
filter2D <- function(img, window) {
# Algoritm for 2D Convolution
filter_center_index_y <- median(1:dim(window)[1])
filter_max_index_y <- dim(window)[1]
filter_center_index_x <- median(1:dim(window)[2])
filter_max_index_x <- dim(window)[2]
# For each position in the picture, 2D convolution is done by
# calculating a score for all overlapping values within the two matrices
x_min <- 1
x_max <- dim(img)[2]
y_min <- 1
y_max <- dim(img)[1]
df <- NULL
for (x_val in c(x_min:x_max)){
for (y_val in c(y_min:y_max)){
# Distanced from cell
img_dist_left <- x_val-1
img_dist_right <- x_max-x_val
img_dist_up <- y_val-1
img_dist_down <- y_max-y_val
# Overlapping filter cells
filter_x_start <- filter_center_index_x-img_dist_left
if (filter_x_start < 1) {
filter_x_start <- 1
}
filter_x_end <- filter_center_index_x+img_dist_right
if (filter_x_end > filter_max_index_x) {
filter_x_end <- filter_max_index_x
}
filter_y_start <- filter_center_index_y-img_dist_up
if (filter_y_start < 1) {
filter_y_start <- 1
}
filter_y_end <- filter_center_index_y+img_dist_down
if (filter_y_end > filter_max_index_y) {
filter_y_end <- filter_max_index_y
}
# Part of filter that overlaps
filter_overlap_matrix <- filter[filter_y_start:filter_y_end, filter_x_start:filter_x_end]
# Overlapped image cells
image_x_start <- x_val-filter_center_index_x+1
if (image_x_start < 1) {
image_x_start <- 1
}
image_x_end <- x_val+filter_max_index_x-filter_center_index_x
if (image_x_end > x_max) {
image_x_end <- x_max
}
image_y_start <- y_val-filter_center_index_y+1
if (image_y_start < 1) {
image_y_start <- 1
}
image_y_end <- y_val+filter_max_index_y-filter_center_index_y
if (image_y_end > y_max) {
image_y_end <- y_max
}
# Part of image that is overlapped
image_overlap_matrix <- img[image_y_start:image_y_end, image_x_start:image_x_end]
# Calculating the cell value
cell_value <- sum(filter_overlap_matrix*image_overlap_matrix)
df = rbind(df,data.frame(x_val,y_val, cell_value))
}
}
# Axis labels
x_axis <- c(x_min:x_max)
y_axis <- c(y_min:y_max)
# Populating matrix
filter_matrix <- matrix(df[,3], nrow = x_max, ncol = y_max, dimnames = list(x_axis, y_axis))
return(filter_matrix)
}
Ausführen des Verfahrens:
> image
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 1 2 3 4 5 6
[2,] 7 8 9 10 11 12
[3,] 13 14 15 16 17 18
[4,] 19 20 21 22 23 24
[5,] 25 26 27 28 29 30
[6,] 31 32 33 34 35 36
> filter
[,1] [,2] [,3]
[1,] 1 2 1
[2,] 0 0 0
[3,] -1 -2 -1
> filter2D(image, filter)
1 2 3 4 5 6
1 -22 -32 -36 -40 -44 -35
2 -36 -48 -48 -48 -48 -36
3 -36 -48 -48 -48 -48 -36
4 -36 -48 -48 -48 -48 -36
5 -36 -48 -48 -48 -48 -36
6 76 104 108 112 116 89
Dies ist die gleiche Ausgabe, die FILTER2 (Bild, Filter) erzeugt in Matlab jedoch, wenn die Option 'gültig' hinzugefügt wird, wird die folgende Ausgabe generiert:
-48 -48 -48 -48
-48 -48 -48 -48
-48 -48 -48 -48
-48 -48 -48 -48
Es ist nicht ganz offensichtlich, wie filter2 mit der Option 'valid' das erzeugt. Benutzt es nur die Mittelwerte? Oder macht es etwas anspruchsvoller?
Minor note: Ihr ursprünglicher Code verwendete 'input' innerhalb der Faltungssumme, wenn Ihre Funktionsdefinition 'img' verwendet wurde. Ich habe im Code "input" in "img" umbenannt und es funktioniert jetzt. – rayryeng