2
$\begingroup$
SeedRandom[0];
n = 5;
(m = N @ RandomInteger[{1, 3}, {n, n}]) // MatrixForm

enter image description here

result1 = MeanFilter[m, 1] // MatrixForm

enter image description here

Since I want to write my own filters I tried to replicate the above

SeedRandom[0];
n = 5;
(m = ArrayPad[N @ RandomInteger[{1, 3}, {n, n}], 1, x]) // MatrixForm

enter image description here

(t = Table[m[[r ;; r + 2, c ;; c + 2]], {r, 1, n}, {c, 1, n}]) // MatrixForm

enter image description here

result2 = Map[Mean, Map[Cases[#, _?NumberQ, 2] &, t, {2}], {2}] // MatrixForm;

result1 == result2

True

So far so good.

The problem is that the inbuilt MeanFilter is ten times faster as my code.

How can i accelerate my code?

$\endgroup$
  • $\begingroup$ I don't have MMA in front of me but I think Developer`PartitionMap may help you. $\endgroup$ – mfvonh Oct 28 '14 at 20:40
5
$\begingroup$

Another way is to use ListConvolve:

neighbors = 
  ListConvolve[{{1, 1, 1}, {1, 1, 1}, {1, 1, 1}}, m, {2, 2}, 0];
neighborCount = 
  ListConvolve[{{1, 1, 1}, {1, 1, 1}, {1, 1, 1}}, ConstantArray[1, Dimensions@m], {2, 2}, 0];

neighbors/neighborCount == MeanFilter[m, 1]

True

However, for speed it's not so good to go over the entire matrix in order to figure out how many neighbors each piece has. Instead we fix that part explicitly:

{dimx, dimy} = Dimensions[m];
ker = {{1, 1, 1}, {1, 1, 1}, {1, 1, 1}}/9 // N;
mean = ListConvolve[ker, m, {2, 2}, 0];
mean[[{1, 1, dimy, dimy}, {1, dimx, 1, dimx}]] = 
  9 mean[[{1, 1, dimy, dimy}, {1, dimx, 1, dimx}]]/4;
mean[[1, 2 ;; dimx - 1]] = 9 mean[[1, 2 ;; dimx - 1]]/6;
mean[[dimy, 2 ;; dimx - 1]] = 9 mean[[dimy, 2 ;; dimx - 1]]/6;
mean[[2 ;; dimy - 1, 1]] = 9 mean[[2 ;; dimy - 1, 1]]/6;
mean[[2 ;; dimy - 1, dimx]] = 9 mean[[2 ;; dimy - 1, dimx]]/6;
mean == MeanFilter[m, 1]

True

When I compare MeanFilter and my last method on a matrix of size $10000\times 10000$ I get that MeanFilter consistently takes 6.9 seconds and the last method takes on average 6.7 seconds. NICE!

$\endgroup$
  • 1
    $\begingroup$ Nice but ... the MeanFilter[] programmer will get fired .. $\endgroup$ – Dr. belisarius Oct 29 '14 at 2:19
  • $\begingroup$ BTW, Dera Pickett, How to understand the result of ListCorrelate[{{u, v}, {p, q}}, {{a, b, c}, {d, e, f}, {g, h, i}}, {3,1}] ,where $\{K_L,K_R\}=\{3,1\}$ $\endgroup$ – xyz Oct 29 '14 at 7:20
  • $\begingroup$ @ShutaoTang It would be better to ask that as a separate question, I am sure many others would like a good explanation of it. $\endgroup$ – C. E. Nov 2 '14 at 14:51
  • 1
    $\begingroup$ @Pickett,got it! :-) $\endgroup$ – xyz Nov 2 '14 at 23:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.