How to Annotate Barcode Object with LabelImg for Machine Learning
Tags: machinelearning, python, programming, webdev
Published: 2023-09-26 07:17:52

LabelImg is a Python and Qt5-based image annotation tool that's both free and open-source. It's compatible with popular machine learning frameworks like Pascal VOC and Yolo formats. If you're keen on barcode object detection, you can employ this tool to annotate various barcode symbologies using bounding boxes. In this article, I'll demonstrate how to efficiently acquire multiple barcode images from Google and leverage the [Dynamsoft Barcode Reader SDK](https://www.dynamsoft.com/barcode-reader/overview/) to automate the process of assigning label names. 

## Image Download
 
To begin, we require images. _How can we obtain a collection of images categorized under the same classification?_ Fortunately, there's a handy Python library known as "google_images_download" for this purpose. 

`pip install google_images_download` 

While utilizing the library, I encountered an issue where it consistently failed to download images, rendering it non-functional. This problem has been discussed on https://github.com/hardikvasa/google-images-download/issues/331. Fortunately, a helpful workaround has been offered. We can opt for a forked repository that has successfully addressed the issue: 

git clone https://github.com/Joeclinton1/google-images-download.git 

`cd google-images-download && python setup.py install` 

A straightforward Python script can be employed to retrieve images, as demonstrated below: 

```
from google_images_download import google_images_download   
import argparse 

 
ap = argparse.ArgumentParser() 
ap.add_argument("-k", "--keywords", required=True, 
    help="The keywords/key phrases you want to search for.") 
ap.add_argument("-l", "--limit", required=True, 
    help="The number of images that you want to download.") 
args = vars(ap.parse_args()) 

response = google_images_download.googleimagesdownload() 
arguments = {"keywords":args\["keywords"\],"limit":args\["limit"\],"print_urls":True}   
paths = response.download(arguments) 
print(paths)  
```
Save the Python script as "`google-image-downloader.py.`" Now, let's proceed to download ten PDF417 images from Google: 

`python3 google-image-downloader.py -k pdf417 -l 10 `

 

## Barcode Object Annotation
 
With the barcode images prepared, we can commence the process of labelling them. Our initial step involves obtaining the source code from the LabelImg repository: 

`git clone https://github.com/tzutalin/labelImg.git `

LabelImg enables us to manually label various objects visually, but when it comes to less familiar barcode symbologies, this method may not be optimal. To efficiently and accurately name barcode objects, we can employ Dynamsoft Barcode Reader as a supplementary tool: 

`pip install dbr` 

Setting up Dynamsoft Barcode Reader is a straightforward process: 

`from dbr import * 
reader = BarcodeReader() `

Navigate to the "`newShape(self)`" function within `labelImg.py`. This function is invoked upon completing the drawing of a bounding box for an object. Subsequently, our next task is to retrieve the coordinates from the current shape, which is stored as the last element within a shape array in the canvas: 

`shape = self.canvas.shapes[-1]` 

Each shape consists of four points. To obtain the coordinate values and define the region values for Dynamsoft Barcode Reader, we focus on the top-left point and the bottom-right point: 

```
reader.reset_runtime_settings() 
shape = self.canvas.shapes[-1] 
points = shape.points 
settings = reader.get_runtime_settings() 
settings.region_bottom  = round(points[2].y()) 
settings.region_left    = round(points[0].x()) 
settings.region_right   = round(points[2].x()) 
settings.region_top     = round(points[0].y()) 
reader.update_runtime_settings(settings) 
```
Following this, we can access the barcode information within the specified region by calling the Python barcode decoding API: 

```
try: 

  text_results = reader.decode_file(self.filePath) 

    if text_results != None: 

      for text_result in text_results: 

          print("Barcode Format :") 

          print(text_result.barcode_format_string) 

          self.prevLabelText = text_result.barcode_format_string 

          print("Barcode Text :") 

          print(text_result.barcode_text) 

          print("Localization Points : ") 

          print(text_result.localization_result.localization_points) 

          print("-------------") 

except BarcodeReaderError as bre: 

    print(bre) 
```
Save the labelImg.py file and execute the program: 

`python3 labelImg.py `

When you draw a rectangular box around a barcode object, it will automatically populate the label dialog with the relevant [barcode type](https://www.dynamsoft.com/barcode-reader/barcode-types/). 

![labelimg barcode annotation](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xiwxkx6o9mcswdvo5zdq.png)