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(&reg);

      /* 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;
}
Ejemplo n.º 2
0
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(&reg);
    }
  }

  dmtxDecodeDestroy(&dec);
  dmtxImageDestroy(&dimg);

  return false;
}