OCR plugins
The ocr plugin works in the synchronous mode, and therefore, becomes a performance bottleneck if used within a BP where the OCR page volume is high, or documents contain more than 20 pages.
ocr
Open plugin description
The plugin recognizes text in images using the WorkFusion OCR service.
The ocr plugin must contain one or more ocr-image plugins and zero or one ocr-pattern plugin. The ocr-image and ocr-pattern plugins need not be nested immediately in ocr, but can be nested into other tags that are directly or indirectly nested in ocr.
You should define JWT parameters in the secure storage. These parameters are used by the ocr plugin to authenticate to the OCR service.
The properties in the secure storage are as follows:
jwt.secret=<jwt secret shared with the ocr instance>
jwt.issuer=workfusion
Define the ocr plugin parameters in $CATALINA_HOME/conf/workfusion.properties:
...
# base URL of the OCR instance where to send requests
ocr.api.base_url=http://your-ocr-host.com/api
# for how long to wait for OCR to complete
ocr.completion_polling.timeout.seconds=1800
# how often to check OCR completion status
ocr.completion_polling.interval.seconds=15
# for how long to keep jwt authentication token before generating a new one. should be < jwt.expiration.minutes
jwt.cache.token_reuse_period.minutes=30
# time-to-live for JWT token
jwt.expiration.minutes=60
When configuring ocr.api.base_url, you need to include /api in the end, as in the example above. Check that the HTTP or HTTPS protocol is configured correctly. Your URL can also include a non-default port.
You can override the base URL and polling parameters in the plugin, but it is not recommended.
Make sure you send the direct link to the source file for OCR. When you upload a file to Dropbox and try to use this link, this doesn't work correctly, as in this case, you send the Dropbox web page to the OCR process that returns an exception.
The plugin contains the following attributes:
| Name | Default | Description |
|---|---|---|
correct-skew | True | For correctSkew, refer to OCR SDK. |
export-format | TXT | Specifies the set export formats. This parameter can contain up to three export formats, separated with commas, for example, txt,pdfSearchable,xml. Supported formats are as follows:
getResults() map property in the ocr plugin result, where each result is accessible by an export format name as a key. |
xml-write-recognition-variants | False | Makes the xml and xmlForCorrectedImage formats to contain all variants of character or word OCR considered as a possible recognition. Also, see xml:writeRecognitionVariants in OCR SDK. |
profile | documentConversion | See the profile in OCR SDK. |
language | English | See language in OCR SDK. |
engine | ABBYY | Currently can be only ABBYY. |
correct-orientation | True | See correctOrientation in OCR SDK. |
custom-regions | Defines regions to process. Has the JSON format: [{"page":1,"left":0,"top":0,"right":800,"bottom":600,"type":"BT_Text"}]. Possible values: BT_Text, BT_RasterPicture, BT_Table, BT_Barcode, BT_VectorPicture, BT_Checkmark, BT_CheckmarkGroup. See more details here in the BlockTypeEnum section. Remember that the XML syntax applies to the machine config. Thus, the above JSON should be included according to the XML escaping rules. Particularly, you can either replace " with " escape sequence, or you can enclose the attribute value with single quotes ' instead of double quotes." | |
skip-preprocessing | False | Can be true or false. |
use-only-custom-regions | False | Can be true or false. If true, OCR skips the original analyzing stage and extracts information from custom regions only. |
use-words-from-dictionary-only | False | Can be true or false.Not supported for multiple images. |
dictionary | A string containing a new-line-separated list of words to use as a dictionary to improve recognition. The set of words extends, not limits, the default dictionary. Not supported for multiple images. | |
alphabet-extension | A string with extra symbols to extend the already defined alphabet. | |
allowed-region-types | Comma-separated list of allowed region types for identified blocks classification. For example, to suppress classifying any block as a picture (BT_RasterPicture), specify the parameter value as BT_Table, BT_Text,BT_Barcode, BT_VectorPicture. | |
custom-alphabet | Specifies a set of characters to be used as an alphabet for recognition. | |
skip-text-layer-extraction | False | Text layer of the source PDF file is not used, only the image layer is recognized. |
original-text | Not supported for multiple images. | |
remove-noise-models | Instructs to remove noise on the image. Contains comma-separated values: CorrelatedNoise, WhiteNoise. The method can be used for color and 8-bit gray images only. | |
remove-garbage-size | Instructs to remove garbage (excess dots smaller than a certain size) from the image. Should be > 0; or -1 to detect garbage size automatically. | |
debug | False | Can be true or false. Instructs to keep extra logging and data for debugging purposes. Do not use for text with sensitive data. |
use-default-pattern | False | Can be true or false. Instructs to apply default pattern bundled with the OCR application. Cannot be used together with the ocr-pattern plugin. |
discard-color-image | False | If you work with black-and-white images or the color of images is not important, set the discard-color-image to true. |
enhance-local-contrast | False | Specifies whether the local contrast of the image should be increased. Such preprocessing may increase the quality of recognition. It is effective for:
|
priority | 0 | An integer number that defines priority in the image processing queue.Max priority is limited to the spring.int.messaging.priority.max value (10 by default). |
timeout | ocr.process.timeout property value in application.properties of the OCR-Rest service. | An integer number that defines timeout in seconds. |
completion-polling-timeout-seconds | ocr.completion_polling.timeout.seconds property value in application.properties config of WorkFusion or 15. | Defines for how long to poll the OCR status while awaiting completion. |
completion-polling-interval-seconds | ocr.completion_polling.interval.seconds property value in application.properties config of WorkFusion. | Defines how often to poll OCR completion status. |
api-base-url | ocr.api.base_url property value in application.properties config of WorkFusion. | Base URL for OCR HTTP API. |
For more information, refer to OCR REST API and processImage | OCR SDK.
In case of success, the ocr plugin returns Java Bean of the OcrResult type that provides response metadata (status, task ID, and so on) together with the map of downloaded results, for example, format > byte array of content. As a result, it can be a PDF which is not necessarily convertible to a string.
| Name | Type | Description |
|---|---|---|
results | Map<String, byte[]> | Maps where the key is the export format and the value is the recognition result content. |
id | String | OCR task ID. |
status | String | Describes the resulting execution status. Supposedly, it is always Completed. The ocr plugin polls the OCR service for the OCR task completion. If it encounters a timeout or a recognition failure, it throws an error. Possible values: Submitted, Queued, Scheduled, InProgress, Completed, ProcessingFailed, Deleted, Cancelled. |
registrationTime | String containing date-time | Time of the first submitImage or processImage. |
processStartTime | String containing date-time | Time of the recognition process start; more precisely, when it is taken from the queue. |
processEndTime | String containing date-time | Time of the recognition process completion or failure. |
statusChangeTime | String containing date-time | Time when the OCR task status was changed: Submitted, Queued, Started, Completed, Failed, Cancelled. |
message | String | Currently used only to indicate that the task is "Cancelled by expiry." |
If the image recognition fails, a network, infrastructure, or other error happens, and an exception is thrown from the ocr plugin.
ocr-image
Open plugin description
To pass an image to OCR, you need to pass a byte array as a body of ocr-image. Make sure you do not pass an image as a string. Otherwise, you can get a runtime error or data corrupted. The ocr-image plugin must be nested in the corresponding ocr plugin. You can use multiple ocr-image per one ocr plugin. In this case, the images are joined and recognized into a single resulting document. In other words, the number of resulting images in the getResults() property depends on the number of export formats specified in the export-format attribute, but not on the number of images passed with ocr-image.
The plugin does not accept any attributes.
OCR for RPA does not support multiple images per single and images in PDF format. An attempt to use those fails.
ocr-pattern
Open plugin description
To pass a pattern to OCR, you need to pass a byte array as a body of ocr-pattern. Make sure you do not pass the pattern file as a string. The ocr-pattern plugin must be nested in the corresponding ocr plugin. You can use only one per one plugin. Which pattern is applied if multiple are passed is unspecified.
The plugin does not accept any attributes. Also, you cannot use with the use-default-pattern attribute of the plugin.
To recognize special symbols in the text, you might need to use a pattern. To retrieve a pattern, you can use the POST api/v1/cloud/trainPattern action. For more information, see POST /trainPattern.
Example:
<var-def name="ocrResult">
<ocr>
<ocr-image>
<var name="inputImageByteArray"/>
</ocr-image>
</ocr>
</var-def>
The ocrResult variable of the OcrResult type contains the result. Due to WebHarvest design peculiarities, the access to the result looks like this:
<script return="ocrResult.get(0).wrappedObject.results['txt']"/>
You can pass the following entities:
Multiple input images:
<ocr>
<ocr-image> <var name="image1"/> </ocr-image>
<ocr-image> <var name="image2"/> </ocr-image>
</ocr>Multiple input images in a loop:
<ocr>
<loop item="image">
<list>
<var name="images"/>
</list>
<body>
<ocr-image> <var name="image"/> </ocr-image>
</body>
</loop>
</ocr>Patterns:
<ocr>
<ocr-image>
<var name="image_byte_array"/>
</ocr-image>
<ocr-pattern>
<var name="pattern_byte_array"/>
</ocr-pattern>
</ocr>Multiple export formats:
<var-def name="ocrResult">
<ocr export-format="xmlForCorrectedImage,pdfSearchable">
<ocr-image> <var name="image"/> </ocr-image>
</ocr>
</var-def>
<script return="ocrResult.get(0).wrappedObject.results['pdfSearchable']"/>A sample image and a pattern:
<config charset="UTF-8" scriptlang="Groovy">
<var-def name="ocr">
<ocr correct-skew="true">
<ocr-image>
<http url="http://user.s3.amazonaws.com/myuploads/costa_rican_colon.pdf"/>
</ocr-image>
<ocr-pattern>
<http url="http://user.s3.amazonaws.com/myuploads/costa_rican_colon.ptn"/>
</ocr-pattern>
</ocr>
</var-def>
<export include-original-data="true">
<single-column name="some_column" value="${new String(ocr.get(0).wrappedObject.results['txt'])}"/>
</export>
</config>ocr with caching:
<config xmlns="http://web-harvest.sourceforge.net/schema/1.0/config" scriptlang="groovy">
<script>
documentLink = "http://yourdomain.com/your_path";
cacheTable = "your_ocr_cache_table_name";
</script>
<var-def name="document">
<http url="${documentLink}"/>
</var-def>
<script>
if (http.statusCode.toString().matches('^[45]\\d{2}')) {
throw new RuntimeException("failed downloading the link: " + documentLink);
}
documentHash = org.apache.commons.codec.digest.DigestUtils.md5Hex(document.toBinary());
</script>
<create-datastore name="${cacheTable}">
<datastore-column name="key"/>
<datastore-column name="result"/>
</create-datastore>
<var-def name="cachedRecord">
<datastore name="${cacheTable}" max="1">
<template>
select * from @this where "key"='${documentHash}'
</template>
</datastore>
</var-def>
<case>
<if condition='${cachedRecord.toString().length() != 0}'>
<var-def name="result">
<xpath expression='/row/result/text()'>
<var name="cachedRecord"/>
</xpath>
</var-def>
</if>
<else>
<var-def name="ocr">
<ocr export-format="txt">
<ocr-image>
<var name="document"/>
</ocr-image>
</ocr>
</var-def>
<var-def name="result">
<s3 bucket="your_s3_bucket_for_ocr_uploads">
<s3-put path="ocr/${java.util.UUID.randomUUID()}.txt" content-type="text/plain" content-disposition="inline">
<script return="ocr.get(0).wrappedObject.results['txt']"/>
</s3-put>
</s3>
</var-def>
<insert-datastore
datastore-name="${cacheTable}"
json-value-map='${new com.google.gson.Gson().toJson(["key": documentHash, "result": result.toString()])}'/>
</else>
</case>
<export include-original-data="true">
<single-column name="result" value="${result}"/>
</export>
</config>