Some methods: fast and slow, coarse and smooth.
Setting each pixel to the mean or standard deviation of the pixels in a surrounding window is a common requirement. For rectangular windows, IM has built-in operations, but the time is proportional to the window size so is slow for large windows.
A number of methods are given below. They fall into two groups:
For each method, we show: the mean and SD results; the auto-levelled SD and a portion of this, enlarged.
set SRC=toes.png |
%IMG7%magick ^ %SRC% ^ ( +clone ^ -statistic mean 21x21 ^ +write wms_mn1.png +delete ) ^ -statistic standard_deviation 21x21 ^ wms_sd1.png |
|
For clarity, auto-level the SD. %IMG7%magick ^ wms_sd1.png ^ -channel RGB -auto-level +channel ^ +write wms_sd1a.png ^ -crop 100x100+16+100 +repage ^ -scale 400%% ^ wms_sd1as.png |
Blockiness is evident in the SD images.
Specifying a radius and a large sigma caps the effect.
set BLR_RAD=10 set BLR_SIG=64000 %IMG7%magick ^ %SRC% ^ ( -clone 0 ^ -evaluate Pow 2 ^ -gaussian-blur %BLR_RAD%x%BLR_SIG% ^ ) ^ ( -clone 0 ^ -gaussian-blur %BLR_RAD%x%BLR_SIG% ^ +write wms_mnc1.png ^ -evaluate Pow 2 ^ ) ^ -delete 0 ^ -alpha off ^ -compose MinusSrc -composite ^ -evaluate Pow 0.5 ^ wms_sdc1.png |
|
For clarity, auto-level the SD. %IMG7%magick ^ wms_sdc1.png ^ -channel RGB -auto-level +channel ^ +write wms_sdc1a.png ^ -crop 100x100+16+100 +repage ^ -scale 400%% ^ wms_sdc1as.png |
This method is explained on the Integral images page.
call %PICTBAT%integMeanSd ^ %SRC% wms_mni1.png wms_sdi1.png 21x21 |
|
For clarity, auto-level the SD. %IMG7%magick ^ wms_sdi1.png ^ -channel RGB -auto-level +channel ^ +write wms_sdi1a.png ^ -crop 100x100+16+100 +repage ^ -scale 400%% ^ wms_sdi1as.png |
This method is explained on the Integral images page.
call %PICTBAT%iiMeanSd ^ %SRC% wms_mnii1.png wms_sdii1.png 21x21 |
|
For clarity, auto-level the SD. %IMG7%magick ^ wms_sdii1.png ^ -channel RGB -auto-level +channel ^ +write wms_sdii1a.png ^ -crop 100x100+16+100 +repage ^ -scale 400%% ^ wms_sdii1as.png |
The windowed mean from "-blur" has pixels near the center of the window weighted more than those near the edge.
set BLR_RAD=0 set BLR_SIG=6.6 %IMG7%magick ^ %SRC% ^ ( -clone 0 ^ -evaluate Pow 2 ^ -blur %BLR_RAD%x%BLR_SIG% ^ ) ^ ( -clone 0 ^ -blur %BLR_RAD%x%BLR_SIG% ^ +write wms_mnb1.png ^ -evaluate Pow 2 ^ ) ^ -delete 0 ^ -alpha off ^ -compose MinusSrc -composite ^ -evaluate Pow 0.5 ^ wms_sdb1.png |
|
For clarity, auto-level the SD. %IMG7%magick ^ wms_sdb1.png ^ -channel RGB -auto-level +channel ^ +write wms_sdb1a.png ^ -crop 100x100+16+100 +repage ^ -scale 400%% ^ wms_sdb1as.png |
This "Gaussian standard deviation" is a useful edge detector, so we implement it as a script. See Gain and bias: Gaussian standard deviation.
The script resizeMeanSd.bat works by resizing the image down, then back up again. For heavy blurs, this is fast, but creates aliased results, a stepped appearance.
set BLR_SIG=6.6 call %PICTBAT%resizeMeanSd ^ %SRC% wms_mnr1.png wms_sdr1.png ^ %BLR_SIG%x%BLR_SIG% |
|
For clarity, auto-level the SD. %IMG7%magick ^ wms_sdr1.png ^ -channel RGB -auto-level +channel ^ +write wms_sdr1a.png ^ -crop 100x100+16+100 +repage ^ -scale 400%% ^ wms_sdr1as.png |
The sloping line near the bottom of both SD images has a stepped appearance. This effect is reduced by using a cubic, quadratic or spline filter. We show the mean, and the auto-levelled standard deviation.
set rmnsdFILTER=Cubic call %PICTBAT%resizeMeanSd ^ %SRC% wms_mnr2.png wms_sdr2.png ^ %BLR_SIG%x%BLR_SIG% %IMG7%magick ^ wms_sdr2.png ^ -channel RGB -auto-level +channel ^ wms_sdr2.png |
|
set rmnsdFILTER=Quadratic call %PICTBAT%resizeMeanSd ^ %SRC% wms_mnr3.png wms_sdr3.png ^ %BLR_SIG%x%BLR_SIG% %IMG7%magick ^ wms_sdr3.png ^ -channel RGB -auto-level +channel ^ wms_sdr3.png |
|
set rmnsdFILTER=Spline call %PICTBAT%resizeMeanSd ^ %SRC% wms_mnr4.png wms_sdr4.png ^ %BLR_SIG%x%BLR_SIG% %IMG7%magick ^ wms_sdr4.png ^ -channel RGB -auto-level +channel ^ wms_sdr4.png set rmnsdFILTER= |
Compare Statistic with Circular blur and Integral (cumulhisto):
%IMG7%magick compare -metric RMSE ^ wms_mn1.png wms_mnc1.png NULL: |
0 (0) |
%IMG7%magick compare -metric RMSE ^ wms_mn1.png wms_mni1.png NULL: |
0.242177 (3.69539e-06) |
These three methods are virtually identical.
Compare the two integral images methods:
%IMG7%magick compare -metric RMSE ^ wms_mni1.png wms_mnii1.png NULL: |
360.401 (0.00549936) |
This difference isn't trivial. The reason is that the methods treat edges differently. If we compare just the central 75% of each:
%IMG7%magick ^ wms_mni1.png ^ wms_mnii1.png ^ -gravity Center -crop 75x75%%+0+0 +repage ^ -metric RMSE -compare -format %%[distortion] ^ info: |
3.21502e-06 |
Compare Statistic with Gaussian blur:
%IMG7%magick compare -metric RMSE ^ wms_mn1.png wms_mnb1.png NULL: |
384.923 (0.00587355) |
Compare Statistic with Resize:
%IMG7%magick compare -metric RMSE ^ wms_mn1.png wms_mnr1.png NULL: |
843.843 (0.0128762) |
Compare Statistic with Cubic Resize:
%IMG7%magick compare -metric RMSE ^ wms_mn1.png wms_mnr2.png NULL: |
1841.85 (0.0281048) |
We compare the performance of some methods using the same large blur on a large image.
set LGE_SRC=AGA_1434_gms.tiff %IMG7%magick identify %LGE_SRC%
AGA_1434_gms.tiff TIFF 4924x7378 4924x7378+0+0 16-bit sRGB 166.02MiB 0.000u 0:00.001
Method | Time
d hh:mm:ss |
---|---|
"-statistic" method. %IMG7%magick ^ %LGE_SRC% ^ -statistic mean 61x61 ^ wms_ls_stat.miff |
0 00:18:42 |
Integral method (using cumulhisto). call %PICTBAT%integMeanSd ^ %LGE_SRC% wms_ls_mni1.miff . 61x61 |
0 00:05:40 |
Blur method. set BLR_RAD=0 set BLR_SIG=19.8 %IMG7%magick ^ %LGE_SRC% ^ -blur %BLR_RAD%x%BLR_SIG% ^ wms_sdb2.miff |
0 00:03:27 |
Integral method (using integim). call %PICTBAT%iiMeanSd ^ %LGE_SRC% wms_ls_mnii1.miff . 61x61 |
0 00:00:12 |
Resize method. set BLR_SIG=19.8 call %PICTBAT%resizeMeanSd ^ %LGE_SRC% wms_mnr1.miff . %BLR_SIG%x%BLR_SIG% |
0 00:00:22 |
There is an enormous variation in speed: a factor of 1000.
For small images where performance isn't an issue:
For large blurs of large images, where performance is an issue:
For convenience, .bat scripts are also available in a single zip file. See Zipped BAT files.
rem From image %1 rem write windowed mean %2 rem and standard deviation %3 rem with window size %4 rem using the resize method. @rem @rem Also uses: @rem rmnsdFILTER @rem @rem @rem Updated: @rem 5-August-2022 for IM v7. @rem @if "%4"=="" findstr /B "rem @rem" %~f0 & exit /B 1 @setlocal enabledelayedexpansion @call echoOffSave call %PICTBAT%setInOut %1 rmnsd set OUTMEAN=%2 if "%OUTMEAN%"=="." set OUTMEAN= if "%OUTMEAN%"=="" set OUTMEAN= set OUTSD=%3 if "%OUTSD%"=="." set OUTSD= if "%OUTSD%"=="" set OUTSD= set WINDIMS=%4 set WW= for /F "usebackq" %%L in (`%IMG7%magick identify ^ -format "WW=%%w\nHH=%%h\n" ^ %INFILE%`) do set %%L if "%WW%"=="" exit /B 1 call parseXxY2 %WW% %HH% rmnsd %WINDIMS% echo %0: rmnsd_X=%rmnsd_X% rmnsd_Y=%rmnsd_Y% for /F "usebackq" %%L in (`%IMG7%magick identify ^ -format "RW=%%[fx:int(%WW%/2/%rmnsd_X%+0.5)]\nRH=%%[fx:int(%HH%/2/%rmnsd_Y%+0.5)]\n" ^ xc:`) do set %%L if %RW%==0 set RW=1 if %RH%==0 set RH=1 echo %0: rmnsd_X=%rmnsd_X% rmnsd_Y=%rmnsd_Y% RW=%RW% RH=%RH% if "%OUTMEAN%"=="" ( set wrOUTMEAN= ) else ( set wrOUTMEAN=+write %OUTMEAN% ) if "%rmnsdFILTER%"=="" ( set sFILT= ) else ( set sFILT=-filter %rmnsdFILTER% ) if "%OUTSD%"=="" ( %IMG7%magick ^ %INFILE% ^ %sFILT% ^ -resize "%RW%x%RH%^!" -resize "%WW%x%HH%^!" ^ %wrOUTMEAN% ^ NULL: ) else ( %IMG7%magick ^ %INFILE% ^ %sFILT% ^ ^( -clone 0 ^ -evaluate Pow 2 ^ -resize "%RW%x%RH%^!" -resize "%WW%x%HH%^!" ^ ^) ^ ^( -clone 0 ^ -resize "%RW%x%RH%^!" -resize "%WW%x%HH%^!" ^ %wrOUTMEAN% ^ -evaluate Pow 2 ^ ^) ^ -delete 0 ^ -alpha off ^ -compose MinusSrc -composite ^ -evaluate Pow 0.5 ^ %OUTSD% ) call echoRestore endlocal
All images on this page were created by the commands shown, using:
%IMG7%magick -version
Version: ImageMagick 7.1.0-42 Q16-HDRI x64 396d87c:20220709 https://imagemagick.org Copyright: (C) 1999 ImageMagick Studio LLC License: https://imagemagick.org/script/license.php Features: Cipher DPC HDRI OpenCL Delegates (built-in): bzlib cairo freetype gslib heic jng jp2 jpeg jxl lcms lqr lzma openexr pangocairo png ps raqm raw rsvg tiff webp xml zip zlib Compiler: Visual Studio 2022 (193231332)
To improve internet download speeds, some images may have been automatically converted (by ImageMagick, of course) from PNG or TIFF or MIFF to JPG.
Source file for this web page is windmnsd.h1. To re-create this web page, execute "procH1 windmnsd".
This page, including the images, is my copyright. Anyone is permitted to use or adapt any of the code, scripts or images for any purpose, including commercial use.
Anyone is permitted to re-publish this page, but only for non-commercial use.
Anyone is permitted to link to this page, including for commercial use.
Page version v1.0 11-June-2017.
Page created 05-Aug-2022 18:40:45.
Copyright © 2022 Alan Gibson.