Hi!
Is it possible to fix this cylindrical (is it really a "cylindrical" distortion?), please?
The original image is:
http://naoliv.googlepages.com/dist_distorted.jpg
And the fixed one is:
http://naoliv.googlepages.com/dist_fixed.jpg
Is it possible to do this in ImageMagick (and how, please)?
Thank you!
Fixing cylindrical distortion
- fmw42
- Posts: 25562
- Joined: 2007-07-02T17:14:51-07:00
- Authentication code: 1152
- Location: Sunnyvale, California, USA
Re: Fixing cylindrical distortion
naoliv wrote:Hi!
Is it possible to fix this cylindrical (is it really a "cylindrical" distortion?), please?
The original image is:
http://naoliv.googlepages.com/dist_distorted.jpg
And the fixed one is:
http://naoliv.googlepages.com/dist_fixed.jpg
Is it possible to do this in ImageMagick (and how, please)?
Thank you!
Here is an attempt, which uses a half sine wave rather than a semicircle, but not really very good.
crop image so it is close to symmetric
http://www.fmwconcepts.com/misc_tests/d ... torted.jpg
process with -wave
see http://www.imagemagick.org/Usage/warping/#wave
convert dist_distorted.jpg -rotate 90 -wave 40x1264 -rotate -90 dist-distort_wave40.jpg
http://www.fmwconcepts.com/misc_tests/d ... wave40.jpg
To do better, you would need to formulate a custom semi-circular displacement or distortion map using -fx.
see http://www.imagemagick.org/Usage/displace/
Or better do a least squares fit with control points, but IM does not yet have that feature to my knowledge. I believe that Anthony has intentions of working on this feature, but I am not sure how far along this is.
Last edited by fmw42 on 2009-02-17T16:18:09-07:00, edited 1 time in total.
Re: Fixing cylindrical distortion
Looks good. I will make some tests with this.fmw42 wrote: Here is an attempt, which uses a half sine wave rather than a semicircle, but not really very good.
crop image so it is close to symmetric
http://www.fmwconcepts.com/misc_tests/d ... torted.jpg
process with -wave
see http://www.imagemagick.org/Usage/warping/#wave
convert dist_distorted.jpg -rotate 90 -wave 40x1264 -rotate -90 dist-distort_wave40.jpg
http://www.fmwconcepts.com/misc_tests/d ... wave40.jpg
To do better, you would need to formulate a custom semi-circular displacement or distortion map using -fx.
see http://www.imagemagick.org/Usage/displace/
Do you know something free and open source that can do this, please?fmw42 wrote: Or better do a least squares fit with control points, but IM does not yet have that feature.
Thank you!
- fmw42
- Posts: 25562
- Joined: 2007-07-02T17:14:51-07:00
- Authentication code: 1152
- Location: Sunnyvale, California, USA
Re: Fixing cylindrical distortion
see ImageJ
http://rsb.info.nih.gov/ij/
http://rsb.info.nih.gov/ij/plugins/
with plugins:
pointpicker http://bigwww.epfl.ch/thevenaz/pointpicker/
bUnwarp http://biocomp.cnb.uam.es/~iarganda/bUnwarpJ/
But prehaps Anthony can figure out a -fx displacement warp for this, if he has time. I will think about it further also.
http://rsb.info.nih.gov/ij/
http://rsb.info.nih.gov/ij/plugins/
with plugins:
pointpicker http://bigwww.epfl.ch/thevenaz/pointpicker/
bUnwarp http://biocomp.cnb.uam.es/~iarganda/bUnwarpJ/
But prehaps Anthony can figure out a -fx displacement warp for this, if he has time. I will think about it further also.
- fmw42
- Posts: 25562
- Joined: 2007-07-02T17:14:51-07:00
- Authentication code: 1152
- Location: Sunnyvale, California, USA
Re: Fixing cylindrical distortion
Here is another try using a semicircular displacement warp
create displacement map:
convert \( -size 1x316 gradient: \) \
\( +clone -negate \) -append -negate \
-channel G -separate +channel \
-negate +clone -compose multiply -composite \
-negate -evaluate pow 0.5 \
+level 0%,49.999999% -scale 2290x632! \
dist_distorted_semicircle_lut.png
apply displacement map
composite -displace -50x0 dist_distorted_semicircle_lut.png dist_distorted.jpg dist_distorted_displace_m50.jpg
http://www.fmwconcepts.com/misc_tests/d ... le_m50.jpg
create displacement map:
convert \( -size 1x316 gradient: \) \
\( +clone -negate \) -append -negate \
-channel G -separate +channel \
-negate +clone -compose multiply -composite \
-negate -evaluate pow 0.5 \
+level 0%,49.999999% -scale 2290x632! \
dist_distorted_semicircle_lut.png
apply displacement map
composite -displace -50x0 dist_distorted_semicircle_lut.png dist_distorted.jpg dist_distorted_displace_m50.jpg
http://www.fmwconcepts.com/misc_tests/d ... le_m50.jpg
- fmw42
- Posts: 25562
- Joined: 2007-07-02T17:14:51-07:00
- Authentication code: 1152
- Location: Sunnyvale, California, USA
Re: Fixing cylindrical distortion
Here is a pretty good result.
I measured the offsets of the curve that was along the left edge at the major grid intersections (using Debabelizer). Then used my plmlut script to make a piecewise linear lookup table and rotated and expanded it to fit your image. Then applied it as a displacement map. I used my profile script to make a graph of the 1D lut before rotating and expanding so you can see the piecewise linear curve. You can do the same with more points for better accuracy.
create piecewise linear lut
plmlut -s 630,44 -t 1 "0,44 58,30 115,18, 173,10 230,4 287,2 345,2 402,4 460,10 516,18 575,30 630,44" dist_distorted_plmlut.png
convert to grayscale, contrast-stretch graylevels, rotate 90 degrees and expand it with scale
convert dist_distorted_plmlut.png -type grayscale -contrast-stretch 0 -rotate 90 -scale 2290x631! dist_distorted_plmlut_cs.png
get profile of first column
profile -c 0 dist_distorted_plmlut_cs.png
http://www.fmwconcepts.com/misc_tests/d ... rofile.gif
apply lut as displacement map
composite -displace 20x0 dist_distorted_plmlut_cs.png dist_distorted.jpg dist_distorted_displace_plmlut_20.jpg
http://www.fmwconcepts.com/misc_tests/d ... lut_20.jpg
scripts available at http://www.fmwconcepts.com/imagemagick/index.html
I measured the offsets of the curve that was along the left edge at the major grid intersections (using Debabelizer). Then used my plmlut script to make a piecewise linear lookup table and rotated and expanded it to fit your image. Then applied it as a displacement map. I used my profile script to make a graph of the 1D lut before rotating and expanding so you can see the piecewise linear curve. You can do the same with more points for better accuracy.
create piecewise linear lut
plmlut -s 630,44 -t 1 "0,44 58,30 115,18, 173,10 230,4 287,2 345,2 402,4 460,10 516,18 575,30 630,44" dist_distorted_plmlut.png
convert to grayscale, contrast-stretch graylevels, rotate 90 degrees and expand it with scale
convert dist_distorted_plmlut.png -type grayscale -contrast-stretch 0 -rotate 90 -scale 2290x631! dist_distorted_plmlut_cs.png
get profile of first column
profile -c 0 dist_distorted_plmlut_cs.png
http://www.fmwconcepts.com/misc_tests/d ... rofile.gif
apply lut as displacement map
composite -displace 20x0 dist_distorted_plmlut_cs.png dist_distorted.jpg dist_distorted_displace_plmlut_20.jpg
http://www.fmwconcepts.com/misc_tests/d ... lut_20.jpg
scripts available at http://www.fmwconcepts.com/imagemagick/index.html
- fmw42
- Posts: 25562
- Joined: 2007-07-02T17:14:51-07:00
- Authentication code: 1152
- Location: Sunnyvale, California, USA
Re: Fixing cylindrical distortion
Here is a way that is similar that does not need plmlut.
However, it assumes the offset values are evenly spaced vertically. It has to make the lut a bit bigger by 1/12 as there are 12 values used, but is then cropped to the proper size. As long as the offsets are not bigger than 255, then the graylevels assigned do not need to be converted to percent as we are going to contrast-stretch them anyway.
create lut:
len=`convert xc: -format "%[fx:floor(2290*(1+1/12))]" info:`
convert -size 1x1 xc:"gray(44)" xc:"gray(30)" xc:"gray(18)" \
xc:"gray(10)" xc:"gray(4)" xc:"gray(2)" \
xc:"gray(2)" xc:"gray(4)" xc:"gray(10)" \
xc:"gray(18)" xc:"gray(30)" xc:"gray(44)" \
+append -contrast-stretch 0 -filter triangle -resize ${len}x1! \
-gravity center -crop 2290x1+0+0 +repage \
-rotate 90 -scale 2290x631! \
dist_distort_triangle_lut.png
compute profile
profile -c 0 dist_distort_triangle_lut.png
http://www.fmwconcepts.com/misc_tests/d ... rofile.gif
apply lut as displacement map:
composite -displace 20x0 dist_distort_triangle_lut.png dist_distorted.jpg dist_distorted_displace_triangle_lut_20.jpg
http://www.fmwconcepts.com/misc_tests/d ... lut_20.jpg
However, it assumes the offset values are evenly spaced vertically. It has to make the lut a bit bigger by 1/12 as there are 12 values used, but is then cropped to the proper size. As long as the offsets are not bigger than 255, then the graylevels assigned do not need to be converted to percent as we are going to contrast-stretch them anyway.
create lut:
len=`convert xc: -format "%[fx:floor(2290*(1+1/12))]" info:`
convert -size 1x1 xc:"gray(44)" xc:"gray(30)" xc:"gray(18)" \
xc:"gray(10)" xc:"gray(4)" xc:"gray(2)" \
xc:"gray(2)" xc:"gray(4)" xc:"gray(10)" \
xc:"gray(18)" xc:"gray(30)" xc:"gray(44)" \
+append -contrast-stretch 0 -filter triangle -resize ${len}x1! \
-gravity center -crop 2290x1+0+0 +repage \
-rotate 90 -scale 2290x631! \
dist_distort_triangle_lut.png
compute profile
profile -c 0 dist_distort_triangle_lut.png
http://www.fmwconcepts.com/misc_tests/d ... rofile.gif
apply lut as displacement map:
composite -displace 20x0 dist_distort_triangle_lut.png dist_distorted.jpg dist_distorted_displace_triangle_lut_20.jpg
http://www.fmwconcepts.com/misc_tests/d ... lut_20.jpg