Code covered by the BSD License  

Highlights from
BlockMean

4.66667

4.7 | 3 ratings Rate this file 15 Downloads (last 30 days) File Size: 9.8 KB File ID: #24812
image thumbnail

BlockMean

by Jan Simon

 

21 Jul 2009 (Updated 05 Nov 2010)

Mean of rectangular submatrices, fast C-Mex (no running mean)

| Watch this File

File Information
Description

BLOCKMEAN - Fast mean of rectangular submatrices

The mean of V*W elements along the 1st and 2nd dimension is calculated. This is no running mean filter: The sizes of the 1st and 2nd dimension are reduced by the factors V and W.
I use this as cheap anti-aliasing of RGB images, therefore it is implemented for DOUBLE and UINT8 input.

Y = BlockMean(X, V, W)
Input:
  X: UINT8 or DOUBLE array of any size.
  V, W: 2 scalars as size of the window. Each element of the output is the
     mean over V*W neighbouring elements of the input.
     V and W are limited to 256 to limit memory usage.
Output:
  Y: UINT8 or DOUBLE array, the 1st and 2nd dimensions are V and W times shorter:
     [FIX(X / V) x FIX(Y / W) x (further dims...)]
     If the size of the 1st or 2nd dimension is not a multiple of V and W, the
     remaining elements at the end are skipped.

E.g. for 4x4 blocks of a 1024x768x3 double array, this MEX implementation is about 5 times faster than the corresponding Matlab method (Matlab 2009a, 1.5GHz Pentium-M, WinXP, MSVC 2008):
  reshape(sum(sum(reshape(X, 4, 256, 4, 192, 3), 1), 3), 256, 192, 3).
Run the unit-test uTest_BlockMean to check validity and speed.

Tested with: LCC v2.4, v3.8, Open Watcom 1.8, BCC 5.5, MSVC 2008, Matlab 6.5, 7.7, 7.8, WinXP 32 bit
Compatibility assumed: Linux, MacOS, 64bit.

Pre-compiled Mex: http://www.n-simon.de/mex

I'd appreciate suggestions for improvements and bug reports sent through email - thanks.

MATLAB release MATLAB 7.8 (R2009a)
Tags for This File  
Everyone's Tags
antialiasing, array, average, block(2), image processing, matrix, mean, rectangular
Tags I've Applied
Add New Tags Please login to tag files.
Please login to add a comment or rating.
Comments and Ratings (7)
28 Jun 2012 Jan Simon

Does your question concern the program BlockMean? If not, please discuss this in a Matlab forum.

28 Jun 2012 M@lik Ali

Hi all,

I want to divide image into 4x4 block, and want to keep the record of each block separately. also i want to know that how many blocks made.

Thanks in advance.

25 May 2012 Simon

Superb. Exactly what I was looking for. Works great, thanks.

10 Apr 2012 Jan Simon

Thanks you very much for this report, Andreas. I currently try to reproduce the problem and will fix the code as soon as possible.

27 Mar 2012 Andreas

Hello, first of all, thank you very much for providing the Mex-File.

Is it possible, that the Mex-File doesn't work on huge matrices (i.e. 50.000x50.000 in size)?

If I do
A=rand(20000);
B=BlockMean(A,10);

it works. Same with A=rand(50000); does not work. Returns a matrix with zeros only.
It would be a great help for me if you could possibly provide a version that can handle matrices up to 60000x60000...

thank you so much for any advice,

Andy

28 Oct 2010 Jan Simon

@Dominik: Thanks for the helpful comments!
Unfortunately I do not have a Linux machine for testing and I've included the wrong uppercase "-std=C99" in all my submissions.
As far as I understand from the very impressive document you've cited, Linux systems run with 80bit precision as default. Therefore I'll submit an updated version, which omits the FPU control under linux completely.
If the increase of the precision from 64 to 80 bits is omitted on Windows machines, the accuracy of the method equals at least the results of SUM obtained inside Matlab. Therefore the extended precision is more a gimmick than a necessary feature for BlockMean.

27 Oct 2010 Dominik Brands

Hi,
I want to use your BlockMean-Function with Matlab on Linux. But I got two errors on compiling.
First one using
mex -O CFLAGS="\$CFLAGS -std=C99" BlockMean.c
as written in the header of BlockMean.c results in
>> cc1: error: unrecognized command line option "-std=C99"
>> mex: compile of ' "BlockMean.c"' failed.
Okay, this error I correct by myself using the option "c99" instead of "C99" since Linux is case sensitive.
But then I get a new error
>> BlockMean.c: In function ‘mexFunction’:
>> BlockMean.c:181: warning: implicit declaration of function ‘_control87’
>> BlockMean.c:181: error: ‘MCW_PC’ undeclared (first use in this function)
>> BlockMean.c:181: error: (Each undeclared identifier is reported only once
>> BlockMean.c:181: error: for each function it appears in.)
>> BlockMean.c:182: error: ‘PC_64’ undeclared (first use in this function)
using the command
mex -O CFLAGS="\$CFLAGS -std=c99" BlockMean.c
For this I found a hint at
http://www.fortran-2000.com/ArnaudRecipes/CompilerTricks.html .
The varaibels MCW_PC and PC_64 are only available at windows. On the mentioned homepage there was show a trick for correct this under thetopic "Floating point precision mode". I do following changes to your code in BlockMean.c
The code-lines after "// Set the floating point precision:" I replace by the code given at the homepage. Additionally I remove the calls to "control87" under comment "// Set precision to 64 bit.." and "// Reset floating point precision"
and use instead the new functions "x86_SetPrecision" and "x86_RestorePrecision".
After compiling again no errors occur and the test with TestBlockMean was succesfully due to the messages from "TestBlockMean"

I hope this modifications was correct for you.
Regards
Dominik

Updates
12 Mar 2010

64 bit addressing supported, rectangular blocks: V ~= W, isEqualTol included in the test function

05 Nov 2010

No need to enable 80bit extended precision under Linux. This avoids troubles during the compilation.

Contact us