<p><div><div><div><div data-show-faces="false" data-height="21" data-width="100" data-layout="button_count" data-send="true" data-href="https://www.r-bloggers.com/support-for-hocr-and-tesseract-4-in-r/"></div></div><div></div></div><div></div></div>
<div>
(This article was first published on <strong><a href="https://ropensci.org/technotes/2018/02/14/tesseract-18/"> rOpenSci - open tools for open science</a></strong>, and kindly contributed to <a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers)</a> </div>
<p> <img alt="cover image" src="https://i0.wp.com/upload.wikimedia.org/wikipedia/commons/d/d7/8-cell.gif?w=456&ssl=1" data-recalc-dims="1"></p>
<p>Earlier this month we released a new version of the <a rel="nofollow" href="https://cran.r-project.org/package=tesseract" target="_blank">tesseract</a> package to CRAN. This package provides R bindings to Google’s open source optical character recognition (OCR) engine <a rel="nofollow" href="https://github.com/tesseract-ocr/tesseract" target="_blank">Tesseract</a>.</p>
<p>Two major new features are support for HOCR and support for the upcoming Tesseract 4.</p>
<h2>hOCR output</h2>
<p>Support for HOCR output was <a rel="nofollow" href="https://github.com/ropensci/tesseract/issues/20" target="_blank">requested</a> by one of our users on Github. The <code>ocr()</code> function gains a parameter <code>HOCR</code> which allows for returning results in hOCR format:</p>
<pre><code>library(tesseract)

# Text output
text &lt;- ocr(&quot;https://jeroen.github.io/images/testocr.png&quot;)
cat(text)

# hOCR output
xml &lt;- ocr(&quot;https://jeroen.github.io/images/testocr.png&quot;, HOCR = TRUE)
cat(xml)
</code></pre>
<p>hOCR is an open standard of data representation for formatted text obtained from OCR <a rel="nofollow" href="https://en.wikipedia.org/wiki/HOCR" target="_blank">(wikipedia)</a>. The definition encodes text, style, layout information, recognition confidence metrics and other information using XML.</p>
<p>Every word in the hOCR output includes meta data such as bounding box, confidence metrics, etc. With a little xml2 and regular expression magic we can extract a beautiful data frame:</p>
<pre><code>library(tesseract)
library(xml2)
library(stringr)
library(tibble)
xml &lt;- ocr(&quot;https://jeroen.github.io/images/testocr.png&quot;, HOCR = TRUE)
doc &lt;- read_xml(xml)
nodes &lt;- xml_find_all(doc, &quot;.//span[@class='ocrx_word']&quot;)
words &lt;- xml_text(nodes)
metatext &lt;- xml_attr(nodes, 'title')
bbox &lt;- str_replace(str_extract(meta, &quot;bbox [\\d ]+&quot;), &quot;bbox &quot;, &quot;&quot;)
conf &lt;- as.numeric(str_replace(str_extract(meta, &quot;x_wconf.*&quot;), &quot;x_wconf &quot;, &quot;&quot;))
tibble(confidence = conf, word = words, bbox = bbox)
</code></pre>
<pre><code># A tibble: 60 x 3
   confidence word  bbox          
        </code></pre>