static PyObject * dmtx_decode(PyObject *self, PyObject *arglist, PyObject *kwargs) { int count=0; int found=0; int width; int height; int gap_size = DmtxUndefined; int max_count = DmtxUndefined; int timeout = DmtxUndefined; int shape = DmtxUndefined; int deviation = DmtxUndefined; int threshold = DmtxUndefined; int shrink = 1; int corrections = DmtxUndefined; int min_edge = DmtxUndefined; int max_edge = DmtxUndefined; PyObject *dataBuf = NULL; Py_ssize_t dataLen; PyObject *context = Py_None; PyObject *output = PyList_New(0); DmtxTime dmtx_timeout; DmtxImage *img; DmtxDecode *dec; DmtxRegion *reg; DmtxMessage *msg; DmtxVector2 p00, p10, p11, p01; const char *pxl; /* Input image buffer */ static char *kwlist[] = { "width", "height", "data", "gap_size", "max_count", "context", "timeout", "shape", "deviation", "threshold", "shrink", "corrections", "min_edge", "max_edge", NULL }; /* Parse out the options which are applicable */ PyObject *filtered_kwargs; filtered_kwargs = PyDict_New(); count = 3; /* Skip the first 3 keywords as they are sent in arglist */ while(kwlist[count]){ if(PyDict_GetItemString(kwargs, kwlist[count])) { PyDict_SetItemString(filtered_kwargs, kwlist[count], PyDict_GetItemString(kwargs, kwlist[count])); } count++; } /* Get parameters from Python for libdmtx */ if(!PyArg_ParseTupleAndKeywords(arglist, filtered_kwargs, "iiOi|iOiiiiiiii", kwlist, &width, &height, &dataBuf, &gap_size, &max_count, &context, &timeout, &shape, &deviation, &threshold, &shrink, &corrections, &min_edge, &max_edge)) { PyErr_SetString(PyExc_TypeError, "decode takes at least 3 arguments"); return NULL; } Py_INCREF(context); /* Reset timeout for each new page */ if(timeout != DmtxUndefined) dmtx_timeout = dmtxTimeAdd(dmtxTimeNow(), timeout); if(dataBuf == NULL) { PyErr_SetString(PyExc_TypeError, "Interleaved bitmapped data in buffer missing"); return NULL; } PyObject_AsCharBuffer(dataBuf, &pxl, &dataLen); img = dmtxImageCreate((unsigned char *)pxl, width, height, DmtxPack24bppRGB); if(img == NULL) return NULL; dec = dmtxDecodeCreate(img, shrink); if(dec == NULL) { dmtxImageDestroy(&img); return NULL; } if(gap_size != DmtxUndefined) dmtxDecodeSetProp(dec, DmtxPropScanGap, gap_size); if(shape != DmtxUndefined) dmtxDecodeSetProp(dec, DmtxPropSymbolSize, shape); if(deviation != DmtxUndefined) dmtxDecodeSetProp(dec, DmtxPropSquareDevn, deviation); if(threshold != DmtxUndefined) dmtxDecodeSetProp(dec, DmtxPropEdgeThresh, threshold); if(min_edge != DmtxUndefined) dmtxDecodeSetProp(dec, DmtxPropEdgeMin, min_edge); if(max_edge != DmtxUndefined) dmtxDecodeSetProp(dec, DmtxPropEdgeMax, max_edge); for(count=1; ;count++) { Py_BEGIN_ALLOW_THREADS if(timeout == DmtxUndefined) reg = dmtxRegionFindNext(dec, NULL); else reg = dmtxRegionFindNext(dec, &dmtx_timeout); Py_END_ALLOW_THREADS /* Finished file or ran out of time before finding another region */ if(reg == NULL) break; msg = dmtxDecodeMatrixRegion(dec, reg, corrections); if(msg != NULL) { p00.X = p00.Y = p10.Y = p01.X = 0.0; p10.X = p01.Y = p11.X = p11.Y = 1.0; dmtxMatrix3VMultiplyBy(&p00, reg->fit2raw); dmtxMatrix3VMultiplyBy(&p10, reg->fit2raw); dmtxMatrix3VMultiplyBy(&p11, reg->fit2raw); dmtxMatrix3VMultiplyBy(&p01, reg->fit2raw); PyList_Append(output, Py_BuildValue("s#((ii)(ii)(ii)(ii))", msg->output, msg->outputIdx, (int)((shrink * p00.X) + 0.5), height - 1 - (int)((shrink * p00.Y) + 0.5), (int)((shrink * p10.X) + 0.5), height - 1 - (int)((shrink * p10.Y) + 0.5), (int)((shrink * p11.X) + 0.5), height - 1 - (int)((shrink * p11.Y) + 0.5), (int)((shrink * p01.X) + 0.5), height - 1 - (int)((shrink * p01.Y) + 0.5))); Py_INCREF(output); dmtxMessageDestroy(&msg); found++; } dmtxRegionDestroy(®); /* Stop if we've reached maximium count */ if(max_count != DmtxUndefined) if(found >= max_count) break; } dmtxDecodeDestroy(&dec); dmtxImageDestroy(&img); Py_DECREF(context); if(output == NULL) { Py_INCREF(Py_None); return Py_None; } return output; }
bool Marker_DMTX::findPattern(const sensor_msgs::Image &img, std::vector<SMarker> &res) { int count=0; DmtxImage *dimg = dmtxImageCreate((unsigned char*)&img.data[0], img.width, img.height, DmtxPack24bppRGB); ROS_ASSERT(dimg); DmtxDecode *dec = dmtxDecodeCreate(dimg, 1); ROS_ASSERT(dec); dmtxDecodeSetProp(dec, DmtxPropEdgeThresh, 1); DmtxRegion *reg; for(count=1; ;count++) { DmtxTime timeout = dmtxTimeAdd(dmtxTimeNow(), timeout_); reg = dmtxRegionFindNext(dec, &timeout); /* Finished file or ran out of time before finding another region */ if(reg == NULL) break; if (reg != NULL) { DmtxMessage *msg = dmtxDecodeMatrixRegion(dec, reg, DmtxUndefined); if (msg != NULL) { SMarker m; m.code_ = std::string((const char*)msg->output,msg->outputSize); m.format_ = "datamatrix"; DmtxVector2 p00, p10, p11, p01; p00.X = p00.Y = p10.Y = p01.X = 0.0; p10.X = p01.Y = p11.X = p11.Y = 1.0; dmtxMatrix3VMultiplyBy(&p00, reg->fit2raw); dmtxMatrix3VMultiplyBy(&p10, reg->fit2raw); dmtxMatrix3VMultiplyBy(&p11, reg->fit2raw); dmtxMatrix3VMultiplyBy(&p01, reg->fit2raw); Eigen::Vector2i v; v(0)=(int)((p01.X) + 0.5); v(1)=img.height - 1 - (int)((p01.Y) + 0.5); m.pts_.push_back(v); v(0)=(int)((p00.X) + 0.5); v(1)=img.height - 1 - (int)((p00.Y) + 0.5); m.pts_.push_back(v); v(0)=(int)((p11.X) + 0.5); v(1)=img.height - 1 - (int)((p11.Y) + 0.5); m.pts_.push_back(v); v(0)=(int)((p10.X) + 0.5); v(1)=img.height - 1 - (int)((p10.Y) + 0.5); m.pts_.push_back(v); res.push_back(m); dmtxMessageDestroy(&msg); } dmtxRegionDestroy(®); } } dmtxDecodeDestroy(&dec); dmtxImageDestroy(&dimg); return false; }