mogrify -implode: Reversible?

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
nmp
Posts: 3
Joined: 2018-04-22T14:20:03-07:00
Authentication code: 1152
Location: South Side, Chicago

mogrify -implode: Reversible?

Post by nmp »

Hello,

Is it possible to implode an image then explode it back to the original image? For example:

mogrify -path output_directory1/ -border 20x20 -implode 0.6 -shave 20x20 test.png

cd output_directory

mogrify -path output_directory2/ -border 20x20 -implode -0.6 -shave 20x20 test.png

This naive attempt did not work as the reversed/exploded image was still warped compared to the original. Perhaps the underlying algorithm is not reversible but if it is, I was wondering what parameters would work.

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

Re: mogrify -implode: Reversible?

Post by fmw42 »

I do not think it is exactly invertable.

try this and you will see that you do not get the original back.

Code: Select all

convert -size 94x94 xc:red -bordercolor white -border 3 redwhitebox.png 
convert redwhitebox.png -virtual-pixel tile -implode 4 -implode -4 tmp.png
Even if so, there would be interpolation both ways which would make the final result blurry.
nmp
Posts: 3
Joined: 2018-04-22T14:20:03-07:00
Authentication code: 1152
Location: South Side, Chicago

Re: mogrify -implode: Reversible?

Post by nmp »

Blurriness would be fine as I was more interested in returning the original image's geometry...but that's most likely not possible. Thanks.
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: mogrify -implode: Reversible?

Post by snibgo »

I'm curious: why do you want an inverse for implode?

It is possible, but not (I think) by a second implode.

I've looked at the code for implode in fx.c. I can't see how to mathematically reverse one implode by another implode. I think that it is self-reversible only at one given radius from the centre.

If you want a similar process that can be used as its own exact inverse, I suggest you design one.

Of course, implode like any geometric transformation does have an inverse, but it isn't a self-inverse. Like most transformations, it is many-to-one so the inverse has holes. We can make an identity displacement map the same size as the input image (eg toes.png, which is 267x233 pixels), and apply "-implode" to that, and find the inverse of that, and fill in the holes.

This gives us a displacement map that can implode toes.png, and another displacement map that will distort it back to a close approximation of the input.

We start with a negative implode, -0.6, because that gives fewer holes.

Code: Select all

call %PICTBAT%identAbsDispMap 267 233 revi_m.png
Image

Code: Select all

%IM%convert revi_m.png -implode -0.6 revi_i.png
Image

Code: Select all

%IMDEV%convert revi_i.png -process 'invdispmap v' revi_ir.png
Image

Code: Select all

call %PICTBAT%blurFill revi_ir.png . revi_irb.png
Image

Code: Select all

%IM%convert ^
  toes.png revi_i.png ^
  -compose Distort -set option:compose:args 100%%x100%% -composite ^
  revi_t1.png
Image

Code: Select all

%IM%convert ^
  revi_t1.png revi_irb.png ^
  -compose Distort -set option:compose:args 100%%x100%% -composite ^
  revi_t2.png
Image

Code: Select all

%IM%compare -metric RMSE toes.png revi_t2.png NULL:

541.477 (0.00826241)
The round-trip is less than 1% different, which isn't visually noticable.

The maps are inverses of each other, so instead of applying the first and then the second, we could apply the second and then the first.

EDIT to add:

1. I expect an exact inverse could be done with a "-fx" operation.

2. My method with displacement maps can be made more accurate by supersampling, eg doubling the sizes reduces the RMSE to 0.0054.
snibgo's IM pages: im.snibgo.com
nmp
Posts: 3
Joined: 2018-04-22T14:20:03-07:00
Authentication code: 1152
Location: South Side, Chicago

Re: mogrify -implode: Reversible?

Post by nmp »

Creating an identity displacement map is a fantastic idea. I'll give it a shot.

To answer your question as to why I wish to invert implode, I created a deep learning semantic segmentation model using FCN-8s for axial CT adominal images https://github.com/NVIDIA/DIGITS/tree/m ... al-imaging. In such images, subcutaneous fat (i.e. belly fat) and core skeletal muscle both resemble irregularly-shaped ellipses:

Image

FCN-8s can segment an image down to an 8x8 pixel block. However, extremely fit or extremely sick patients often exhibit very thin subcutaneous fat and/or core muscles layers. These layers often fall below FCN-8s 8x8 pixel resolution threshold and thus are not recognized for segmentation.

Imploded CT images for such patients thickens the fat and muscle rings nicely. Inverting the distorted input image and resulting segmentation mask with your stated level of error would be more than adequate for anatomical segmentation.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: mogrify -implode: Reversible?

Post by fmw42 »

Perhaps some other distortion would work better. For example spherical and inverse spherical. See my script http://www.fmwconcepts.com/imagemagick/ ... /index.php as one example. You can also create your own distortions as snibgo suggested and its inverse distortion.
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: mogrify -implode: Reversible?

Post by snibgo »

nmp wrote:Imploded CT images for such patients thickens the fat and muscle rings nicely.
Ha! Very neat. So you want to implode, segment, then de-implode.

The "-implode" transformation moves pixels along the radius from the centre:

Code: Select all

r' = pow( sin(PI*r),-amount)
where r' is the normalised radius of the source pixel, r is the radius of the destination, PI is 3.141... and amount is the "-implode" parameter.

A simpler version is:

Code: Select all

r' = pow(r,amount)
where the radii are normalised to zero at the centre and one at the corners. It is self-reversible, using reciprocal amounts. Many other versions are possible, eg normalising so radius=1 at the centre of the long sides. You could experiment to find the best for segmentation.

Here is a script that implements the simple version as a Windows BAT script, squishPow.bat. It is readily translated to bash or anything else. The amount is expressed as numerator and denominator, to simplify the inversion.

Code: Select all

rem From image %1,
rem makes output %2
rem shifting pixels along radius by power factor %3/%4.

set sFX=^
Cx=w/2;^
Cy=h/2;^
Hy=hypot(i-Cx,j-Cy)/hypot(Cx,Cy);^
FF=Hy^>1?1:pow(Hy,%3/%4)/Hy;^
Xs=FF*(i-Cx)+Cx;^
Ys=FF*(j-Cy)+Cy;^
p{Xs,Ys}

%IM%convert ^
  %1 ^
  -virtual-pixel Black ^
  -fx "%sFX%" ^
  %2
For example, using abdo_grid.png:
Image

Code: Select all

call %PICTBAT%squishPow abdo_grid.png abdo_g1.png 3 4
Image

Code: Select all

call %PICTBAT%squishPow abdo_g1.png abdo_g2.png 4 3
Image

Inevitably, there is fuzziness that increases towards the centre.

We can supersample, eg resize the input by 400%, do the process, and resize the output by 25%, making the round-trip result:
Image
The result is much less fuzzy. You could do the segmentation on the 400% super-sampled image.

The "-fx" operator is interpreted at every pixel, so it is slow, about 6 seconds for this example (supersampling at 400% take 16 times as long). If you need to process many same-sized images, you can create two displacement maps (by applying two transformations to an identity displacement map) and apply those to the images, as in my previous post.
snibgo's IM pages: im.snibgo.com
Post Reply