DEV Community

Xiao Ling
Xiao Ling

Posted on • Edited on • Originally published at dynamsoft.com

Web Parcel Management: Scan 1D Barcodes and Recognize Surrounding Text in Any Orientation

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.

parcel management with barcode and OCR

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.

    Dynamsoft Capture Vision trial license

  • Generate a combo of Dynamsoft SDK modules for barcode and OCR.

    1. Open the generator page.
    2. Select "NPM for JavaScript Edition".
    3. Check Dynamsoft Barcode Reader, Dynamsoft Label Recognizer, and Dynamsoft Camera Enhancer.

      Generate Dynamsoft SDK modules

4. Click the `Generate` button to get the combo URLs.
Enter fullscreen mode Exit fullscreen mode
    ```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>
    ```
Enter fullscreen mode Exit fullscreen mode
    Copy the above script tags to your HTML file. Do not disrupt the order, or you will encounter errors.
Enter fullscreen mode Exit fullscreen mode

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 Architecture

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>
Enter fullscreen mode Exit fullscreen mode

Step 2.Initialize Dynamsoft Barcode Reader and Dynamsoft Label Recognizer

  1. Set the license key:

    Dynamsoft.License.LicenseManager.initLicense(license);
    
  2. 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.

  3. 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
    
  4. Create instances of CaptureVisionRouter, CameraView, CameraEnhancer and CapturedResultReceiver. The CapturedResultReceiver 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);
    
  5. 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.

  6. 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.

  7. 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.

    scan barcode and OCR text in web

Troubleshooting

If you encounter issues with text recognition, check the developer console to verify whether the OCR model has been loaded successfully.

check OCR model in the developer console

Source Code

https://github.com/yushulx/javascript-barcode-qr-code-scanner/tree/main/examples/10.x/barcode_ocr_text

Top comments (0)