# Cut pages for OCR with RMagick?

**URL:** <https://www.ruby-forum.com/t/cut-pages-for-ocr-with-rmagick/115873>\
**Category:** Ruby\
**Created:** [September 29, 2007, 4:46pm UTC](https://www.ruby-forum.com/t/cut-pages-for-ocr-with-rmagick/115873 "2007-09-29T16:46:28Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Axel\_E](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/7c8e57/32.png) [@Axel\_E](https://www.ruby-forum.com/u/Axel_E)\
**Post date:** [September 29, 2007, 4:46pm UTC](https://www.ruby-forum.com/t/cut-pages-for-ocr-with-rmagick/115873/1 "2007-09-29T16:46:28Z")

</div>

Dear all,

I have many scanned pages which I’d like to cut to prepare them  
for OCR.  
There are two things I’d like to do:

1.) Cut off a header of each page containing the page number,

2.) Find the largest horizontal blanks in a page (which are supposed  
to separate chapters) like this:

Chapter1’s text Chapter1’s text  
Chapter1’s text Chapter1’s text  
Chapter1’s text Chapter1’s text  
Chapter1’s text Chapter1’s text  
\<---- cut here, at this blank  
Chapter2’s text Chapter2’s text  
Chapter2’s text Chapter2’s text  
Chapter2’s text Chapter2’s text  
Chapter2’s text Chapter2’s text  
^  
|  
— (Then cut vertically)

I have tried to convert my pages, which are A4 and 600 dpi, to pixel  
arrays,  
but this is quite slow. Is there a better method, ie. using to\_blob ?

Thank you very much,

Axel

---

<div class="post-metadata">

**Author:** ![Axel\_E](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/7c8e57/32.png) [@Axel\_E](https://www.ruby-forum.com/u/Axel_E)\
**Post date:** [September 29, 2007, 10:15pm UTC](https://www.ruby-forum.com/t/cut-pages-for-ocr-with-rmagick/115873/2 "2007-09-29T22:15:32Z")

</div>

On 9/29/07, Axel E. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Dear all,
> 
> I have many scanned pages which I’d like to cut to prepare them  
> for OCR.  
> There are two things I’d like to do:
> 
> 1.) Cut off a header of each page containing the page number,
> 
> 2.) Find the largest horizontal blanks in a page (which are supposed  
> to separate chapters) like this:

If you have a binary string of the pixel data in the image  
(I guess to\_blob gives that), you can do something like this  
for cutting the vertical spans of non-white pixels:

scanline\_bytes = image\_width \* bytes\_per\_pixel  
scanlines = pixels.scan(/.{#{scanline\_bytes}}/)  
chapters = [[]]  
scanlines.each{|sl|  
if is\_white(sl)  
chapters \<\< [] unless paragraphs.last.empty?  
else  
chapters.last \<\< sl  
end  
}

For finding larger spans of white, keep track of white  
scanlines seen previously. #is\_white can well be something  
that returns true if less than 50 pixels on a scanline are white  
or somesuch.

To crop the margins off the chapter scanlines:

left\_border = chapter\_scanlines.min{|sl| sl =~ /#{non\_white\_pixel}/ }  
left\_border -= left\_border % bytes\_per\_pixel  
right\_border = chapter\_scanlines.min{|sl| sl.reverse =~  
/#{non\_white\_pixel}/ }  
right\_border -= right\_border % bytes\_per\_pixel

chapter\_scanlines.map!{|sl| sl[left\_border…right\_border] }

The middle whitespace can be had by (tune the magic number to signify  
enough pixels to not be a character space):

left\_border = chapter\_scanlines.max{|sl| sl =~ /#{non\_white\_pixel}{20}/  
}

and with reversed scanline for right border.

\</imaging regexps for fun and profit\>

HTH,

---

<div class="post-metadata">

**Author:** ![Axel\_E](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/7c8e57/32.png) [@Axel\_E](https://www.ruby-forum.com/u/Axel_E)\
**Post date:** [October 1, 2007, 9:12pm UTC](https://www.ruby-forum.com/t/cut-pages-for-ocr-with-rmagick/115873/3 "2007-10-01T21:12:43Z")

</div>

Tim H. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) writes:

> ## accomplish your goal. Since the ImageMagick/GraphicsMagick routines
> 
> RMagick OS X Installer [[http://rubyforge.org/projects/rmagick/](http://rubyforge.org/projects/rmagick/)]  
> RMagick Hints & Tips [[http://rubyforge.org/forum/forum.php?forum\_id=1618](http://rubyforge.org/forum/forum.php?forum_id=1618)]  
> RMagick Installation FAQ [[http://rmagick.rubyforge.org/install-faq.html](http://rmagick.rubyforge.org/install-faq.html)]

When it comes to document imaging, the problem with most image  
processing kits, including/especially ImageMagick, is that they insist  
on using a 32-bit per pixel memory representation for all images.  
Fine for your 200x200 web GIF, but No Fun when your ~4MB B&W scanned  
page suddenly expands to 140MB in memory.

You can try NArray[1] (8x expansion is better the 32x), or use a kit  
that can handle 1-bit images in memory, e.g. Leptonica[2].

Steve

[1] [http://narrary.rubyforge.org/](http://narrary.rubyforge.org/)  
[2] [http://www.leptonica.com/](http://www.leptonica.com/)

---

<div class="post-metadata">

**Author:** ![Axel\_E](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/7c8e57/32.png) [@Axel\_E](https://www.ruby-forum.com/u/Axel_E)\
**Post date:** [September 29, 2007, 10:40pm UTC](https://www.ruby-forum.com/t/cut-pages-for-ocr-with-rmagick/115873/4 "2007-09-29T22:40:43Z")

</div>

Axel E. wrote:

> I have tried to convert my pages, which are A4 and 600 dpi, to pixel arrays,  
> but this is quite slow. Is there a better method, ie. using to\_blob ?

to\_blob just gives you an in-memory copy of the image file. If the image  
is in JPG format, for example, then the blob is an in-memory JPG file.  
So, there’s no help there.

Ideally you could use some RMagick method or combination of methods to  
accomplish your goal. Since the ImageMagick/GraphicsMagick routines are  
written in C they’d be much faster. Offhand I can’t think of any such  
methods, but then I’m not very clever at that sort of thing.

You might try asking the ImageMagick gurus  
([Legacy ImageMagick Discussions Archive - Index page](http://www.imagemagick.org/discourse-server/)) if there’s a way to do it  
with the command-line utilities. If so, you can usually translate the  
commands and options into RMagick methods. See  
[RMagick 1.15.0: Magick Command Options and Their Equivalent Methods](http://www.simplesystems.org/RMagick/doc/optequiv.html) for help with  
that.
