Median resize

Questions and postings pertaining to the usage of ImageMagick regardless of the interface. This includes the command-line utilities, as well as the C and C++ APIs. Usage questions are like "How do I use ImageMagick to create drop shadows?".
Post Reply
msundman
Posts: 2
Joined: 2017-03-22T13:55:48-07:00
Authentication code: 1151

Median resize

Post by msundman » 2017-03-22T14:26:00-07:00

I've been reading the examples but can't make head or tails of this thing, which is probably simple for someone much smarter than me.. :)

The end result I seek is to coalesce each 5x5 pixel square into 1 pixel that's the median of those 25 pixels. (The median of input pixels {0,0}-{4,4} become output pixel {0,0}, the median of input pixels {5,0}-{9,4} become output pixel {1,0}, etc.) The resulting image will be 1/5 width and 1/5 height of the input image.

My first idea was to use -fx with Median on all pixels and then a Point resize, but I can't figure out how to use Median on an area.

My second idea was to duplicate the image 24 times, shifting it a bit each time, and then running a Median on the sequence, but I can't wrap my head around how that works. (And this also might be quite inefficient?)

If nothing else I could just use the API to extract raw pixels using one of the programming language bindings and do it manually, but I would prefer to do the operation as efficiently as possible, and in a "magick way" if possible.

(I could use any version, but currently using 6.8.9-9 Q16 x86_64 2017-03-14.)

snibgo
Posts: 12161
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Median resize

Post by snibgo » 2017-03-22T14:46:05-07:00

Here's a simple way to do that. Windows BAT syntax for IM v6.

(When asking questions, please always state your version of IM, and platform.)

Code: Select all

convert ^
  in.png ^
  -statistic median 5x5 ^
  -crop 5x +repage ^
  -crop 1x+1+0 +repage ^
  +append ^
  -crop x5 +repage ^
  -crop x1+0+1 +repage ^
  -append ^
  +write info: ^
  out.png
"-statistic median 5x5" calculates the median of every pixel, so does 25 times as much work as you want.

Then we remove the extra columns of pixels, that we don't need. "-crop 5x" chops the image into many images, each 5 pixels wide. From each, we want only the central pixel, and -crop 1x+1+1 does that, making a number of 1xH pixel images. We append these sideways.

Similarly, we remove rows we don't need.

This takes 49 seconds for a 7378x4924 image. There may be a quicker way.

EDIT: corrected bugs.
snibgo's IM pages: im.snibgo.com

User avatar
fmw42
Posts: 25566
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Median resize

Post by fmw42 » 2017-03-22T15:09:34-07:00

Perhaps this is simpler, assuming I understand what you want.

Suppose your image is 100x100. Then 100/5=20.

Code: Select all

convert image -statistic median 5x5 -sample 20x20 result
Or since 1/5 = 20%, you can use that for any size image.

Code: Select all

convert image -statistic median 5x5 -sample 20%x20% result
If your image is not a multiple of your filter size, then in Unix syntax:

in IM 6, do

Code: Select all

filt=5
declare `convert -ping image -format "dim=%[fx:floor(w/$filt)]x%[fx:floor(h/$filt)]" info:`
convert image -statistic median ${filt}x${filt} -sample $dim result
in IM 7, you can do

Code: Select all

filt=5
magick image -statistic median ${filt}x${filt} -sample "%[fx:floor(w/$filt)]x%[fx:floor(h/$filt)]" result
The resulting image will only contain pixels corresponding to whole blocks of filt x filt medians.

See
http://www.imagemagick.org/script/comma ... php#sample

The default pixel used from the median image is subsampled at the center of the filt x filt region when computed this way. But you can use the -define to change the location.

msundman
Posts: 2
Joined: 2017-03-22T13:55:48-07:00
Authentication code: 1151

Re: Median resize

Post by msundman » 2017-03-22T15:16:55-07:00

Ooh, thank you so much!

Hmm..

Code: Select all

$ convert a.jpg +write info: -statistic median 5x5 -crop 5x +repage -crop 1x+1+1 +repage +append -crop x5 +repage -crop x1+1+1 +repage -append +write info: b.jpg
a.jpg JPEG 2296x1724 2296x1724+0+0 8-bit sRGB 0.010u 0:00.030
a.jpg JPEG 459x345 8-bit sRGB 0.000u 0:00.000
convert: geometry does not contain image `a.jpg' @ warning/transform.c/CropImage/716.
What does the last line mean?

User avatar
fmw42
Posts: 25566
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Median resize

Post by fmw42 » 2017-03-22T15:20:41-07:00

Not sure but perhaps you have more than one +write info: and it does not like that at the end. Perhaps do +write b.jpg info:

Or try my solution above

snibgo
Posts: 12161
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Median resize

Post by snibgo » 2017-03-22T15:39:54-07:00

As, yes, Fred's method with "-sample 20%x20%" is cleaner, and slightly quicker.

My command had two bugs, now corrected. msundman should have "-crop 1x+1+0 +repage +append -crop x5 +repage -crop x1+0+1" for my method.
snibgo's IM pages: im.snibgo.com

Post Reply