我想知道R是否具有此功能,或者如何编码高斯平滑内核的2D离散版本。目标是使用它来平滑2D矩阵值。
答案 0 :(得分:1)
我写了一个函数来解决我的问题。这是我称之为 kernelsmooth 的功能。它需要三个参数,一个要平滑的数据矩阵,一个内核和一个布尔标志 norm ,如果为真,则通过其值的平均值对内核进行标准化(防止矩阵数据膨胀)。
kernelsmooth <- function(x, kern, norm=TRUE) {
# how many rows/cols of zeroes are used to pad.
width <- dim(kern)[1]
pad <- floor(width / 2)
# record the width and height the input data matrix
x_w <- ncol(x)
x_h <- nrow(x)
# Are we normalizing the kernel?
if (norm == TRUE) {
k <- kern / sum(abs(kern))
} else {
k <- kern
}
# pad all around the matrix an equal width of zeros
x_pad <- t(padzeros(data=x, nzeros=pad, side="both"))
x_pad <- t(padzeros(data=x_pad, nzeros=pad, side="both"))
# Pre-allocate the final (smoothed) data matrix
s <- matrix(0, nrow = x_h, ncol = x_w)
# Pre-allocate a temporary matrix for the iterative calculations
temp <- matrix(0, width, width)
# Loop through the data to apply the kernel.
for (col in 1:x_w ) {
for (row in 1:x_h ) {
temp <- x_pad[row:(row + width - 1), col:(col + width - 1)]
s[row,col] <- sum(k * temp)
}
}
# return the smoothed data
return(s)
}
一些例子:
不要平滑矩阵(应用类似于单位矩阵的身份内核)。
kernelsmooth(x =矩阵(2,5,5),kern =矩阵(c(0,0,0,0,1,0,0,0,0),3,3))
输出:
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 2 2 2 2 2 2
[2,] 2 2 2 2 2 2
[3,] 2 2 2 2 2 2
[4,] 2 2 2 2 2 2
[5,] 2 2 2 2 2 2
[6,] 2 2 2 2 2 2
平均平滑(如果自身及其邻居平均每个元素平滑):
kernelsmooth(x =矩阵(4,5,5),kern =矩阵(1,3,3))
输出:
[,1] [,2] [,3] [,4] [,5]
[1,] 1.777778 2.666667 2.666667 2.666667 1.777778
[2,] 2.666667 4.000000 4.000000 4.000000 2.666667
[3,] 2.666667 4.000000 4.000000 4.000000 2.666667
[4,] 2.666667 4.000000 4.000000 4.000000 2.666667
[5,] 1.777778 2.666667 2.666667 2.666667 1.777778
高斯平滑(各向同性平滑):
高斯&lt; - (c(1,4,7,4,1)%*%t(c(1,4,7,4,1))) kernelsmooth(x = matrix(5,8,8),kern = gauss)
输出:
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
[1,] 2.491349 3.321799 3.529412 3.529412 3.529412 3.529412 3.321799 2.491349
[2,] 3.321799 4.429066 4.705882 4.705882 4.705882 4.705882 4.429066 3.321799
[3,] 3.529412 4.705882 5.000000 5.000000 5.000000 5.000000 4.705882 3.529412
[4,] 3.529412 4.705882 5.000000 5.000000 5.000000 5.000000 4.705882 3.529412
[5,] 3.529412 4.705882 5.000000 5.000000 5.000000 5.000000 4.705882 3.529412
[6,] 3.529412 4.705882 5.000000 5.000000 5.000000 5.000000 4.705882 3.529412
[7,] 3.321799 4.429066 4.705882 4.705882 4.705882 4.705882 4.429066 3.321799
[8,] 2.491349 3.321799 3.529412 3.529412 3.529412 3.529412 3.321799 2.491349
答案 1 :(得分:0)
矩阵边缘的急剧下降,例如从3.529412到0,是坏消息。您需要将矩阵放大到边缘值尽可能接近零的大小。您可以通过计算每个矩阵的2D傅里叶变换来检查此语句的有效性,并将其与在较大版本上完成的相同变换进行比较。当应用于您的数据时,您还会看到更好的结果。