📄 dmtxregion.c
字号:
angleBest = 0; hOffset = hOffsetBest = 0; follow = FollowSeekLoc(dec, loc0); rHp = line.locBeg = line.locPos = line.locNeg = follow.loc; line.stepBeg = line.stepPos = line.stepNeg = 0; /* Predetermine which angles to test */ for(i = 0; i < DMTX_HOUGH_RES; i++) { if(houghAvoid == -1) { houghTest[i] = 1; } else { houghMin = (houghAvoid + DMTX_HOUGH_RES/6) % DMTX_HOUGH_RES; houghMax = (houghAvoid - DMTX_HOUGH_RES/6 + DMTX_HOUGH_RES) % DMTX_HOUGH_RES; if(houghMin > houghMax) houghTest[i] = (i > houghMin || i < houghMax) ? 1 : 0; else houghTest[i] = (i > houghMin && i < houghMax) ? 1 : 0; } } /* Test each angle for steps along path */ for(step = 0; step < tripSteps; step++) { xDiff = follow.loc.X - rHp.X; yDiff = follow.loc.Y - rHp.Y; /* Increment Hough accumulator */ for(i = 0; i < DMTX_HOUGH_RES; i++) { if((int)houghTest[i] == 0) continue; dH = (rHvX[i] * yDiff) - (rHvY[i] * xDiff); if(dH >= -384 && dH <= 384) { if(dH > 128) hOffset = 2; else if(dH >= -128) hOffset = 1; else hOffset = 0; hough[hOffset][i]++; /* New angle takes over lead */ if(hough[hOffset][i] > hough[hOffsetBest][angleBest]) { angleBest = i; hOffsetBest = hOffset; } } }/* CALLBACK_POINT_PLOT(follow.loc, (sign > 1) ? 4 : 3, 1, DMTX_DISPLAY_POINT); */ follow = FollowStep2(dec, reg, follow, sign); } line.angle = angleBest; line.hOffset = hOffsetBest; line.mag = hough[hOffsetBest][angleBest]; return line;}/** * * */static intFindTravelLimits(DmtxDecode *dec, DmtxRegion *reg, DmtxBestLine *line){ int i; int distSq, distSqMax; int xDiff, yDiff; int posRunning, negRunning; int posTravel, negTravel; int posWander, posWanderMin, posWanderMax, posWanderMinLock, posWanderMaxLock; int negWander, negWanderMin, negWanderMax, negWanderMinLock, negWanderMaxLock; int cosAngle, sinAngle; DmtxFollow followPos, followNeg; DmtxPixelLoc loc0, posMax, negMax; /* line->stepBeg is already known to sit on the best Hough line */ followPos = followNeg = FollowSeek(dec, reg, line->stepBeg); loc0 = followPos.loc; cosAngle = rHvX[line->angle]; sinAngle = rHvY[line->angle]; distSqMax = 0; posMax = negMax = followPos.loc; posTravel = negTravel = 0; posWander = posWanderMin = posWanderMax = posWanderMinLock = posWanderMaxLock = 0; negWander = negWanderMin = negWanderMax = negWanderMinLock = negWanderMaxLock = 0; for(i = 0; i < reg->stepsTotal/2; i++) { posRunning = (int)(i < 10 || abs(posWander) < abs(posTravel)); negRunning = (int)(i < 10 || abs(negWander) < abs(negTravel)); if(posRunning != 0) { xDiff = followPos.loc.X - loc0.X; yDiff = followPos.loc.Y - loc0.Y; posTravel = (cosAngle * xDiff) + (sinAngle * yDiff); posWander = (cosAngle * yDiff) - (sinAngle * xDiff); if(posWander >= -3*256 && posWander <= 3*256) { distSq = DistanceSquared(followPos.loc, negMax); if(distSq > distSqMax) { posMax = followPos.loc; distSqMax = distSq; line->stepPos = followPos.step; line->locPos = followPos.loc; posWanderMinLock = posWanderMin; posWanderMaxLock = posWanderMax; } } else { posWanderMin = min(posWanderMin, posWander); posWanderMax = max(posWanderMax, posWander); } } else if(!negRunning) { break; } if(negRunning != 0) { xDiff = followNeg.loc.X - loc0.X; yDiff = followNeg.loc.Y - loc0.Y; negTravel = (cosAngle * xDiff) + (sinAngle * yDiff); negWander = (cosAngle * yDiff) - (sinAngle * xDiff); if(negWander >= -3*256 && negWander < 3*256) { distSq = DistanceSquared(followNeg.loc, posMax); if(distSq > distSqMax) { negMax = followNeg.loc; distSqMax = distSq; line->stepNeg = followNeg.step; line->locNeg = followNeg.loc; negWanderMinLock = negWanderMin; negWanderMaxLock = negWanderMax; } } else { negWanderMin = min(negWanderMin, negWander); negWanderMax = max(negWanderMax, negWander); } } else if(!posRunning) { break; }/* CALLBACK_POINT_PLOT(followPos.loc, 2, 1, DMTX_DISPLAY_POINT); CALLBACK_POINT_PLOT(followNeg.loc, 4, 1, DMTX_DISPLAY_POINT); */ followPos = FollowStep(dec, reg, followPos, +1); followNeg = FollowStep(dec, reg, followNeg, -1); } line->devn = max(posWanderMaxLock - posWanderMinLock, negWanderMaxLock - negWanderMinLock)/256; line->distSq = distSqMax;/* CALLBACK_POINT_PLOT(posMax, 2, 1, DMTX_DISPLAY_SQUARE); CALLBACK_POINT_PLOT(negMax, 2, 1, DMTX_DISPLAY_SQUARE); */ return DMTX_SUCCESS;}/** * * */static intMatrixRegionAlignCalibEdge(DmtxDecode *dec, DmtxRegion *reg, int edgeLoc){ int streamDir; int steps; int avoidAngle; int symbolShape; DmtxVector2 pTmp; DmtxPixelLoc loc0, loc1, locOrigin; DmtxBresLine line; DmtxFollow follow; DmtxBestLine bestLine; /* Determine pixel coordinates of origin */ pTmp.X = 0.0; pTmp.Y = 0.0; dmtxMatrix3VMultiplyBy(&pTmp, reg->fit2raw); locOrigin.X = (int)(pTmp.X + 0.5); locOrigin.Y = (int)(pTmp.Y + 0.5); locOrigin.status = DMTX_RANGE_GOOD; if(dec->sizeIdxExpected == DmtxSymbolSquareAuto || (dec->sizeIdxExpected >= DmtxSymbol10x10 && dec->sizeIdxExpected <= DmtxSymbol144x144)) symbolShape = DmtxSymbolSquareAuto; else if(dec->sizeIdxExpected == DmtxSymbolRectAuto || (dec->sizeIdxExpected >= DmtxSymbol8x18 && dec->sizeIdxExpected <= DmtxSymbol16x48)) symbolShape = DmtxSymbolRectAuto; else symbolShape = DmtxSymbolShapeAuto; /* Determine end locations of test line */ if(edgeLoc == DmtxEdgeTop) { streamDir = reg->polarity * -1; avoidAngle = reg->leftLine.angle; follow = FollowSeekLoc(dec, reg->locT); pTmp.X = 0.8; pTmp.Y = (symbolShape == DmtxSymbolRectAuto) ? 0.2 : 0.6; } else { assert(edgeLoc == DmtxEdgeRight); streamDir = reg->polarity; avoidAngle = reg->bottomLine.angle; follow = FollowSeekLoc(dec, reg->locR); pTmp.X = (symbolShape == DmtxSymbolSquareAuto) ? 0.7 : 0.9; pTmp.Y = 0.8; } dmtxMatrix3VMultiplyBy(&pTmp, reg->fit2raw); loc1.X = (int)(pTmp.X + 0.5); loc1.Y = (int)(pTmp.Y + 0.5); loc1.status = DMTX_RANGE_GOOD; loc0 = follow.loc; line = BresLineInit(loc0, loc1, locOrigin); steps = TrailBlazeGapped(dec, reg, line, streamDir); bestLine = FindBestSolidLine2(dec, reg, loc0, steps, streamDir, avoidAngle); if(bestLine.mag < 5) { ; } if(edgeLoc == DmtxEdgeTop) { reg->topKnown = 1; reg->topAngle = bestLine.angle; reg->topLoc = bestLine.locBeg; } else { reg->rightKnown = 1; reg->rightAngle = bestLine.angle; reg->rightLoc = bestLine.locBeg; } return DMTX_SUCCESS;}/** * * */static DmtxBresLineBresLineInit(DmtxPixelLoc loc0, DmtxPixelLoc loc1, DmtxPixelLoc locInside){ int cp; DmtxBresLine line; DmtxPixelLoc *locBeg, *locEnd; /* XXX Verify that loc0 and loc1 are inbounds */ /* Values that stay the same after initialization */ line.loc0 = loc0; line.loc1 = loc1; line.xStep = (loc0.X < loc1.X) ? +1 : -1; line.yStep = (loc0.Y < loc1.Y) ? +1 : -1; line.xDelta = abs(loc1.X - loc0.X); line.yDelta = abs(loc1.Y - loc0.Y); line.steep = (int)(line.yDelta > line.xDelta); /* Take cross product to determine outward step */ if(line.steep != 0) { /* Point first vector up to get correct sign */ if(loc0.Y < loc1.Y) { locBeg = &loc0; locEnd = &loc1; } else { locBeg = &loc1; locEnd = &loc0; } cp = (((locEnd->X - locBeg->X) * (locInside.Y - locEnd->Y)) - ((locEnd->Y - locBeg->Y) * (locInside.X - locEnd->X))); line.xOut = (cp > 0) ? +1 : -1; line.yOut = 0; } else { /* Point first vector left to get correct sign */ if(loc0.X > loc1.X) { locBeg = &loc0; locEnd = &loc1; } else { locBeg = &loc1; locEnd = &loc0; } cp = (((locEnd->X - locBeg->X) * (locInside.Y - locEnd->Y)) - ((locEnd->Y - locBeg->Y) * (locInside.X - locEnd->X))); line.xOut = 0; line.yOut = (cp > 0) ? +1 : -1; } /* Values that change while stepping through line */ line.loc = loc0; line.travel = 0; line.outward = 0; line.error = (line.steep) ? line.yDelta/2 : line.xDelta/2;/* CALLBACK_POINT_PLOT(loc0, 3, 1, DMTX_DISPLAY_SQUARE); CALLBACK_POINT_PLOT(loc1, 3, 1, DMTX_DISPLAY_SQUARE); */ return line;}/** * * */static intBresLineGetStep(DmtxBresLine line, DmtxPixelLoc target, int *travel, int *outward){ /* Determine necessary step along and outward from Bresenham line */ if(line.steep != 0) { *travel = (line.yStep > 0) ? target.Y - line.loc.Y : line.loc.Y - target.Y; BresLineStep(&line, *travel, 0); *outward = (line.xOut > 0) ? target.X - line.loc.X : line.loc.X - target.X; assert(line.yOut == 0); } else { *travel = (line.xStep > 0) ? target.X - line.loc.X : line.loc.X - target.X; BresLineStep(&line, *travel, 0); *outward = (line.yOut > 0) ? target.Y - line.loc.Y : line.loc.Y - target.Y; assert(line.xOut == 0); } return DMTX_SUCCESS;}/** * * */static intBresLineStep(DmtxBresLine *line, int travel, int outward){ int i; DmtxBresLine lineNew; lineNew = *line; assert(abs(travel) < 2); assert(abs(outward) >= 0); /* Perform forward step */ if(travel > 0) { lineNew.travel++; if(lineNew.steep != 0) { lineNew.loc.Y += lineNew.yStep; lineNew.error -= lineNew.xDelta; if(lineNew.error < 0) { lineNew.loc.X += lineNew.xStep; lineNew.error += lineNew.yDelta; } } else { lineNew.loc.X += lineNew.xStep; lineNew.error -= lineNew.yDelta; if(lineNew.error < 0) { lineNew.loc.Y += lineNew.yStep; lineNew.error += lineNew.xDelta; } } } else if(travel < 0) { lineNew.travel--; if(lineNew.steep != 0) { lineNew.loc.Y -= lineNew.yStep; lineNew.error += lineNew.xDelta; if(lineNew.error >= lineNew.yDelta) { lineNew.loc.X -= lineNew.xStep; lineNew.error -= lineNew.yDelta; } } else { lineNew.loc.X -= lineNew.xStep; lineNew.error += lineNew.yDelta; if(lineNew.error >= lineNew.xDelta) { lineNew.loc.Y -= lineNew.yStep; lineNew.error -= lineNew.xDelta; } } } for(i = 0; i < outward; i++) { /* Outward steps */ lineNew.outward++; lineNew.loc.X += lineNew.xOut; lineNew.loc.Y += lineNew.yOut; } *line = lineNew; return DMTX_SUCCESS;}/** * * *//**static voidWriteDiagnosticImage(DmtxDecode *dec, DmtxRegion *reg, char *imagePath){ int row, col; int width, height; int offset; FILE *fp; DmtxRgb rgb; DmtxVector2 p; DmtxImage *img; assert(reg != NULL); fp = fopen(imagePath, "wb"); if(fp == NULL) { exit(3); } width = dmtxImageGetProp(dec->image, DmtxPropScaledWidth); height = dmtxImageGetProp(dec->image, DmtxPropScaledHeight); img = dmtxImageMalloc(width, height); // Populate image for(row = 0; row < height; row++) { for(col = 0; col < width; col++) { offset = dmtxImageGetOffset(dec->image, col, row); if(offset == DMTX_BAD_OFFSET) { rgb[0] = 0; rgb[1] = 0; rgb[2] = 128; } else { dmtxImageGetRgb(dec->image, col, row, rgb); p.X = col; p.Y = row; dmtxMatrix3VMultiplyBy(&p, reg->raw2fit); if(p.X < 0.0 || p.X > 1.0 || p.Y < 0.0 || p.Y > 1.0) { rgb[0] = 0; rgb[1] = 0; rgb[2] = 128; } else if(p.X + p.Y > 1.0) { rgb[0] += (0.4 * (255 - rgb[0])); rgb[1] += (0.4 * (255 - rgb[1])); rgb[2] += (0.4 * (255 - rgb[2])); } } dmtxImageSetRgb(img, col, row, rgb); } } // Write additional markers rgb[0] = 255; rgb[1] = 0; rgb[2] = 0; dmtxImageSetRgb(img, reg->topLoc.X, reg->topLoc.Y, rgb); dmtxImageSetRgb(img, reg->rightLoc.X, reg->rightLoc.Y, rgb); // Write image to PNM file fprintf(fp, "P6\n%d %d\n255\n", width, height); for(row = height - 1; row >= 0; row--) { for(col = 0; col < width; col++) { dmtxImageGetRgb(img, col, row, rgb); fwrite(rgb, sizeof(char), 3, fp); } } fclose(fp);}*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -