Skip to main content

Read text from an image in C#

Read text from an image in C#Photo by Clément H

Originally Posted On: https://ironsoftware.com/csharp/ocr/tutorials/how-to-read-text-from-an-image-in-csharp-net/

 

How to read text from images with C# OCR

In this tutorial, we will learn how to convert images to text in C# and other .NET languages. We will use the Iron OCR library to recognize text within images and look at the nuances of how to use Iron OCR to get the highest performance in terms of accuracy and speed when reading text from images in .NET Hello World.

To achive Image to Text we will install the IronOCR OCR library into a Visual Studio project.

To do this, we Download the IronOcr DLL or use Nuget.

PM > Install-Package IronOcr

Video Link

AutoOCR

In this simple example, you can see we use the IronOcr.AutoOcr class to read the text from an image and automatically return its value as a string.

  1. using IronOcr;
  2. AutoOcr OCR = new AutoOcr() { ReadBarCodes = false };
  3. var Results = OCR.Read(“img/Screenshot.png”);
  4. Console.WriteLine(Results.Text);

Copy code to clipboardVB  C#C# OCR of a Screenshot

Although this may seem simplistic, there is sophisticated behavior going on ‘under the surface’: scanning the image for alignment, quality and resolution, looking at its properties, optimizing the OCR engine, and using a trained artificial intelligence network to then read the text as a human would.

OCR is not a simple process for a computer to achieve, and reading speeds may be similar to those of a human. In other words, OCR is not an instantaneous process. In this case though, it is 100% accurate.

C# OCR application results accuracy

Advanced OCR

In most real world use cases, developers are going to want the best performance possible for their project. In this case, we recommend that you move forward from the Auto OCR example and look at the AdvancedOCR class within the Iron OCR namespace.

This gives you the facility to set the specific characteristics of an OCR job, such as:

  • cleaning background noise;
  • enhancing contrast;
  • enhancing resolution;
  • choosing a specific language;
  • choosing particular OCR strategies (balance speed against performance);
  • specifying color spaces;
  • working with negative images where there is dark text on white backgrounds;
  • specifying a document type whether we are looking at a screenshot, a snippet, or an entire document;
  • specifying whether or not we wish to spend time correcting for skew, rotation, and perspective within the original scanned image;
  • specifying if IronOCR read barcodes when we are performing OCR;
  • and choosing the number of bits per pixel within our color depth.
Example: Safe Defaults

This all may seem daunting, but in the example below you will see the default settings which we would recommend you start with, which will work with almost any image you input to Iron OCR.

  1. var Ocr = new AdvancedOcr()
  2. {
  3. CleanBackgroundNoise = true,
  4. EnhanceContrast = true,
  5. EnhanceResolution = true,
  6. Language = IronOcr.Languages.English.OcrLanguagePack,
  7. Strategy = IronOcr.AdvancedOcr.OcrStrategy.Advanced,
  8. ColorSpace = AdvancedOcr.OcrColorSpace.Color,
  9. DetectWhiteTextOnDarkBackgrounds = true,
  10. InputImageType = AdvancedOcr.InputTypes.Document,
  11. RotateAndStraighten = true,
  12. ReadBarCodes = true,
  13. ColorDepth = 4
  14. };
  15. var Results = Ocr.Read(“any_image_or_pdf.pdf”);

Copy code to clipboardVB  C#

Example: A Medium Quality Scan

 

C# OCR Scan From Tiff Example

In the following example we will perform OCR on a medium quality TIFF scan of a page from Harry Potter and the Chamber of Secrets.

  1. var Ocr = new AdvancedOcr()
  2. {
  3. CleanBackgroundNoise = false,
  4. EnhanceContrast = true,
  5. EnhanceResolution = false,
  6. Language = IronOcr.Languages.English.OcrLanguagePack,
  7. Strategy = IronOcr.AdvancedOcr.OcrStrategy.Advanced,
  8. ColorSpace = AdvancedOcr.OcrColorSpace.Color,
  9. DetectWhiteTextOnDarkBackgrounds = false,
  10. InputImageType = AdvancedOcr.InputTypes.Document,
  11. RotateAndStraighten = false,
  12. ReadBarCodes = false,
  13. ColorDepth = 4
  14. };
  15. var Results = Ocr.Read(“img/Potter.tiff”);

