예제 #1
0
/**
 * \brief  Convert fitted Data Matrix region into a decoded message
 * \param  dec
 * \param  reg
 * \param  fix
 * \return Decoded message
 */
extern DmtxMessage *
dmtxDecodeMatrixRegion(DmtxDecode *dec, DmtxRegion *reg, int fix)
{
   DmtxMessage *msg;
   DmtxVector2 topLeft, topRight, bottomLeft, bottomRight;
   DmtxPixelLoc pxTopLeft, pxTopRight, pxBottomLeft, pxBottomRight;

   msg = dmtxMessageCreate(reg->sizeIdx, DmtxFormatMatrix);
   if(msg == NULL)
      return NULL;

   if(PopulateArrayFromMatrix(dec, reg, msg) != DmtxPass) {
      dmtxMessageDestroy(&msg);
      return NULL;
   }

   /* maybe place remaining logic into new dmtxDecodePopulatedArray()
      function so other people can pass in their own arrays */

   ModulePlacementEcc200(msg->array, msg->code,
         reg->sizeIdx, DmtxModuleOnRed | DmtxModuleOnGreen | DmtxModuleOnBlue);

   if(RsDecode(msg->code, reg->sizeIdx, fix) == DmtxFail)
   {
      dmtxMessageDestroy(&msg);
      return NULL;
   }

   topLeft.X = bottomLeft.X = topLeft.Y = topRight.Y = -0.1;
   topRight.X = bottomRight.X = bottomLeft.Y = bottomRight.Y = 1.1;

   dmtxMatrix3VMultiplyBy(&topLeft, reg->fit2raw);
   dmtxMatrix3VMultiplyBy(&topRight, reg->fit2raw);
   dmtxMatrix3VMultiplyBy(&bottomLeft, reg->fit2raw);
   dmtxMatrix3VMultiplyBy(&bottomRight, reg->fit2raw);

   pxTopLeft.X = (int)(0.5 + topLeft.X);
   pxTopLeft.Y = (int)(0.5 + topLeft.Y);
   pxBottomLeft.X = (int)(0.5 + bottomLeft.X);
   pxBottomLeft.Y = (int)(0.5 + bottomLeft.Y);
   pxTopRight.X = (int)(0.5 + topRight.X);
   pxTopRight.Y = (int)(0.5 + topRight.Y);
   pxBottomRight.X = (int)(0.5 + bottomRight.X);
   pxBottomRight.Y = (int)(0.5 + bottomRight.Y);

   CacheFillQuad(dec, pxTopLeft, pxTopRight, pxBottomRight, pxBottomLeft);

   DecodeDataStream(msg, reg->sizeIdx, NULL);

   return msg;
}
예제 #2
0
/**
 * @brief  Allocate memory for message
 * @param  sizeIdx
 * @param  symbolFormat DmtxFormatMatrix | DmtxFormatMosaic
 * @return Address of allocated memory
 */
extern DmtxMessage *
dmtxMessageCreate(int sizeIdx, int symbolFormat)
{
   DmtxMessage *message;
   int mappingRows, mappingCols;

   assert(symbolFormat == DmtxFormatMatrix || symbolFormat == DmtxFormatMosaic);

   mappingRows = dmtxGetSymbolAttribute(DmtxSymAttribMappingMatrixRows, sizeIdx);
   mappingCols = dmtxGetSymbolAttribute(DmtxSymAttribMappingMatrixCols, sizeIdx);

   message = (DmtxMessage *)calloc(1, sizeof(DmtxMessage));
   if(message == NULL)
      return NULL;

   message->arraySize = sizeof(unsigned char) * mappingRows * mappingCols;

   message->array = (unsigned char *)calloc(1, message->arraySize);
   if(message->array == NULL) {
      perror("Calloc failed");
      dmtxMessageDestroy(&message);
      return NULL;
   }

   message->codeSize = sizeof(unsigned char) *
         dmtxGetSymbolAttribute(DmtxSymAttribSymbolDataWords, sizeIdx) +
         dmtxGetSymbolAttribute(DmtxSymAttribSymbolErrorWords, sizeIdx);

   if(symbolFormat == DmtxFormatMosaic)
      message->codeSize *= 3;

   message->code = (unsigned char *)calloc(message->codeSize, sizeof(unsigned char));
   if(message->code == NULL) {
      perror("Calloc failed");
      dmtxMessageDestroy(&message);
      return NULL;
   }

   /* XXX not sure if this is the right place or even the right approach.
      Trying to allocate memory for the decoded data stream and will
      initially assume that decoded data will not be larger than 2x encoded data */
   message->outputSize = sizeof(unsigned char) * message->codeSize * 10;
   message->output = (unsigned char *)calloc(message->outputSize, sizeof(unsigned char));
   if(message->output == NULL) {
      perror("Calloc failed");
      dmtxMessageDestroy(&message);
      return NULL;
   }

   return message;
}
예제 #3
0
/**
 * \brief  Convert fitted Data Mosaic region into a decoded message
 * \param  dec
 * \param  reg
 * \param  fix
 * \return Decoded message
 */
