/** * \brief Returns xxx * \param img * \param Scaled x coordinate * \param Scaled y coordinate * \return Scaled pixel offset */ extern unsigned char * dmtxDecodeGetCache(DmtxDecode *dec, int x, int y) { int width, height; assert(dec != NULL); /* if(dec.cacheComplete == DmtxFalse) CacheImage(); */ width = dmtxDecodeGetProp(dec, DmtxPropWidth); height = dmtxDecodeGetProp(dec, DmtxPropHeight); if(x < 0 || x >= width || y < 0 || y >= height) return NULL; return &(dec->cache[y * width + x]); }
/** * \brief Initialize scan grid pattern * \param dec * \return Initialized grid */ static DmtxScanGrid InitScanGrid(DmtxDecode *dec) { int scale, smallestFeature; int xExtent, yExtent, maxExtent; int extent; DmtxScanGrid grid; memset(&grid, 0x00, sizeof(DmtxScanGrid)); scale = dmtxDecodeGetProp(dec, DmtxPropScale); smallestFeature = dmtxDecodeGetProp(dec, DmtxPropScanGap) / scale; grid.xMin = dmtxDecodeGetProp(dec, DmtxPropXmin); grid.xMax = dmtxDecodeGetProp(dec, DmtxPropXmax); grid.yMin = dmtxDecodeGetProp(dec, DmtxPropYmin); grid.yMax = dmtxDecodeGetProp(dec, DmtxPropYmax); /* Values that get set once */ xExtent = grid.xMax - grid.xMin; yExtent = grid.yMax - grid.yMin; maxExtent = (xExtent > yExtent) ? xExtent : yExtent; assert(maxExtent > 1); for(extent = 1; extent < maxExtent; extent = ((extent + 1) * 2) - 1) if(extent <= smallestFeature) grid.minExtent = extent; grid.maxExtent = extent; grid.xOffset = (grid.xMin + grid.xMax - grid.maxExtent) / 2; grid.yOffset = (grid.yMin + grid.yMax - grid.maxExtent) / 2; /* Values that get reset for every level */ grid.total = 1; grid.extent = grid.maxExtent; SetDerivedFields(&grid); return grid; }
extern unsigned char * dmtxDecodeCreateDiagnostic(DmtxDecode *dec, int *totalBytes, int *headerBytes, int style) { int i, row, col; int width, height; int widthDigits, heightDigits; int count, channelCount; int rgb[3]; double shade; unsigned char *pnm, *output, *cache; width = dmtxDecodeGetProp(dec, DmtxPropWidth); height = dmtxDecodeGetProp(dec, DmtxPropHeight); channelCount = dmtxImageGetProp(dec->image, DmtxPropChannelCount); style = 1; /* this doesn't mean anything yet */ /* Count width digits */ for(widthDigits = 0, i = width; i > 0; i /= 10) widthDigits++; /* Count height digits */ for(heightDigits = 0, i = height; i > 0; i /= 10) heightDigits++; *headerBytes = widthDigits + heightDigits + 9; *totalBytes = *headerBytes + width * height * 3; pnm = (unsigned char *)malloc(*totalBytes); if(pnm == NULL) return NULL; #ifdef _VISUALC_ count = sprintf_s((char *)pnm, *headerBytes + 1, "P6\n%d %d\n255\n", width, height); #else //count = snprintf((char *)pnm, *headerBytes + 1, "P6\n%d %d\n255\n", width, height); count = sprintf_s((char *)pnm, *headerBytes + 1, "P6\n%d %d\n255\n", width, height); #endif if(count != *headerBytes) { free(pnm); return NULL; } output = pnm + (*headerBytes); for(row = height - 1; row >= 0; row--) { for(col = 0; col < width; col++) { cache = dmtxDecodeGetCache(dec, col, row); if(cache == NULL) { rgb[0] = 0; rgb[1] = 0; rgb[2] = 128; } else if(*cache & 0x40) { rgb[0] = 255; rgb[1] = 0; rgb[2] = 0; } else { shade = (*cache & 0x80) ? 0.0 : 0.7; for(i = 0; i < 3; i++) { if(i < channelCount) dmtxDecodeGetPixelValue(dec, col, row, i, &rgb[i]); else dmtxDecodeGetPixelValue(dec, col, row, 0, &rgb[i]); rgb[i] += (int)(shade * (double)(255 - rgb[i]) + 0.5); if(rgb[i] > 255) rgb[i] = 255; } } *(output++) = (unsigned char)rgb[0]; *(output++) = (unsigned char)rgb[1]; *(output++) = (unsigned char)rgb[2]; } } assert(output == pnm + *totalBytes); return pnm; }
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(®); } dmtxDecodeDestroy(&dec); dmtxImageDestroy(&img); return detected; }