Page 1 of 1

Image distortion from a B&W mask

Posted: 2016-08-02T05:10:42-07:00
by roipoussiere
Hello,
I digitalized several big books with a camera (~1000 photos), using a green background. I would like to make them more readable.

Original photos looks like this (this is an example, not the real books, which are much bigger) :

Image

I first extracted a mask representing the shape of the book:

Code: Select all

convert original.jpg -fuzz 25% -fill None -floodfill +0+0 '#0a613e' -alpha extract -morphology Open Disk mask.png
Image

Using this shape, I keep only the book, and I also crop an resize the pic:

Code: Select all

convert original.jpg -compose CopyOpacity mask.png -composite -trim +repage -resize 600 output.png
Image

My question is: Is it possible, using the mask, to distort the pic by moving the extremities of the book in the extremities of the picture, in order to have a "flat book" aspect, so the text would be in straight lines (like if I used a scanner) ?

Shepards Distortion ? I don't really know how to use them for my purpose... I think to write a script to get all dots of the mask perimeter and generate a very long im command, but is there a easier way?

Re: Image distortion from a B&W mask

Posted: 2016-08-02T06:03:05-07:00
by snibgo
The left and right sides are straight, more or less, with the top and bottom curved. So a reasonable method is:

1. Find the four corners. Distort perspective to put the corners in a rectangle. Now the sides are vertical.

2. Now stretch the image vertically to fit into its bounding box.

For (2), see the thread viewtopic.php?f=1&t=30073&p=135852 , where the requirement was to stretch horizontally. I showed two methods: a faster one that needs my process modules, and a slower one that doesn't. You can apply those methods by first rotating your image by 90 degrees, and finally rotatating the result back.

Re: Image distortion from a B&W mask

Posted: 2016-08-02T06:58:47-07:00
by roipoussiere
1. Find the four corners.
Ok, I can do this with IM? How?

So to use your module, I use http://im.snibgo.com/sh2sh.htm#sh2shLinear.bat (which I should rewrite I think, because I use Linux) and then do something like:

Code: Select all

sh2shLinear.bat sh2shLinear output.png mask.png h 75 r stretched.png 0
that's right?

Re: Image distortion from a B&W mask

Posted: 2016-08-02T08:59:57-07:00
by fmw42
To find the corners, you would pick them manually using some GUI tool such as GIMP. Or use -morphology on the mask to find corners. See http://www.imagemagick.org/Usage/morphology/#corners

Re: Image distortion from a B&W mask

Posted: 2016-08-02T09:39:52-07:00
by fmw42
Another way to find the corners is to do a -distort depolar on the mask and find the 4 tallest peaks (or valleys depending upon polarity)

Re: Image distortion from a B&W mask

Posted: 2016-08-02T09:40:55-07:00
by fmw42
If on Unix, you could try my script unperspective at the link below

Re: Image distortion from a B&W mask

Posted: 2016-08-02T11:06:05-07:00
by roipoussiere
If on Unix, you could try my script unperspective at the link below
Wow, wonderful script, congrats! :-)

I applied unperspective, the book looks better :-)

Code: Select all

./unperspective -f 5 -V output.png stretched.png
Image

I will try -morphology on my mask and -distort depolar tonight.

Just to don't reinvent the wheel: your script can also stretch the picture to have a "flat book" (as I explained above), or "just" make a perspective transformation (and this is a lot ;-) ) ?

Edit:

I tried -morphology, and it found a lot of corners, instead of only 4 corners:

Code: Select all

convert _mask.png -morphology HMT Corners -morphology Dilate Disk out.png
Image
I never used morphology before, any idea how to get less corners?

Re: Image distortion from a B&W mask

Posted: 2016-08-02T12:30:13-07:00
by snibgo
There are many ways of finding the corners from a b/w mask. For your example, a subimage-search for corners (each 4x4 pixels) works well.
Image
I found them with my unpublished script find4cornSub.bat. When the four corners are known, find their bounding rectangle and use "-distort perpective". In this case, the top of the image will be stretched out.
Image

sh2shLinear.bat needs my process modules. Using the method outlined in the other thread:
Image
I haven't yet published the scripts for this.

Re: Image distortion from a B&W mask

Posted: 2016-08-02T17:43:41-07:00
by roipoussiere
Phew, I finished the first step: distorting the picture by looking for corners as you suggested:

Code: Select all

#!/bin/sh

# creating the mask
convert original.jpg -fuzz 25% -fill None -floodfill +0+0 '#0a613e' -alpha extract -morphology Open Disk -resize 200 mask.png

# creating corner pitures
convert -size 4x4 xc:white -draw 'line 0,0 3,0 line 0,0 0,3' /tmp/upleft.png
convert -size 4x4 xc:white -draw 'line 0,0 3,0 line 3,0 3,3' /tmp/upright.png
convert -size 4x4 xc:white -draw 'line 0,3 3,3 line 0,3 0,0' /tmp/downleft.png
convert -size 4x4 xc:white -draw 'line 0,3 3,3 line 3,3 3,0' /tmp/downright.png

# looking for corners in the mask
upleft=$(compare -subimage-search -metric Fuzz mask.png /tmp/upleft.png /tmp/out 2>&1 | cut -d'@' -f 2)
upright=$(compare -subimage-search -metric Fuzz mask.png /tmp/upright.png /tmp/out 2>&1 | cut -d'@' -f 2)
downleft=$(compare -subimage-search -metric Fuzz mask.png /tmp/downleft.png /tmp/out 2>&1 | cut -d'@' -f 2)
downright=$(compare -subimage-search -metric Fuzz mask.png /tmp/downright.png /tmp/out 2>&1 | cut -d'@' -f 2)
echo "Corners: $upleft $upright $downright $downleft"

# (optional) creating a picture showing the corners on the mask
convert \( \( -size 200x150 xc:black -draw "fill red point $upleft point $upright point $downright point $downleft" \) -morphology Dilate Disk \) \( mask.png \) -compose dissolve -define compose:args='50,50' -composite corners.png

# distording the original picture
convert _original.png -matte -virtual-pixel transparent -distort Perspective "$upleft 0,0   $upright 200,0   $downright 200,150   $downleft 0,150" out.png
Image
Image

There are however some bugs:
- Corners positions have an offset corresponding to the corners picture dimensions;
- The output picture is cropped.

But I need to go to bed :-)
I haven't yet published the scripts for this.
When do you think you will? :-P

Re: Image distortion from a B&W mask

Posted: 2016-08-02T18:22:10-07:00
by snibgo
roipoussiere wrote:Corners positions have an offset...
"-subimage-search" returns the position of the top-left of the small image within the large image. Your code incorrectly assumes it returns the position of the centre of the small image within the large.
roipoussiere wrote:The output picture is cropped.
That's because your destination coords are (0,0), (200,0) etc. As well as cropping the book pages, this changes their aspect ratio.

Given the coords of the book corners, a simple calculation gives the bounding rectangle of those four points. Then you can use the corners of that rectangle as your destination coords.
roipoussiere wrote:When do you think you will?
When there are at least 26 hours in the day.

Re: Image distortion from a B&W mask

Posted: 2016-08-05T10:02:07-07:00
by snibgo
I've uploaded some stuff, including "Finding four corners" which includes find4cornSub.bat. The "Shape to shape" page has a new section, "Horizontal stretch method".