Copy code to clipboardVB  C#

As you can see, reading the text (and optionally barcodes) from a scanned image such as a TIFF was rather easy. This OCR job yields an accuracy of 96.5%. OCR is not a perfect science when it comes to real world documents.

You will also note that Iron OCR can automatically read multipage documents, such as TIFFs and even PDF documents, automatically with these settings.

Example: A Low Quality Scan

 

C# OCR Low Resolution Scan with Digital Noise

Now we will try a much lower quality scan of the same page, at a low DPI, which has lots of distortion and digital noise and damage to the original paper.

This is where IronOCR truly shines against other OCR libraries such as Tesseract, and we will find alternative OCR projects shy away from discussing. OCR on real world scanned images rather than unrealistically ‘perfect’ test cases created digitally to give a 100% OCR accuracy.

  1. var Ocr = new AdvancedOcr()
  2. {
  3. CleanBackgroundNoise = true,
  4. EnhanceContrast = true,
  5. EnhanceResolution = true,
  6. Language = IronOcr.Languages.English.OcrLanguagePack,
  7. Strategy = IronOcr.AdvancedOcr.OcrStrategy.Advanced,
  8. ColorSpace = AdvancedOcr.OcrColorSpace.GrayScale,
  9. DetectWhiteTextOnDarkBackgrounds = false,
  10. InputImageType = AdvancedOcr.InputTypes.Document,
  11. RotateAndStraighten = true,
  12. ReadBarCodes = false,
  13. ColorDepth = 4
  14. };
  15. var Results = Ocr.Read(“img/Potter.LowQuality.tiff”);

Copy code to clipboardVB  C#

This OCR job yields an accuracy of 95.6% which is almost as accurate as the OCR of a high quality scan, although it may take a little longer to run.

C# OCR Scan Accuracy

Performance Tuning

The most important factor in the speed of an OCR job is in fact the quality of the input image. The less background noise that is present and the higher the dpi, with a perfect target dpi at about 300 dpi, will cause the fastest and most accurate OCR results.

This is not, however, necessary, as Iron OCR shines at correcting imperfect documents (though this is time-consuming and will cause your OCR jobs to use more CPU cycles).

If possible, choosing input image formats with less digital noise such as TIFF or PNG can also yield faster results than lossy image formats such as JPEG.

Example: Setup for Speed

Using AdvancedOCR, we may wish to disable some of the more time-consuming features, such as clean background noise, enhance contrast, enhance resolution, rotate & straighten, if we do not believe that these features are necessary for our specific input documents. This will save up to 50% of the OCR time.

If optimizing for speed we might start at this position and then turn features back on until the prefect balance is found.

  1. var Ocr = new AdvancedOcr()
  2. {
  3. CleanBackgroundNoise = false,
  4. EnhanceContrast = false,
  5. EnhanceResolution = false,
  6. Language = IronOcr.Languages.English.OcrLanguagePack,
  7. Strategy = IronOcr.AdvancedOcr.OcrStrategy.Fast,
  8. ColorSpace = AdvancedOcr.OcrColorSpace.GrayScale,
  9. DetectWhiteTextOnDarkBackgrounds = false,
  10. InputImageType = AdvancedOcr.InputTypes.Document,
  11. RotateAndStraighten = false,
  12. ReadBarCodes = false,
  13. ColorDepth = 4
  14. };
  15. var Results = Ocr.Read(“img/300dpi.png”);

Copy code to clipboardVB  C#

Reading Cropped Regions of Images

As you can see from the following code sample, Iron OCR is adept at reading specific areas of images. We may use a System.Drawing.Rectangle to specify, in pixels, the exact area of an image to read.

This can be incredibly useful when we are dealing with a standardized form which is filled out, where only a certain area has text which changes from case to case.

Example: Scanning an Area of a Page

We can use a System.Drawing.Rectangle to specify a region in which we will read a document. The unit of measurement is always pixels.

