Page 1 of 1

Median resize

Posted: 2017-03-22T14:26:00-07:00
by msundman
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.)

Re: Median resize

Posted: 2017-03-22T14:46:05-07:00
by snibgo
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: ^
"-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.

Re: Median resize

Posted: 2017-03-22T15:09:34-07:00
by fmw42
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

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

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 ... 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.

Re: Median resize

Posted: 2017-03-22T15:16:55-07:00
by msundman
Ooh, thank you so much!


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?

Re: Median resize

Posted: 2017-03-22T15:20:41-07:00
by fmw42
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

Re: Median resize

Posted: 2017-03-22T15:39:54-07:00
by snibgo
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.