Steve on Image Processing

December 21st, 2007

Cleaning up scanned text - revisited

Have you ever used the distance transform?

For a binary image, the distance transform is the distance from every pixel to the nearest foreground (nonzero) pixel. (Sometimes you'll see it defined the other way around. It doesn't really matter that much; you just need to pay attention to whatever convention is being used and complement the image as needed.)

Last week I posted a method for cleaning up scanned text. The method distinguished between small dots that were far away from or were close to pixels belonging to large characters. In that post I used dilation and logical operators to identify small dots that were far away from characters. Later it occurred to me that one could also use the distance transform for this purpose.

Here again are the first few steps. Use bwareaopen to remove the small dots, and use a logical operator to identify the pixels that got removed.

url = 'http://blogs.mathworks.com/images/steve/186/scanned_page.png';
page = imread(url);
bw = page(735:1280, 11:511);
imshow(bw)
bw2 = imcomplement(bw);
bw3 = bwareaopen(bw2, 8);
removed = xor(bw2, bw3);

Next, use the distance transform to identify all pixels that are within a certain distance from foreground pixels in the image bw3.

D = bwdist(bw3);
within_hailing_distance = D <= 10;
imshow(within_hailing_distance)

Which removed pixels do we want to put back?

put_back_pixels = removed & within_hailing_distance;

Use a logical OR to put the pixels back.

gotta_go_the_holiday_party_is_about_to_start = bw3 | put_back_pixels;
imshow(~gotta_go_the_holiday_party_is_about_to_start)

I suspect that not many people know about the "extra" feature that's tucked inside bwdist. Not only can bwdist compute the distance transform for you, but it can also compute a result sometimes called the "feature transform." For each pixel, the feature transform tells you which foreground pixel is nearest. You get the feature transform simply by using a second output argument when you call bwdist.

Do you use this capability? Or do you think you might have a use for it? Please let me know. I'd love to hear about it.


Get the MATLAB code

Published with MATLAB® 7.5

4 Responses to “Cleaning up scanned text - revisited”

  1. ian replied on :

    Thanks for the block.Hopefully I will be doing OCR if all goes well. Sorry to use thiss forum but I have spend 4 hours trying to figure out a solution.Checking online and trying in matlab. Am trying to a rectangular around every labelled component in the image.However I can’t figure out how to do this using BoundingBox the documentation gives a brief mention. Pointing me the right direction would help. I tried following the syntax of adding a centroid to the image but even that was failure.

  2. Steve replied on :

    Ian—Use hold on and plot to superimpose lines on top of an image. See this post for examples.

  3. Greg replied on :

    Look up the work on reconstructing FAX images which essentially do the following:
    1) Break the fax into glyphs (i.e, each character)
    2) Find the glyphs that nearly match each other
    3) Combine glyphs that nearly match each other (a simple naive method is to average the glyphs and then threshold the result)
    4) Put the glyphs back on the page in their original location

    This is quite similar to the lossy JBIG2 compression algorithm.

    Another approach is to use a vertical median filter where each pixel in an X pixel (usually 5 or 7) vertical line is set to the median value of the X pixels. This preserves vertical lines and fills in 1 pixel gaps. Follow that with a horizontal median filter to fill in gaps in horizontal lines.

  4. Steve replied on :

    Greg—Thanks for your suggestions.

Leave a Reply

Wrap code fragments inside <pre> tags, like this:

<pre class="code">
a = magic(3);
sum(a)
</pre>

If you have a "<" character in your code, either follow it with a space or replace it with "&lt;" (including the semicolon).


Steve Eddins manages the Image & Geospatial development team at The MathWorks and coauthored Digital Image Processing Using MATLAB. He writes here about image processing concepts, algorithm implementations, and MATLAB.

  • Sana: hi steve, could you explain to me how i would be able to use the dir function, to do a loop through a directory...
  • Nishtha: Sir, I have preprocessed the image in following steps: [1] adaptive histogram equalization [2] thresholding...
  • Kristof: I also strongly support the idea. I have just recently bumped into the problem that im2single was not...
  • Steve: David—I’ m glad you found it useful!
  • David Lalejini: I found your example very useful for finding connected nodes in a large set of input pairs. I start...
  • tommy: Dear Steve, I have a question,please if you are kind to help me regarding the accumulator array dimensions of...
  • Steve: Abc—I don’t know how to distinguish the faces. You might try posting your question in the MATLAB...
  • Manju: well if we have a few ovals within each other like in a cell how do we measure the distance from the center...
  • Steve: Manju—What do you mean? How is each region defined?
  • Manju: if we have 2-3 regions within each other how do we measure the regions of each one?

These postings are the author's and don't necessarily represent the opinions of The MathWorks.