These are just a few Python barcode SDKs that support ARM32 and ARM64 architectures. Dynamsoft Barcode Reader is the only commercial 1D and 2D barcode SDK that provides barcode recognition capabilities for ARM32 and ARM64 devices. This article demonstrates how to create ARM32 and ARM64 emulated environments on Windows to implement barcode scanning with Dynamsoft Python Barcode SDK.
Getting Started with Dynamsoft Python Barcode SDK
You can install the Dynamsoft Python Barcode SDK using pip:
pip install dbr
The Python package supports Python 3.6 and above.
Supported Platforms
- Windows (x64)
- Linux (x64, ARM32, and ARM64)
- macOS (x64 and ARM64)
License Key
After installing the Python barcode SDK, you need to apply for a valid license to activate it.
from dbr import *
BarcodeReader.init_license(license_key)
Quick Start
from dbr import *
license_key = "Input your own license"
image = r"Please input your own image path"
BarcodeReader.init_license(license_key)
reader = BarcodeReader()
try:
text_results = reader.decode_file(image)
if text_results != None:
for text_result in text_results:
print("Barcode Format : ")
print(text_result.barcode_format_string)
print("Barcode Text : ")
print(text_result.barcode_text)
print("Localization Points : ")
print(text_result.localization_result.localization_points)
print("Exception : ")
print(text_result.exception)
print("-------------")
except BarcodeReaderError as bre:
print(bre)
Sample Code
https://github.com/Dynamsoft/barcode-reader-python-samples
Online API Documentation
https://www.dynamsoft.com/barcode-reader/docs/server/programming/python/
Visual Studio Code Extension
https://marketplace.visualstudio.com/items?itemName=yushulx.dbr-code-generator
Why Do You Need ARM32 and ARM64 Emulated Environments?
If you want to create a Python barcode scanning application that can run on an ARM32 or ARM64 device, like Raspberry Pi and Jetson Nano, an emulated environment is a convenient way to write and test code without the need for a physical ARM device.
How to Create Docker ARM32 and ARM64 Images Containing Dynamsoft Barcode SDK on Windows
QEMU is a popular open-source emulator that can emulate a variety of CPU architectures, including ARM, PowerPC, and MIPS. multiarch/qemu-user-static is a Docker image that allows you to emulate different CPU architectures on your host machine using QEMU.
Here are the steps to create Docker ARM32 and ARM64 images containing Dynamsoft Barcode SDK on Windows:
- Install Docker Desktop for Windows.
-
Install qemu-user-static:
docker run --rm --privileged multiarch/qemu-user-static:register --reset
-
Create a Dockerfile that specifies the base image as an arm32 or arm64 architecture, and installs the necessary tools and dependencies: CMake, Dynamsoft Barcode Reader, OpenCV and Pillow.
DockerfileArm32
FROM arm32v7/python RUN apt-get update && apt-get install -y cmake libgl1-mesa-glx RUN pip install dbr opencv-python pillow
DockerfileArm64
FROM arm64v8/python RUN apt-get update && apt-get install -y cmake libgl1-mesa-glx RUN pip install dbr opencv-python pillow
The
opencv-python
package is used to load and decode images to NumPy arrays, but it does not provide a pre-built wheel for ARM32. So, it may take a long time to build the package from the source code. Thepillow
package is an alternative toopencv-python
for loading and decoding images. -
Build the Docker images for ARM32 and ARM64:
docker build --platform linux/arm64 -f DockerfileArm64 -t <IMAGE-NAME> . docker build --platform linux/arm/v7 -f DockerfileArm32 -t <IMAGE-NAME> .
Now, we have successfully created Docker ARM32 and ARM64 images that contain Dynamsoft Python Barcode SDK. Next, we can write a Python barcode reader script and run it in the Docker container.
How to Run a Python Barcode Recognition Script in an ARM32 or ARM64 Docker Container
Most single-board computers, like Raspberry Pi and Jetson Nano, do not feature high-end hardware. Therefore, the decoding speed may not be ideal for large-sized images. The common scenario is to acquire images from a low-resolution (e.g. 640x480) USB camera and scan barcode QR codes in real-time.
To simulate the process, we first write a Python script to capture consecutive frames that contains QR codes from a USB camera and save them to a folder.
import cv2 as cv
from dbr import *
capture = cv.VideoCapture(0)
if not capture.isOpened():
print("Cannot open camera")
exit()
BarcodeReader.init_license("DLS2eyJoYW5kc2hha2VDb2RlIjoiMjAwMDAxLTE2NDk4Mjk3OTI2MzUiLCJvcmdhbml6YXRpb25JRCI6IjIwMDAwMSIsInNlc3Npb25QYXNzd29yZCI6IndTcGR6Vm05WDJrcEQ5YUoifQ==")
reader = BarcodeReader()
index = 0
while True:
frame = capture.read()[1]
cv.imshow("frame", frame)
if cv.waitKey(1) == ord('q'):
break
results = reader.decode_buffer(frame)
if results != None and len(results) > 0:
cv.imwrite('images/' + str(index) + '.png', frame)
index += 1
if index == 30:
break
Run the script on Windows and save the images to a folder named images
.
Then, we write another Python script to read the images using PIL
and decode barcodes with Dynamsoft Barcode Reader.
#!/usr/bin/env python3
import os
from dbr import *
import dbr
import time
from PIL import Image
def main():
print('version: ' + dbr.__version__)
BarcodeReader.init_license("DLS2eyJoYW5kc2hha2VDb2RlIjoiMjAwMDAxLTE2NDk4Mjk3OTI2MzUiLCJvcmdhbml6YXRpb25JRCI6IjIwMDAwMSIsInNlc3Npb25QYXNzd29yZCI6IndTcGR6Vm05WDJrcEQ5YUoifQ==")
reader = BarcodeReader()
reader.init_runtime_settings_with_file('faster.json', conflict_mode=EnumConflictMode.CM_OVERWRITE)
# read file list
folder = 'images'
target_dir = os.path.join(os.getcwd(), folder)
if os.path.exists(target_dir):
filelist = os.listdir('images')
index = 0
while index < 5:
file = filelist[index]
filapath = os.path.join(target_dir, file)
index += 1
with Image.open(filapath) as im:
try:
start_time = time.time()
results = reader.decode_buffer_manually(im.tobytes(), im.width, im.height, im.width * 3, EnumImagePixelFormat.IPF_RGB_888)
elapsed_time = time.time() - start_time
print(file + ", elapsed time: " + str(round(elapsed_time * 1000)) + "ms, " + ' results: ' + str(len(results)))
if results != None:
for result in results:
print(result.barcode_format_string + ': ' + result.barcode_text)
else:
print(' results: 0')
except Exception as err:
print(err)
if __name__ == '__main__':
main()
We can mount the current Windows folder to the Docker container and run the script in the container.
docker run --platform linux/arm64 -it --rm -v ${pwd}:/usr/src/myapp -w /usr/src/myapp <IMAGE-NAME> python pillow_test.py
docker run --platform linux/arm/v7 -it --rm -v ${pwd}:/usr/src/myapp -w /usr/src/myapp <IMAGE-NAME> python pillow_test.py
There is one more question: how does CPU affect the decoding speed? The default hardware resources can be configured in the settings.
By default, each container's access to the host machine's CPU cycles is unlimited.
Although it is impossible to change the CPU speed in Docker, we can use --cpuset-cpus to limit the number of CPU cores.
For example, we can limit the CPU cores to 2 and run the script in the container to check the performance difference.
docker run --cpuset-cpus="0,1" --platform linux/arm64 -it --rm -v ${pwd}:/usr/src/myapp -w /usr/src/myapp yushulx/dbr-arm64:1.0 python pillow_test.py
The nproc
command can be used to verify the core number:
docker run --cpuset-cpus="0,1" --platform linux/arm64 -it --rm -v ${pwd}:/usr/src/myapp -w /usr/src/myapp yushulx/dbr-arm64:1.0 nproc
2
Raspberry Pi Emulator
To make the emulated environment more realistic, we can use dockerpi to emulate different Raspberry Pi models.
docker run -it lukechilds/dockerpi pi2
pi@raspberrypi:~$ lscpu
Architecture: armv7l
Byte Order: Little Endian
CPU(s): 4
On-line CPU(s) list: 0-3
Thread(s) per core: 1
Core(s) per socket: 4
Socket(s): 1
Vendor ID: ARM
Model: 5
Model name: Cortex-A7
Stepping: r0p5
CPU max MHz: 700.0000
CPU min MHz: 700.0000
BogoMIPS: 125.00
Flags: half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm
docker run -it lukechilds/dockerpi pi3
pi@raspberrypi:~$ lscpu
Architecture: aarch64
Byte Order: Little Endian
CPU(s): 4
On-line CPU(s) list: 0-3
Thread(s) per core: 1
Core(s) per socket: 4
Socket(s): 1
Vendor ID: ARM
Model: 4
Model name: Cortex-A53
Stepping: r0p4
CPU max MHz: 700.0000
CPU min MHz: 700.0000
BogoMIPS: 125.00
Flags: fp asimd evtstrm aes pmull sha1 sha2 crc32 cpuid
Source Code
https://github.com/yushulx/docker-arm64-arm32-python-barcode-detection
Top comments (0)