Reading Barcode with Webcam in OpenCV and Python

Barcode is an efficient way to make information readable for machines. There are many scenarios of using Barcode reader software. For example, companies use Barcode encoding and decoding software to manage various documents that captured by office scanners. Airport security uses handheld scanners to check the boarding pass and record personal information to the database. Students use the built-in camera of the smartphone to check attendance via Barcode reader software. Since I have a Webcam connected to my desktop PC, I want to empower it to work as a Barcode reader. To implement the solution, I decide to choose OpenCV and Dynamsoft Barcode Reader SDK.


Python Webcam Barcode Reader

Installation

How to Recognize Barcode via Webcam in Python

Here are the steps:

  1. Copy <opencv_installation_dir>\build\python\2.7\x86\cv2.pyd
    to <Python27>\Lib\site-packages\cv2.pyd
  2. Create a project folder.
  3. Build Python Barcode library with Dynamsoft Barcode Reader SDK.
  4. Copy Barcode library and all dependencies to the project folder.
  5. Connect a Webcam to your PC. Make sure you have installed the Webcam driver.
  6. Create a Python script to control Webcam. Capture images from Webcam and decode images with Python Barcode library.

Creating Python Barcode Library with Dynamsoft Barcode SDK

The first step is to build the Python Barcode library yourself.

#include "Python.h"

#include "If_DBR.h"
#include "BarcodeFormat.h"
#include "BarcodeStructs.h"
#include "ErrorCode.h"

#ifdef _WIN64
#pragma comment(lib, "DBRx64.lib")
#else
#pragma comment(lib, "DBRx86.lib")
#endif

void SetOptions(pReaderOptions pOption, int option_iMaxBarcodesNumPerPage, int option_llBarcodeFormat){

	if (option_llBarcodeFormat > 0)
		pOption->llBarcodeFormat = option_llBarcodeFormat;
	else
		pOption->llBarcodeFormat = OneD;

	if (option_iMaxBarcodesNumPerPage > 0)
		pOption->iMaxBarcodesNumPerPage = option_iMaxBarcodesNumPerPage;
	else
		pOption->iMaxBarcodesNumPerPage = INT_MAX;

}

static PyObject *
initLicense(PyObject *self, PyObject *args)
{
	char *license;

	if (!PyArg_ParseTuple(args, "s", &license)) {
		return NULL;
	}

	printf("information: %s\n", license);

	int ret = DBR_InitLicense(license);

	printf("return value = %d", ret);

	return Py_None;
}

static PyObject *
decodeFile(PyObject *self, PyObject *args)
{
	char *pFileName;
	int option_iMaxBarcodesNumPerPage = -1;
	int option_llBarcodeFormat = -1;

	if (!PyArg_ParseTuple(args, "s", &pFileName)) {
		return NULL;
	}

	pBarcodeResultArray pResults = NULL;
	ReaderOptions option;
	SetOptions(&option, option_iMaxBarcodesNumPerPage, option_llBarcodeFormat);

	int ret = DBR_DecodeFile(
		pFileName,
		&option,
		&pResults
		);

	if (ret == DBR_OK){
		int count = pResults->iBarcodeCount;
		pBarcodeResult* ppBarcodes = pResults->ppBarcodes;
		pBarcodeResult tmp = NULL;

		PyObject* list = PyList_New(count);
		PyObject* result = NULL;

		for (int i = 0; i < count; i++)
		{
			tmp = ppBarcodes[i];
			result = PyString_FromString(tmp->pBarcodeData);

			PyList_SetItem(list, i, Py_BuildValue("iN", (int)tmp->llFormat, result));
		}

		// release memory
		DBR_FreeBarcodeResults(&pResults);

		return list;
	}

	return Py_None;
}

static PyMethodDef methods[] = {
	{ "initLicense", initLicense, METH_VARARGS, NULL },
	{ "decodeFile", decodeFile, METH_VARARGS, NULL },
	{ NULL, NULL }
};

PyMODINIT_FUNC
initDynamsoftBarcodeReader(void)
{
	Py_InitModule("DynamsoftBarcodeReader", methods);
}

For detailed information, please refer to the source code on GitHub. Once the library built successfully, copy DynamsoftBarcodeReader.pyd and DynamsoftBarcodeReaderx64.dll /DynamsoftBarcodeReaderx86.dll to the project folder.

Opening Webcam with OpenCV

Using OpenCV, we can show Webcam preview and capture images with a few lines of Python code.

import cv2.cv as cv

title = "Dynamsoft Barcode Reader"
cv.NamedWindow(title, 1)
capture = cv.CaptureFromCAM(0)

while True:
    img = cv.QueryFrame(capture)
    cv.ShowImage(title, img)

Reading Barcode and Drawing Results over Image

line_type = cv.CV_AA
font = cv.InitFont(cv.CV_FONT_HERSHEY_COMPLEX,
                          0.1, 1, 1, 1, line_type)
fileName = 'test.jpg'
img = cv.QueryFrame(capture)
cv.SaveImage(fileName, img)

results = DynamsoftBarcodeReader.decodeFile(fileName)
top = 30
increase = 20
if results:
    for result in results:
        barcode_format = "Format: " + formats[result[0]]
        barcode_value = "Value: " + result[1]
        cv.PutText(img, barcode_format, (10, top), font, (254, 142, 20))
        top += increase
        cv.PutText(img, barcode_value, (10, top), font, (254, 142, 20))
        top += increase
        cv.PutText(img, "************************", (10, top), font, (254, 142, 20))
        top += increase

cv.ShowImage(title, img)

Source Code

https://github.com/yushulx/webcam-barcode-reader