虽然手机上Barcode应用已经非常流行,但是工作的时候还是用Webcam比较方便。比如需要检测Barcode,我只需要拿Webcam对着电脑屏幕或者纸张扫一下就可以了。今天分享下如何轻松使用OpenCV控制Webcam,以及如何获取一帧图像做Barcode检测。
翻译:yushulx
软件安装
Dynamsoft Barcode SDK: http://www.dynamsoft.com/Downloads/Dynamic-Barcode-Reader-Download.aspx
Python: https://www.python.org/ftp/python/
NumPy: http://sourceforge.net/projects/numpy/files/NumPy/
SciPy: http://sourceforge.net/projects/scipy/files/scipy/
OpenCV: http://sourceforge.net/projects/opencvlibrary/files/opencv-win/
控制Webcam,读取Barcode
基本步骤:
拷贝\build\python\2.7\x86\cv2.pyd到 \Lib\site-packages\cv2.pyd。
创建一个工程目录。
构建Python Barcode动态链接库。
拷贝所有依赖的动态链接库到工程目录。
把Webcam连接到PC上。
创建Python脚本控制Webcam,捕捉Webcam图像,并使用Python Barcode库来读取图像中的Barcode。
使用Dynamsoft Barcode SDK创建Python Barcode动态链接库
编译Python Barcode动态链接库。
#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);
}
具体请参考GitHub上的源码。编译成功之后请记得拷贝DynamsoftBarcodeReader.pyd和DynamsoftBarcodeReaderx64.dll /DynamsoftBarcodeReaderx86.dll到工程目录中。
使用OpenCV打开Webcam
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)
使用OpenCV绘制显示结果
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)
源码