0

If I have a 2d matrix and I would like to apply some sort of filter (e.g. dilate, erode, sobel edge detection) given some filter matrix:

f = matrix(c(0,1,0,
             1,1,1,
             0,1,0), 3)

What is the most efficient way to apply it to a matrix.

For looping over each pixel seems too inefficient:

for(i in 2:nrow(mat)){
    for(j in 2:ncol(mat)){
        //Apply filter to pixel i,j
    }
}
Omar Wagih
  • 8,504
  • 7
  • 59
  • 75
  • 3
    This is impossible to answer without a _specific_ function to apply to each pixel. – joran Apr 19 '13 at 16:20
  • Maybe You can be inspired from `kernel2dsmooth` in `SpatialVx` package... – agstudy Apr 19 '13 at 16:35
  • `focal()` in the **raster** package supports pretty general operations in which you want to calculate, for each cell, a function of the values in its neighborhood. [Here is one example](http://stackoverflow.com/questions/9931706/sliding-window-function-in-r/9933326#9933326) and [here is another](http://stackoverflow.com/questions/11059104/given-a-2d-numeric-height-map-matrix-in-r-how-can-i-find-all-local-maxima/11059479#11059479). – Josh O'Brien Apr 19 '13 at 16:56
  • 1
    @JoshO'Brien reading the comments in your first link, looks like the `focal` is moved from `raster` and also it is inefficient. Maybe I miss something. – agstudy Apr 19 '13 at 17:04
  • 1
    @agstudy -- No. You misread that first comment. Re: efficiency, that's always relative. These 2-D neighborhood operations are generally relatively slow (I believe b/c for each cell they must access several non-contiguous blocks of memory), and there's no way to tell from the OP's question just how fast they'll need it to be. Plus, do you know of anything faster (in R)? – Josh O'Brien Apr 19 '13 at 17:09
  • @JoshO'Brien No I don't know faster. Thanks for your clarification(+1)! – agstudy Apr 19 '13 at 17:16

2 Answers2

1

It depends what you are doing I guess!! You could apply a function to every cell of a matrix just by calling a function that operates on your matrix. Something like this:

f1 <- function(x){ x*2 }

m <- matrix(sample(25,9),nrow=3)
m
#    [,1] [,2] [,3]
#[1,]   24   16    2
#[2,]   11   10    5
#[3,]   23   19    8

## Operates on all cells as R treats the matrix like a vector
f1(m)
#    [,1] [,2] [,3]
#[1,]   48   32    4
#[2,]   22   20   10
#[3,]   46   38   16

Or if this kind of construct won't work for you then you could use apply to apply a function across each row/column of a matrix:

apply( m , 1:2 , function(x){ x * 10 } )
#    [,1] [,2] [,3]
#[1,]  240  160   20
#[2,]  110  100   50
#[3,]  230  190   80

But like @joran said, it depends what you want to do!

Simon O'Hanlon
  • 58,647
  • 14
  • 142
  • 184
0

there is function called convolve, but I guess it works only for 1D signals. So you are left with fft option. Do the operation in frequency domain and convert back to time domain.

Hard to show exact steps without knowing expected input/output, but try this:

Re( fft( (1/dimension) * fft(signal) * fft(f), inverse=T))
Nishanth
  • 6,932
  • 5
  • 26
  • 38