We will see that this provides speed improvements as well as avoiding reading unnecessary text. In this example we will read a students name from a central area of a standardized document.

 

C# OCR Scan From Tiff Example   C# OCR Scan From Tiff Example

 

  1. var Ocr = new IronOcr.AutoOcr();
  2. var Area = new System.Drawing.Rectangle() { X = 215, Y = 1250, Height = 280, Width = 1335 };
  3. var Results = Ocr.Read(“img/ComSci.Png”, Area);
  4. Console.WriteLine(Results.Text);

Copy code to clipboardVB  C#

Cropping is also supported when reading PDFs – Click here to see the object reference.

International Languages

Iron OCR supports 22 international languages via language packs which are distributed as DLLs, which can be downloaded from this website, or also from the NuGet Package Manager for Visual Studio.

We can install them by browsing NuGet (search for “IronOcr Languages”) or from the OCR language packs page.

Supported languages Include:

  • English
  • Arabic
  • ChineseSimplified
  • ChineseTraditional
  • Czech
  • Danish
  • Finnish
  • French
  • German
  • Greek
  • Hebrew
  • Hungarian
  • Italian
  • Japanese
  • Korean
  • Norwegian
  • Polish
  • Portuguese
  • Russian
  • Spanish
  • Swedish
  • Thai
  • Turkish
Example: OCR in Arabic (+ many more)

In the following example, we will show how we can scan an Arabic document.

PM> Install-Package IronOcr.Languages.ArabicC# OCR in Arabic Language

  1. var Ocr = new AutoOcr()
  2. {
  3. Language = IronOcr.Languages.Arabic.OcrLanguagePack,
  4. };
  5. var Results = Ocr.Read(“img/arabic.gif”);
  6. Console.WriteLine(“{0} Characters of Arabic Read”,Results.Text.Length);
  7. // Note that the .Net Console can not yet display Arabic characters… they all print as question marks.

Copy code to clipboardVB  C#

Example: OCR in more than one languge in the same document.

In the following example, we will show how to OCR scan multiple languages to the same document.

This is actually very common, where for example a Chinese document way contain English words and Urls.

PM> Install-Package IronOcr.Languages.ChineseSimplified

  1. var Ocr = new AdvancedOcr();
  2. Ocr.Language = new IronOcr.Languages.MultiLanguage(IronOcr.Languages.ChineseSimplified.OcrLanguagePack, IronOcr.Languages.English.OcrLanguagePack)

Copy code to clipboardVB  C#

A Detailed Look at Image to Text OCR Results

The last thing we will look at in this tutorial is the OCR results object. When we read OCR, we normally only want the text out, but Iron OCR actually contains a huge amount of information which may be of use to advanced developers.

Within an OCR results object, we have a collection of pages which can be iterated. Within each page, we may find barcodes, power graphs, lines of text, words, and characters.

Each of these objects in fact contains: a location; an X coordinate; a Y coordinate; a width and a height; an image associated with it which can be inspected; a font name; the font size; the direction in which the text is written; the rotation of the text; and the statistical confidence that Iron OCR has for that specific word, line, or paragraph.

