本文档仅记录自己使用libdmtx这个库过程中的总结。
1. 基础使用
DmtxMessage* msg;
DmtxRegion* reg;
if (!src.data)
cout << "Load image failed!" << endl;
DmtxImage* img;
img = dmtxImageCreate(src.data, src.cols, src.rows, DmtxPack8bppK);
DmtxDecode* dec = dmtxDecodeCreate(img, 1);
reg = dmtxRegionFindNext(dec, NULL);
if (reg != NULL) {
msg = dmtxDecodeMatrixRegion(dec, reg, DmtxUndefined);
if (msg != NULL) {
cout << msg->output << endl;
dmtxMessageDestroy(&msg);
}
else
cout<<"Not valid data type."<<endl;
dmtxRegionDestroy(®);
}
else
cout << "Cannot find codes..." << endl;
dmtxDecodeDestroy(&dec);
dmtxImageDestroy(&img);
注明:首先创建dmtx类型的图像,再创建decode的方式(缩写dec),在根据dec方式寻找区域region(reg),如果能够找到区域,再在区域内根据dec方式进行解码。
2. 设置属性
在某些情况下,dm码一些性质是已知的,可以通过设置避免误判,同时提高检测速度:
在dmtxdecod.c文件源码中,发现:
dmtxDecodeCreate时,默认进行了如下设定:
dec->fnc1 = DmtxUndefined;
dec->edgeMin = DmtxUndefined;
dec->edgeMax = DmtxUndefined;
dec->scanGap = 1;
dec->squareDevn = cos(50 * (M_PI/180));
dec->sizeIdxExpected = DmtxSymbolShapeAuto;
dec->edgeThresh = 10;
dec->xMin = 0;
dec->xMax = width - 1;
dec->yMin = 0;
dec->yMax = height - 1;
dec->scale = scale;
dec->cache = (unsigned char *)calloc(width * height, sizeof(unsigned char));
if(dec->cache == NULL) {
free(dec);
return NULL;
}
dec->image = img;
dec->grid = InitScanGrid(dec);
可以发现,将edge最大最小,扫描间隔,dm码尺寸,起止位置等均设置为了一些默认值。
设置之后,设定了scan时网格的初始化dec->grid方式。
可以通过设置相关属性。利用:dmtxDecodeSetProp函数。函数原型如下:
extern DmtxPassFail
dmtxDecodeSetProp(DmtxDecode *dec, int prop, int value)
{
switch(prop) {
case DmtxPropEdgeMin:
dec->edgeMin = value;
break;
case DmtxPropEdgeMax:
dec->edgeMax = value;
break;
case DmtxPropScanGap:
dec->scanGap = value; /* XXX Should this be scaled? */
break;
case DmtxPropFnc1:
dec->fnc1 = value;
break;
case DmtxPropSquareDevn:
dec->squareDevn = cos(value * (M_PI/180.0));
break;
case DmtxPropSymbolSize:
dec->sizeIdxExpected = value;
break;
case DmtxPropEdgeThresh:
dec->edgeThresh = value;
break;
/* Min and Max values arrive unscaled */
case DmtxPropXmin:
dec->xMin = value / dec->scale;
break;
case DmtxPropXmax:
dec->xMax = value / dec->scale;
break;
case DmtxPropYmin:
dec->yMin = value / dec->scale;
break;
case DmtxPropYmax:
dec->yMax = value / dec->scale;
break;
default:
break;
}
if(dec->squareDevn <= 0.0 || dec->squareDevn >= 1.0)
return DmtxFail;
if(dec->scanGap < 1)
return DmtxFail;
if(dec->edgeThresh < 1 || dec->edgeThresh > 100)
return DmtxFail;
/* Reinitialize scangrid in case any inputs changed */
dec->grid = InitScanGrid(dec);
return DmtxPass;
}
可以看出,当指定某一属性时,将相关编码器的属性进行了修改,并重新init网格。
一些属性推测:
dec->edgeMin:最小间隔,指一个dm码尺寸,而不是一个小像素的大小
dec->squareDevn:(推测)为倾斜程度
dec->sizeIdxExpected :
dm码尺寸,设定后在后续扫描时会比较当前尺寸与更大一号的尺寸哪个更为合适,
在解码时会按照更合适的尺寸进行解码;若未设置,则全部尺寸过一遍。
所以针对这些情况,可以在初始化之后进行如下设置:
DmtxDecode* dec = dmtxDecodeCreate(img, 1);
dmtxDecodeSetProp(dec, DmtxPropEdgeMin, 120);
dmtxDecodeSetProp(dec, DmtxPropEdgeMax, 150);
dmtxDecodeSetProp(dec, DmtxPropSquareDevn, 5);
dmtxDecodeSetProp(dec, DmtxPropSymbolSize, DmtxSymbol12x12);
reg = dmtxRegionFindNext(dec, NULL);