How to unwarp an image

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?".
impoweruser
Posts: 7
Joined: 2013-12-04T14:39:42-07:00
Authentication code: 6789

Re: How to unwarp an image

Post by impoweruser »

fmw42 wrote:try the following. I negate the image, then get the height of the white on a column by column basis and use that height image to generate a new image that draws black from the top of a pure white image as much as the specified height, then flips the image over so that the flat is at the bottom. The value of 35 is the scale factor use to match the height of the original image.

Image

convert sample1.png \
\( -clone 0 -fill white -colorize 100 \) \
\( -clone 0 -negate -scale 96x1! \) \
-delete 0 -fx "j<35*v?black:white" -flip sample1_proc.png

Image
works nicely, but the problem is, on ocassion, the source images will have specs of white in them that need to be preserved.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: How to unwarp an image

Post by fmw42 »

Provide an example
impoweruser
Posts: 7
Joined: 2013-12-04T14:39:42-07:00
Authentication code: 6789

Re: How to unwarp an image

Post by impoweruser »

fmw42 wrote:Actually this is simpler, the colorize step is not needed:


convert sample1.png \
\( -clone 0 -negate -scale 96x1! \) \
-fx "j<35*v?black:white" -flip result.png
I think my post was deleted somehow ~ anyway, this seems to work ok, but on ocassion there are white specs within the black columns that need to be preserved.

EDIT: Nevermind ~ didnt notice we are on page 2 here :). Ill try to dig up a sample
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: How to unwarp an image

Post by fmw42 »

Here is one way.

Image

# first I take the input and flip and trim it and check the dimensions to be sure I know if it has been trimmed. It must not have full white for the boundary or the floodfill will not work
# then I put one white row at the top
# then I flood fill from the top with red stopping where the black is
# then I convert red to white and the rest to black and save the image

convert sample2.png -flip -trim -format "%wx%h\n" -write info: \
-gravity north -background white -splice 0x1 \
-fill red -draw "color 0,0 floodfill" -alpha off \
-fill black +opaque red -fill white -opaque red -gravity north -chop 0x1 \
-write show: 1tmp1.png

#Since the trim size is the same as the input I know I can use 96x35 for my arguments.
# then I flip the input here and scale the previously created image to one row whose graylevel is the height of the red or where the white was below the black in the original
# then I use -fx to shift the rows up by the amount in the tmp file
# and finally flip the result back again

convert \( sample2.png -flip \) \( 1tmp1.png -scale 96x1! \) \
-virtual-pixel white -fx "jj=round(35*v.p{i,0}); u.p{i,j+jj}" -flip sample2_proc.png

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

Re: How to unwarp an image

Post by snibgo »

I love the simple elegance of fmw's script.

A trivial modification to my script straightens the bottom instead of the top. (Change "rectangle:1x2" to "rectangle:1x2+0+1".) A more complex modification straightens the mid-line of the blob, so it becomes symmetrical about its horizontal axis.

Yes, my script will place the resulting line at the mid-height of the result. This "drags in" pixels from outside the image (which I show as khaki) and "pushes out" pixels that were in the image. To avoid losing pixels, simply extend the input image to be twice as high:

Code: Select all

convert in.png -background white -gravity center -extent 100%x200% out.png
impoweruser wrote:... but on ocassion there are white specs within the black columns that need to be preserved.
My script assumes the blob is black, and elsewhere is white, possibly with antialiasing at the blob's edge. If this isn't true then the image will need to be cleaned up first (such as by fmw's latest post) to create the displacement map, then the map is applied to the original image.
snibgo's IM pages: im.snibgo.com
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: How to unwarp an image

Post by fmw42 »

My solution is just an fx equivalent of a distortion map that shift columns. The tmp file I created could have been scaled to repeat the row to fill the height of the input. That could then be used as the distortion map with -displace as in snibgo's solution to do the same thing. For small images, it probably does not matter. For very large images, the distortion map will be faster than -fx.
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: How to unwarp an image

Post by snibgo »

Using my 400x300 source image clutLine2.png given above, your single command takes 2.2 seconds and mine takes 0.4 seconds. As you say, they are essentially the same method. "-fx" is always slow.
snibgo's IM pages: im.snibgo.com
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: How to unwarp an image

Post by fmw42 »

Here is the equivalent using -compose displace


convert sample2.png -flip -trim -format "%wx%h\n" -write info: \
-gravity north -background white -splice 0x1 \
-fill red -draw "color 0,0 floodfill" -alpha off \
-fill black +opaque red -fill white -opaque red -gravity north -chop 0x1 \
-write show: 1tmp1.png

# old -fx
convert \( sample2.png -flip \) \( 1tmp1.png -scale 96x1! \) \
-virtual-pixel white -fx "jj=round(35*v.p{i,0}); u.p{i,j+jj}" -flip sample2_proc.png

# new -compose displace
convert \( sample2.png -flip \) \( 1tmp1.png -scale 96x1! -scale 96x35! -function polynomial "0.5,0.5" \) \
-virtual-pixel white -define compose:args="0x35" -compose displace -composite -flip sample2_proc2.png
Post Reply