In short, this allows developers to create advanced OCR applications and to find out and deal with scenarios where they have less than 100% confidence in their input content.

  1. using IronOcr;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Drawing; //Add Assembly Reference
  5. // We can delve deep into OCR results as an object model of
  6. // Pages, Barcodes, Paragraphs, Lines, Words and Characters
  7. var Ocr = new AdvancedOcr()
  8. {
  9. Language = IronOcr.Languages.English.OcrLanguagePack,
  10. ColorSpace = AdvancedOcr.OcrColorSpace.GrayScale,
  11. EnhanceResolution = true,
  12. EnhanceContrast = true,
  13. CleanBackgroundNoise = true,
  14. ColorDepth = 4,
  15. RotateAndStraighten = false,
  16. DetectWhiteTextOnDarkBackgrounds = false,
  17. ReadBarCodes = true,
  18. Strategy = AdvancedOcr.OcrStrategy.Fast,
  19. InputImageType = AdvancedOcr.InputTypes.Document
  20. };
  21. var results = Ocr.Read(@”pathtodocument.png”);
  22. foreach (var page in results.Pages)
  23. {
  24. // page object
  25. int page_number = page.PageNumber;
  26. String page_text = page.Text;
  27. int page_wordcount = page.WordCount;
  28. List<OcrResult.OcrBarcode> barcodes = page.Barcodes;
  29. System.Drawing.Image page_image = page.Image;
  30. int page_width_px = page.Width;
  31. int page_height_px = page.Height;
  32. foreach (var paragraph in page.Paragraphs)
  33. {
  34. // pages -> paragraphs
  35. int paragraph_number = paragraph.ParagraphNumber;
  36. String paragraph_text = paragraph.Text;
  37. System.Drawing.Image paragraph_image = paragraph.Image;
  38. int paragraph_x_location = paragraph.X;
  39. int paragraph_y_location = paragraph.Y;
  40. int paragraph_width = paragraph.Width;
  41. int paragraph_height = paragraph.Height;
  42. double paragraph_ocr_accuracy = paragraph.Confidence;
  43. string paragraph_font_name = paragraph.FontName;
  44. double paragraph_font_size = paragraph.FontSize;
  45. OcrResult.TextFlow paragrapth_text_direction = paragraph.TextDirection;
  46. double paragrapth_rotation_degrees = paragraph.TextOrientation;
  47. foreach (var line in paragraph.Lines)
  48. {
  49. // pages -> paragraphs -> lines
  50. int line_number = line.LineNumber;
  51. String line_text = line.Text;
  52. System.Drawing.Image line_image = line.Image;
  53. int line_x_location = line.X;
  54. int line_y_location = line.Y;
  55. int line_width = line.Width;
  56. int line_height = line.Height;
  57. double line_ocr_accuracy = line.Confidence;
  58. double line_skew = line.BaselineAngle;
  59. double line_offset = line.BaselineOffset;
  60. foreach (var word in line.Words)
  61. {
  62. // pages -> paragraphs -> lines -> words
  63. int word_number = word.WordNumber;
  64. String word_text = word.Text;
  65. System.Drawing.Image word_image = word.Image;
  66. int word_x_location = word.X;
  67. int word_y_location = word.Y;
  68. int word_width = word.Width;
  69. int word_height = word.Height;
  70. double word_ocr_accuracy = word.Confidence;
  71. String word_font_name = word.FontName;
  72. double word_font_size = word.FontSize;
  73. bool word_is_bold = word.FontIsBold;
  74. bool word_is_fixed_width_font = word.FontIsFixedWidth;
  75. bool word_is_italic = word.FontIsItalic;
  76. bool word_is_serif_font = word.FontIsSerif;
  77. bool word_is_underlined = word.FontIsUnderlined;
  78. foreach (var character in word.Characters)
  79. {
  80. // pages -> paragraphs -> lines -> words -> characters
  81. int character_number = character.CharacterNumber;
  82. String character_text = character.Text;
  83. System.Drawing.Image character_image = character.Image;
  84. int character_x_location = character.X;
  85. int character_y_location = character.Y;
  86. int character_width = character.Width;
  87. int character_height = character.Height;
  88. double character_ocr_accuracy = character.Confidence;
  89. }
  90. }
  91. }
  92. }
  93. }

Copy code to clipboardVB  C#

Putting this all together, we can see that if we input even an imperfect document [insert document] to Iron OCR, it can accurately read its content to a statistical accuracy of about 98% to 99%, even though the document was badly formatted, skewed, and had a lot of digital noise. This is unique to Iron OCR and is a feature you will not find in standard OCR libraries.

Moving Forward

To continue to learn more about Iron OCR, we recommend you try the code samples on the IronOCR homepage, visit us on GitHub, or read the in-depth MSDN-style Object Reference.

Source Code Download

You may also enjoy the other .Net OCR tutorials in this section.

Data & News supplied by www.cloudquote.io
Stock quotes supplied by Barchart
Quotes delayed at least 20 minutes.
By accessing this page, you agree to the following
Privacy Policy and Terms and Conditions.