extern DmtxMessage *
dmtxDecodeMosaicRegion(DmtxDecode *dec, DmtxRegion *reg, int fix)
{
   int offset;
   int colorPlane;
   DmtxMessage *oMsg, *rMsg, *gMsg, *bMsg;

   colorPlane = reg->flowBegin.plane;

   /**
    * Consider performing a color cube fit here to identify exact RGB of
    * all 6 "cube-like" corners based on pixels located within region. Then
    * force each sample pixel to the "cube-like" corner based o which one
    * is nearest "sqrt(dr^2+dg^2+db^2)" (except sqrt is unnecessary).
    * colorPlane = reg->flowBegin.plane;
    *
    * To find RGB values of primary colors, perform something like a
    * histogram except instead of going from black to color N, go from
    * (127,127,127) to color. Use color bins along with distance to
    * identify value. An additional method will be required to get actual
    * RGB instead of just a plane in 3D. */

   reg->flowBegin.plane = 0; /* kind of a hack */
   rMsg = dmtxDecodeMatrixRegion(dec, reg, fix);

   reg->flowBegin.plane = 1; /* kind of a hack */
   gMsg = dmtxDecodeMatrixRegion(dec, reg, fix);

   reg->flowBegin.plane = 2; /* kind of a hack */
   bMsg = dmtxDecodeMatrixRegion(dec, reg, fix);

   reg->flowBegin.plane = colorPlane;

   oMsg = dmtxMessageCreate(reg->sizeIdx, DmtxFormatMosaic);

   if(oMsg == NULL || rMsg == NULL || gMsg == NULL || bMsg == NULL) {
      dmtxMessageDestroy(&oMsg);
      dmtxMessageDestroy(&rMsg);
      dmtxMessageDestroy(&gMsg);
      dmtxMessageDestroy(&bMsg);
      return NULL;
   }

   offset = 0;
   memcpy(oMsg->output + offset, rMsg->output, rMsg->outputIdx);
   offset += rMsg->outputIdx;
   memcpy(oMsg->output + offset, gMsg->output, gMsg->outputIdx);
   offset += gMsg->outputIdx;
   memcpy(oMsg->output + offset, bMsg->output, bMsg->outputIdx);
   offset += bMsg->outputIdx;

   oMsg->outputIdx = offset;

   dmtxMessageDestroy(&rMsg);
   dmtxMessageDestroy(&gMsg);
   dmtxMessageDestroy(&bMsg);

   return oMsg;
}
예제 #4
0
파일: Rdmtx.c 프로젝트: srijan/ruby-dmtx
static VALUE rdmtx_decode(VALUE self, VALUE image /* Image from RMagick (Magick::Image) */, VALUE timeout /* Timeout in msec */) {

    VALUE rawImageString = rb_funcall(image, rb_intern("export_pixels_to_str"), 0);

    VALUE safeImageString = StringValue(rawImageString);

    char * imageBuffer = RSTRING_PTR(safeImageString);

    int width = NUM2INT(rb_funcall(image, rb_intern("columns"), 0));
    int height = NUM2INT(rb_funcall(image, rb_intern("rows"), 0));

    DmtxImage *dmtxImage = dmtxImageCreate((unsigned char *)imageBuffer, width,
          height, DmtxPack24bppRGB);

    VALUE results = rb_ary_new();

    /* Initialize decode struct for newly loaded image */
    DmtxDecode * decode = dmtxDecodeCreate(dmtxImage, 1);

    DmtxRegion * region;
    DmtxMessage * message;

    int intTimeout = NUM2INT(timeout);
    DmtxTime dmtxTimeout = dmtxTimeAdd(dmtxTimeNow(), intTimeout);

    for(;;) {
        if (intTimeout == 0) {
            region = dmtxRegionFindNext(decode, NULL);
        } else {
            region = dmtxRegionFindNext(decode, &dmtxTimeout);
        }

        if (region == NULL )
            break;

        message = dmtxDecodeMatrixRegion(decode, region, DmtxUndefined);
        if (message != NULL) {
            VALUE outputString = rb_str_new2((char *)message->output);
            rb_ary_push(results, outputString);
            dmtxMessageDestroy(&message);
        }

        dmtxRegionDestroy(&region);
    }

    dmtxDecodeDestroy(&decode);
    dmtxImageDestroy(&dmtxImage);

    return results;
}
예제 #5
0
파일: dmtxencode.c 프로젝트: dmtx/libdmtx
/**
 * \brief  Deinitialize encode struct
 * \param  enc
 * \return void
 */
