How to perform logarithmic distortion on one axis

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?".
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: How to perform logarithmic distortion on one axis

Post by anthony »

Interpolation works but only for compressions of less than 50% more than that and you will get aliases.


Rather than interpolating, I would figure out what range of pixels needs to be compressed into a single pixel, then resample those to produce the right colored pixel. An simple average of all the pixels to be compressed will be better than a direct interpolated lookup, even if the 'weightings' should also be some type of logirithmic scaling.

Basically it comes down to how much work do you want to get the accuracy that is accaptable.

The Distortion page (start at the top) goes though the basic steps that is followed to get more accurate color results.
http://www.imagemagick.org/Usage/distorts/
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
martinwguy
Posts: 13
Joined: 2012-07-22T08:01:33-07:00
Authentication code: 15

Re: How to perform logarithmic distortion on one axis

Post by martinwguy »

Thanks to all. The displacement map optimization, making a 1xheight DM and replicating it to widthxheight, reduced the processing time from 504 seconds to 66 for real-world images.

For those who are interested, the modified Makefile fragment is

time sndfile-spectrogram --dyn-range=$(DYN_RANGE) --no-border $< \
$(WIDTH) $(LIN_HEIGHT) $*.png
#
# Make a displacement map to distort the Y axis with.
# We calculate a 1-pixel high one then replicate this across the map.
#
time convert -size 1x$(LOG_HEIGHT) -depth 16 xc: \
-fx "freq = $(MIN_FREQ_OUT) * pow($(MAX_FREQ_OUT) / $(MIN_FREQ_OUT), ($(MAX_Y_OUT) - j) / $(MAX_Y_OUT)); \
yy = $(MAX_Y_IN) - freq * $(MAX_Y_IN) / $(MAX_FREQ_IN); \
yy/$(MAX_Y_IN)" \
-scale $(WIDTH)x$(LOG_HEIGHT)! map.png
#
# Now apply the displacement map
#
time convert \
-size $(WIDTH)x$(LOG_HEIGHT) xc: \
$*.png map.png \
-virtual-pixel White \
-interpolate Mesh \
-fx "v.p{i,u[2] * $(LIN_HEIGHT)}" \
$*.ppm
cjpeg -progressive -optimize $*.ppm > $@
rm $*.png $*.ppm

and an example page of the site on which I am using this, with the spectrogram and the corresponding listenable audio, is
http://wiki.delia-derbyshire.net/wiki/T ... rn_Emerges

Bless & thanks again

M
Post Reply