In today's fast-paced world, efficiently managing and tracking parcels is crucial for businesses. The use of 1D and 2D barcodes has revolutionized the way parcels are labeled, scanned, and processed. Additionally, Optical Character Recognition (OCR) technology has enabled the digitization of text on parcels, facilitating automated data extraction and processing. Most OCR technologies can only recognize text in a horizontal orientation. However, in real-world scenarios, a barcode and its surrounding text label can appear in any orientation on a parcel. This article aims to address this challenge using Dynamsoft Capture Vision SDKs.
Online Demo
https://yushulx.me/javascript-barcode-qr-code-scanner/examples/10.x/barcode_ocr_text
Prerequisites
-
Obtain a 30-Day trial license key for multiple Dynamsoft SDK modules.
-
Generate a combo of Dynamsoft SDK modules for barcode and OCR.
- Open the generator page.
- Select "NPM for JavaScript Edition".
-
Check Dynamsoft Barcode Reader, Dynamsoft Label Recognizer, and Dynamsoft Camera Enhancer.
4. Click the `Generate` button to get the combo URLs.
```bash
<script src="https://cdn.jsdelivr.net/npm/dynamsoft-core@3.0.33/dist/core.js"></script>
<script src="https://cdn.jsdelivr.net/npm/dynamsoft-barcode-reader@10.0.21/dist/dbr.js"></script>
<script src="https://cdn.jsdelivr.net/npm/dynamsoft-camera-enhancer@4.0.1/dist/dce.js"></script>
<script src="https://cdn.jsdelivr.net/npm/dynamsoft-capture-vision-router@2.0.32/dist/cvr.js"></script>
<script src="https://cdn.jsdelivr.net/npm/dynamsoft-label-recognizer@3.0.30/dist/dlr.js"></script>
<script src="https://cdn.jsdelivr.net/npm/dynamsoft-license@3.0.40/dist/license.js"></script>
<script src="https://cdn.jsdelivr.net/npm/dynamsoft-utility@1.0.21/dist/utility.js"></script>
```
Copy the above script tags to your HTML file. Do not disrupt the order, or you will encounter errors.
The Architecture of Dynamsoft Capture Vision
If this is your first time hearing about Dynamsoft Capture Vision, you may wonder how it works. The following diagram illustrates the architecture of Dynamsoft Capture Vision:
Dynamsoft Capture Vision consists of several key modules: Dynamsoft Barcode Reader, Dynamsoft Label Recognizer, Dynamsoft Document Normalizer, Dynamsoft Code Parser, and Dynamsoft Camera Enhancer. These modules can function independently or collaboratively, providing a comprehensive solution for barcode scanning, OCR, document processing, and image enhancement.
In the parcel management scenario discussed in this article, we focus on Dynamsoft Barcode Reader and Dynamsoft Label Recognizer. The former is used to scan 1D barcodes, while the latter is used to recognize text on parcels. In the subsequent sections, you will learn how to integrate these two modules into a web application.
How to Scan 1D Barcodes and OCR Text Simultaneously
Step 1. Include the Dynamsoft SDK Modules
Create an HTML file and include the script tags generated in the prerequisites section.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdn.jsdelivr.net/npm/dynamsoft-core@3.2.30/dist/core.js"></script>
<script src="https://cdn.jsdelivr.net/npm/dynamsoft-license@3.2.20/dist/license.js"></script>
<script src="https://cdn.jsdelivr.net/npm/dynamsoft-utility@1.2.20/dist/utility.js"></script>
<script src="https://cdn.jsdelivr.net/npm/dynamsoft-label-recognizer@3.2.30/dist/dlr.js"></script>
<script src="https://cdn.jsdelivr.net/npm/dynamsoft-barcode-reader@10.2.10/dist/dbr.js"></script>
<script src="https://cdn.jsdelivr.net/npm/dynamsoft-capture-vision-router@2.2.30/dist/cvr.js"></script>
<script src="https://cdn.jsdelivr.net/npm/dynamsoft-camera-enhancer@4.0.2/dist/dce.js"></script>
<title>Dynamsoft Capture Vision Example</title>
<link rel="stylesheet" href="main.css">
</head>
<body>
</body>
</html>
Step 2.Initialize Dynamsoft Barcode Reader and Dynamsoft Label Recognizer
-
Set the license key:
Dynamsoft.License.LicenseManager.initLicense(license);
-
Load the wasm files actively:
Dynamsoft.Core.CoreModule.loadWasm(["cvr", "dbr", "dlr",]);
Downloading WASM files may take some time. Without calling this method, the SDK will load the WASM files automatically when needed. However, this may cause a delay when scanning barcodes or recognizing text.
-
Pick a suitable OCR model for the label recognizer:
await Dynamsoft.DLR.LabelRecognizerModule.loadRecognitionData("Letter");
All available OCR models are listed in the documentation. You can choose the one that best fits your scenario.
Letter.data MRZ.data Number.data NumberLetter.data NumberUppercase.data Uppercase.data VIN.data
-
Create instances of
CaptureVisionRouter
,CameraView
,CameraEnhancer
andCapturedResultReceiver
. TheCapturedResultReceiver
provides callbacks for handling different types of results, such as barcode results and text results.
let router = await Dynamsoft.CVR.CaptureVisionRouter.createInstance(); let view = await Dynamsoft.DCE.CameraView.createInstance(); let cameraEnhancer = await Dynamsoft.DCE.CameraEnhancer.createInstance(view); document.querySelector("#cameraViewContainer").append(view.getUIElement()); router.setInput(cameraEnhancer); const resultsContainer = document.querySelector("#results"); const resultReceiver = new Dynamsoft.CVR.CapturedResultReceiver(); let lastResult = {}; resultReceiver.onCapturedResultReceived = (result) => { if (result.items.length == 0) { resultsContainer.textContent = ''; } } resultReceiver.onDecodedBarcodesReceived = (result) => { if (!lastResult["id"]) { lastResult["id"] = result.originalImageTag.imageId; } else { if (lastResult["id"] !== result.originalImageTag.imageId) { resultsContainer.textContent = ''; lastResult["id"] = result.originalImageTag.imageId; } } if (result.barcodeResultItems.length > 0) { for (let item of result.barcodeResultItems) { resultsContainer.textContent += `Barcode Type: ${item.formatString}, Value: ${item.text}\n\n`; } } } resultReceiver.onRecognizedTextLinesReceived = (result) => { if (!lastResult["id"]) { lastResult["id"] = result.originalImageTag.imageId; } else { if (lastResult["id"] !== result.originalImageTag.imageId) { resultsContainer.textContent = ''; lastResult["id"] = result.originalImageTag.imageId; } } if (result.textLineResultItems.length > 0) { for (let item of result.textLineResultItems) { resultsContainer.textContent += `Text: ${item.text}\n`; } } }; router.addResultReceiver(resultReceiver);
-
Define a custom template for image processing logics and set it to the router:
let settings = { "CaptureVisionTemplates": [ { "Name": "ReadBarcode&AccompanyText", "ImageROIProcessingNameArray": [ "roi-read-barcodes-only", "roi-read-text" ] } ], "TargetROIDefOptions": [ { "Name": "roi-read-barcodes-only", "TaskSettingNameArray": ["task-read-barcodes"] }, { "Name": "roi-read-text", "TaskSettingNameArray": ["task-read-text"], "Location": { "ReferenceObjectFilter": { "ReferenceTargetROIDefNameArray": ["roi-read-barcodes-only"] }, "Offset": { "MeasuredByPercentage": 1, "FirstPoint": [-20, -50], "SecondPoint": [150, -50], "ThirdPoint": [150, -5], "FourthPoint": [-20, -5] } } } ], "CharacterModelOptions": [ { "Name": "Letter" } ], "ImageParameterOptions": [ { "Name": "ip-read-text", "TextureDetectionModes": [ { "Mode": "TDM_GENERAL_WIDTH_CONCENTRATION", "Sensitivity": 8 } ], "TextDetectionMode": { "Mode": "TTDM_LINE", "CharHeightRange": [ 20, 1000, 1 ], "Direction": "HORIZONTAL", "Sensitivity": 7 } } ], "TextLineSpecificationOptions": [ { "Name": "tls-11007", "CharacterModelName": "Letter", "CharHeightRange": [5, 1000, 1], "BinarizationModes": [ { "BlockSizeX": 30, "BlockSizeY": 30, "Mode": "BM_LOCAL_BLOCK", "MorphOperation": "Close" } ] } ], "BarcodeReaderTaskSettingOptions": [ { "Name": "task-read-barcodes", "BarcodeFormatIds": ["BF_ONED"] } ], "LabelRecognizerTaskSettingOptions": [ { "Name": "task-read-text", "TextLineSpecificationNameArray": [ "tls-11007" ], "SectionImageParameterArray": [ { "Section": "ST_REGION_PREDETECTION", "ImageParameterName": "ip-read-text" }, { "Section": "ST_TEXT_LINE_LOCALIZATION", "ImageParameterName": "ip-read-text" }, { "Section": "ST_TEXT_LINE_RECOGNITION", "ImageParameterName": "ip-read-text" } ] } ] } await router.initSettings(settings);
There are several preset templates defined in the SDK. If none of them fits your scenario, you can create a custom template like the one above.
-
Start the camera and the router:
await cameraEnhancer.open(); await router.startCapturing("ReadBarcode&AccompanyText");
The
ReadBarcode&AccompanyText
string is the name of the custom template defined in the previous step. -
Run the application in a browser. Point the camera at a parcel with a 1D barcode and text label. The application will scan the barcode and recognize the text simultaneously.
Troubleshooting
If you encounter issues with text recognition, check the developer console to verify whether the OCR model has been loaded successfully.