extern DmtxPassFail
dmtxEncodeDestroy(DmtxEncode **enc)
{
   if(enc == NULL || *enc == NULL)
      return DmtxFail;

   /* Free pixel array allocated in dmtxEncodeDataMatrix() */
   if((*enc)->image != NULL && (*enc)->image->pxl != NULL) {
      free((*enc)->image->pxl);
      (*enc)->image->pxl = NULL;
   }

   dmtxImageDestroy(&((*enc)->image));
   dmtxMessageDestroy(&((*enc)->message));

   free(*enc);

   *enc = NULL;

   return DmtxPass;
}
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;
}
/**
 * Decode the image, returning tags found (as DMTXTag objects)
 */
JNIEXPORT jobjectArray JNICALL
Java_org_libdmtx_DMTXImage_getTags(JNIEnv *aEnv, jobject aImage,
      jint aTagCount, jint lSearchTimeout)
{
   jclass        lImageClass, lTagClass, lPointClass;
   jmethodID     lTagConstructor, lPointConstructor;
   jfieldID      lWidth, lHeight, lData;
   DmtxImage    *lImage;
   DmtxDecode   *lDecode;
   DmtxRegion   *lRegion;
   DmtxTime      lTimeout;
   int           lW, lH, lI;
   jintArray     lJavaData;
   jint         *lPixels;
   jobject      *lTags;
   jobjectArray  lResult;
   int           lTagCount = 0;

   /* Find DMTXImage class */
   lImageClass = (*aEnv)->FindClass(aEnv, "org/libdmtx/DMTXImage");
   if(lImageClass == NULL)
      return NULL;

   /* Find Tag class */
   lTagClass = (*aEnv)->FindClass(aEnv, "org/libdmtx/DMTXTag");
   if(lTagClass == NULL)
      return NULL;

   /* Find Point class */
   lPointClass = (*aEnv)->FindClass(aEnv, "java/awt/Point");
   if(lPointClass == NULL)
      return NULL;

   /* Find constructors */
   lTagConstructor = (*aEnv)->GetMethodID(
      aEnv, lTagClass, "<init>",
      "(Ljava/lang/String;Ljava/awt/Point;Ljava/awt/Point;Ljava/awt/Point;Ljava/awt/Point;)V"
   );

   lPointConstructor = (*aEnv)->GetMethodID(aEnv, lPointClass, "<init>", "(II)V");
   if(lTagConstructor == NULL || lPointConstructor == NULL)
      return NULL;

   /* Find fields */
   lWidth = (*aEnv)->GetFieldID(aEnv, lImageClass, "width", "I");
   lHeight = (*aEnv)->GetFieldID(aEnv, lImageClass, "height", "I");
   lData = (*aEnv)->GetFieldID(aEnv, lImageClass, "data", "[I");

   if(lWidth == NULL || lHeight == NULL || lData == NULL)
      return NULL;

   /* Get fields */
   lW = (*aEnv)->GetIntField(aEnv, aImage, lWidth);
   lH = (*aEnv)->GetIntField(aEnv, aImage, lHeight);

   lJavaData = (*aEnv)->GetObjectField(aEnv, aImage, lData);
   lPixels = (*aEnv)->GetIntArrayElements(aEnv, lJavaData, NULL);

   /* Create DmtxImage object */
   lImage = dmtxImageCreate((unsigned char *)lPixels, lW, lH, DmtxPack32bppRGBX);
   if(lImage == NULL)
      return NULL;

   /* Create DmtxDecode object */
   lDecode = dmtxDecodeCreate(lImage, 1);
   if(lDecode == NULL)
      return NULL;

   /* Allocate temporary Tag array */
   lTags = (jobject *)malloc(aTagCount * sizeof(jobject));
   if(lTags == NULL)
      return NULL;

   /* Find all tags that we can inside timeout */
   lTimeout = dmtxTimeAdd(dmtxTimeNow(), lSearchTimeout);

   while(lTagCount < aTagCount && (lRegion = dmtxRegionFindNext(lDecode, &lTimeout))) {
      jstring sStringID;
      DmtxMessage *lMessage = dmtxDecodeMatrixRegion(lDecode, lRegion, DmtxUndefined);

      if(lMessage != NULL) {
         DmtxVector2 lCorner1, lCorner2, lCorner3, lCorner4;
         jobject lJCorner1, lJCorner2, lJCorner3, lJCorner4;

         /* Calculate position of Tag */
         lCorner1.X = lCorner1.Y = lCorner2.Y = lCorner4.X = 0.0;
         lCorner2.X = lCorner4.Y = lCorner3.X = lCorner3.Y = 1.0;

         dmtxMatrix3VMultiplyBy(&lCorner1, lRegion->fit2raw);
         dmtxMatrix3VMultiplyBy(&lCorner2, lRegion->fit2raw);
         dmtxMatrix3VMultiplyBy(&lCorner3, lRegion->fit2raw);
         dmtxMatrix3VMultiplyBy(&lCorner4, lRegion->fit2raw);

         /* Create Location instances for corners */
         lJCorner1 = (*aEnv)->NewObject(aEnv, lPointClass, lPointConstructor,
               (int) lCorner1.X, (int) (lH - lCorner1.Y - 1));

         lJCorner2 = (*aEnv)->NewObject(aEnv, lPointClass, lPointConstructor,
               (int) lCorner2.X, (int) (lH - lCorner2.Y - 1));

         lJCorner3 = (*aEnv)->NewObject(aEnv, lPointClass, lPointConstructor,
               (int) lCorner3.X, (int) (lH - lCorner3.Y - 1));

         lJCorner4 = (*aEnv)->NewObject(aEnv, lPointClass, lPointConstructor,
               (int) lCorner4.X, (int) (lH - lCorner4.Y - 1));

         /* Decode Message */
         sStringID = (*aEnv)->NewStringUTF(aEnv, lMessage->output);

         /* Create Tag instance */
         lTags[lTagCount] = (*aEnv)->NewObject(aEnv, lTagClass, lTagConstructor,
               sStringID, lJCorner1, lJCorner2, lJCorner3, lJCorner4);
         if(lTags[lTagCount] == NULL)
            return NULL;

         /* Increment Count */
         lTagCount++;

         /* Free Message */
         dmtxMessageDestroy(&lMessage);
      }

      /* Free Region */
      dmtxRegionDestroy(&lRegion);
   }

   /* Free DMTX Structures */
   dmtxDecodeDestroy(&lDecode);
   dmtxImageDestroy(&lImage);

   /* Release Image Data */
   (*aEnv)->ReleaseIntArrayElements(aEnv, lJavaData, lPixels, 0);

   /* Create result array */
   lResult = (*aEnv)->NewObjectArray(aEnv, lTagCount, lTagClass, NULL);

   for(lI = 0; lI < lTagCount; lI++) {
      (*aEnv)->SetObjectArrayElement(aEnv, lResult, lI, lTags[lI]);
   }

   /* Free local references */
   (*aEnv)->DeleteLocalRef(aEnv, lJavaData);
   (*aEnv)->DeleteLocalRef(aEnv, lImageClass);
   (*aEnv)->DeleteLocalRef(aEnv, lTagClass);
   (*aEnv)->DeleteLocalRef(aEnv, lPointClass);

   return lResult;
}
예제 #8
0
  bool Detector::detect(cv::Mat& image, int timeout, unsigned int offsetx, unsigned int offsety){
    bool detected = false;
    lines_.clear();
    message_.clear();
    polygon_.clear();
    DmtxRegion     *reg;
    DmtxDecode     *dec;
    DmtxImage      *img;
    DmtxMessage    *msg;
    DmtxTime       t;

    img = dmtxImageCreate(image.data, image.cols, image.rows, DmtxPack24bppRGB);
    //dmtxImageSetProp(img, DmtxPropImageFlip, DmtxFlipY);

    dec = dmtxDecodeCreate(img, 1);
    assert(dec != NULL);

    t = dmtxTimeAdd(dmtxTimeNow(), timeout);
    reg = dmtxRegionFindNext(dec, &t);

    if(reg != NULL) {

      int height;
      int dataWordLength;
      int rotateInt;
      double rotate;
      DmtxVector2 p00, p10, p11, p01;

      height = dmtxDecodeGetProp(dec, DmtxPropHeight);

      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);
      polygon_.push_back(cv::Point(p00.X + offsetx,image.rows-p00.Y + offsety));
      polygon_.push_back(cv::Point(p10.X + offsetx,image.rows-p10.Y + offsety));
      polygon_.push_back(cv::Point(p11.X + offsetx,image.rows-p11.Y + offsety));
      polygon_.push_back(cv::Point(p01.X + offsetx,image.rows-p01.Y + offsety));

      lines_.push_back(
                       std::pair<cv::Point,cv::Point>(
                                                      cv::Point(p00.X + offsetx,image.rows-p00.Y + offsety),
                                                      cv::Point(p10.X + offsetx,image.rows-p10.Y + offsety)
                                                      )
                       );
      lines_.push_back(
                             std::pair<cv::Point,cv::Point>(
                                                            cv::Point(p10.X + offsetx,image.rows-p10.Y + offsety),
                                                            cv::Point(p11.X + offsetx,image.rows-p11.Y + offsety)
                                                            )
                             );
      lines_.push_back(
                             std::pair<cv::Point,cv::Point>(
                                                            cv::Point(p11.X + offsetx,image.rows-p11.Y + offsety),
                                                            cv::Point(p01.X + offsetx,image.rows-p01.Y + offsety)
                                                            )
                             );
      lines_.push_back(
                             std::pair<cv::Point,cv::Point>(
                                                            cv::Point(p01.X + offsetx,image.rows-p01.Y + offsety),
                                                            cv::Point(p00.X + offsetx,image.rows-p00.Y + offsety)
                                                            )
                             );
      detected = true;
      msg = dmtxDecodeMatrixRegion(dec, reg, DmtxUndefined);
      if(msg != NULL) {
        message_ = (const char*)msg->output;
        dmtxMessageDestroy(&msg);
      }
      dmtxRegionDestroy(&reg);
    }
      
    dmtxDecodeDestroy(&dec);
    dmtxImageDestroy(&img);
    return detected;
  }
예제 #9
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;
}