Nothing
# 2D convolution-based linear filter for images and matrix data
# Copyright (c) 2007-2015, Andrzej OleÅ›, Gregoire Pau, Oleg Sklyar
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public License
# as published by the Free Software Foundation; either version 2.1
# of the License, or (at your option) any later version.
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Lesser General Public License for more details.
# LGPL license wording: http://www.gnu.org/licenses/lgpl.html
## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
filter2 = function(x, filter, boundary = c("circular", "replicate")) {
if ( is.numeric(boundary) ) {
val = boundary
boundary = "linear"
}
else
boundary = match.arg(boundary)
validObject(x)
validObject(filter)
d = dx = dim(x)
df = dim(filter)
dnames = dimnames(x)
## do not enforce odd filter dimensions in the special case when filter size
## equals image size
if ( any(dx[1:2]!=df) || boundary!="circular" ) {
if (any(df%%2==0)) stop("dimensions of 'filter' matrix must be odd")
if (any(dx[1:2]<df)) stop("'filter' dimensions cannot exceed dimensions of 'x'")
}
cf = df%/%2
of = df%%2
res = x
switch(boundary,
## default mode just wraps around edges
circular = {
x = imageData(x)
},
## pad with a given value
linear = {
dx[1:2] = dx[1:2] + cf[1:2]
if ( length(dx)>2 && length(val)==prod(dx[-(1:2)]) ) {
# Higher dim array with matching linear boundry values
xpad = array(rep(val, each=prod(dx[1:2])), dim = dx)
} else {
if ( length(val)>1 ) {
warning('The boundary value length does not match the number of frames, only the first element of boundary will be used')
}
xpad = array(val[1], dx)
}
# The do.call and arguments as a list of dimensions is to take are of arrays of unknown dimension
x = do.call("[<-", c(quote(xpad), lapply(d, function(x) enquote(1:x)), quote(x)) )
},
replicate = {
x = imageData(x)
dx[1:2] = dx[1:2] + df[1:2] - 1L
rep.dim <- function(x, dim, index, times) {
xs <- asub(x, idx=index, dims=dim, drop=FALSE)
ds <- dim(xs)
ds[dim] <- times
if ( dim==2L ) {
xs <- split(xs, ceiling(seq_along(xs)/ds[1L]))
xs <- sapply(xs, FUN=rep, times=times)
} else {
xs <- rep(xs, each=times)
}
array(xs, dim=ds)
}
# Add left and right colums
lc <- rep.dim(x, 2L, 1L, cf[2L])
rc <- rep.dim(x, 2L, d[2L], cf[2L])
x <- abind::abind(x, rc, lc, along=2L)
# Add top and bottom rows
tr <- rep.dim(x, 1L, 1L, cf[1L])
br <- rep.dim(x, 1L, d[1L], cf[1L])
x <- abind::abind(x, br, tr, along=1L)
}
)
## create fft filter matrix
wf = matrix(0.0, nrow=dx[1L], ncol=dx[2L])
wf[c(if (cf[1L]>0L) (dx[1L]-cf[1L]+1L):dx[1L] else NULL, 1L:(cf[1L]+of[1L])),
c(if (cf[2L]>0L) (dx[2L]-cf[2L]+1L):dx[2L] else NULL, 1L:(cf[2L]+of[2L]))] = filter
wf = fftw2d(wf)
pdx = prod(dx[1:2])
.filter = function(xx) Re(fftw2d(fftw2d(xx)*wf, inverse=1)/pdx)
## convert to a frame-based 3D array
if ( length(dx) > 2L ) {
y = apply(x, 3:length(dx), .filter)
dim(y) = dx
}
else {
y = .filter(x)
}
if ( boundary!="circular" ) {
y = asub(y, list(1:d[1L], 1:d[2L]), 1:2)
}
dimnames(y) = dnames
imageData(res) <- y
res
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.