Dynamsoft Barcode Reader C++ SDK is available for Windows, Linux, and Mac (iOS and Android editions are coming soon). I have shared an article that illustrates how to build webcam barcode reader in Python. In this tutorial, I’ll use a different C++ API to implement barcode scanner applications for Windows and Raspberry Pi with a webcam.
Prerequisites
Windows
Raspberry Pi
- How to install OpenCV on Raspbian Jessie
- Contact support@dynamsoft.com to get the SDK, which is not publicly available yet.
Getting Started with Webcam Barcode Reader
How to capture frame from webcam using OpenCV
VideoCapture cap(0); if (!cap.isOpened()) return -1; Mat frame; for (;;) { cap >> frame; // Get a new frame from camera imshow(windowName, frame); // Display the new frame if (waitKey(30) >= 0) break; }
How to initialize Dynamsoft Barcode Reader
CBarcodeReader reader; reader.InitLicense("38B9B94D8B0E2B41660D13B593BE6EF9"); __int64 llFormat = (OneD | QR_CODE | PDF417 | DATAMATRIX); int iMaxCount = 0x7FFFFFFF; ReaderOptions ro = { 0 }; ro.llBarcodeFormat = llFormat; ro.iMaxBarcodesNumPerPage = iMaxCount; reader.SetReaderOptions(ro);
How to pre-process camera frame buffer
The barcode API only takes DIB (device-independent bitmap) structure as the input data, and thus, you have to re-construct the buffer wrapped in Mat:
int elemSize = image.elemSize(); int size = image.total() * elemSize; // Get image data char *imageData = (char *)image.data; // Combine header info and image data int width = image.cols, height = image.rows; char *total = (char *)malloc(size + 40); if (!total) { printf("Failed to allocate memory"); return; } memset(total, 0, size + 40); BITMAPINFOHEADER bitmap_info = { 40, width, height, 0, 24, 0, size, 0, 0, 0, 0 }; memcpy(total, &bitmap_info, 40); char *data = total + 40; // Reverse the image buffer from bottom to top width *= 3; for (int i = 1; i <= height; i++) { memcpy(data, imageData + width * (height - i), width); data += width; }
Reading barcode image buffer on Windows
int iRet = reader.DecodeBuffer((unsigned char*)total, size + 40); char * pszTemp = (char*)malloc(4096); if (iRet != DBR_OK && iRet != DBRERR_LICENSE_EXPIRED && iRet != DBRERR_QR_LICENSE_INVALID && iRet != DBRERR_1D_LICENSE_INVALID && iRet != DBRERR_PDF417_LICENSE_INVALID && iRet != DBRERR_DATAMATRIX_LICENSE_INVALID) { sprintf(pszTemp, "Failed to read barcode: %s\r\n", DBR_GetErrorString(iRet)); printf(pszTemp); free(pszTemp); free(total); return; } pBarcodeResultArray paryResult = NULL; reader.GetBarcodes(&paryResult); if (paryResult->iBarcodeCount > 0) { for (int iIndex = 0; iIndex < paryResult->iBarcodeCount; iIndex++) { sprintf(pszTemp, "Barcode %d:\r\n", iIndex + 1); printf(pszTemp); sprintf(pszTemp, " Page: %d\r\n", paryResult->ppBarcodes[iIndex]->iPageNum); printf(pszTemp); sprintf(pszTemp, " Type: %s\r\n", GetFormatStr(paryResult->ppBarcodes[iIndex]->llFormat)); printf(pszTemp); char *pszTemp1 = (char*)malloc(paryResult->ppBarcodes[iIndex]->iBarcodeDataLength + 1); memset(pszTemp1, 0, paryResult->ppBarcodes[iIndex]->iBarcodeDataLength + 1); memcpy(pszTemp1, paryResult->ppBarcodes[iIndex]->pBarcodeData, paryResult->ppBarcodes[iIndex]->iBarcodeDataLength); sprintf(pszTemp, " Value: %s\r\n", pszTemp1); printf(pszTemp); free(pszTemp1); sprintf(pszTemp, " Region: {Left: %d, Top: %d, Width: %d, Height: %d}\r\n\r\n", paryResult->ppBarcodes[iIndex]->iLeft, paryResult->ppBarcodes[iIndex]->iTop, paryResult->ppBarcodes[iIndex]->iWidth, paryResult->ppBarcodes[iIndex]->iHeight); printf(pszTemp); } } free(pszTemp); reader.FreeBarcodeResults(&paryResult); free(total);
Reading barcode image buffer on Linux
Porting the source code from Windows to Linux is a little bit tricky because DIB structure is not defined on Linux platform. We can define it ourselves:
typedef unsigned long DWORD; typedef long LONG; typedef unsigned short WORD; typedef struct tagBITMAPINFOHEADER { DWORD biSize; LONG biWidth; LONG biHeight; WORD biPlanes; WORD biBitCount; DWORD biCompression; DWORD biSizeImage; LONG biXPelsPerMeter; LONG biYPelsPerMeter; DWORD biClrUsed; DWORD biClrImportant; } BITMAPINFOHEADER;
Build the source code:
g++ -ggdb -I$(DynamsoftBarcodeReader)/include -o barcodereader barcodereader.cpp -lDynamsoftBarcodeReader `pkg-config --libs opencv`
Source Code
https://github.com/dynamsoftlabs/cplusplus-webcam-barcode-reader
The post Real-time Webcam Barcode Detection with OpenCV and C++ appeared first on Code Pool.