internal DmtxRegion(DmtxRegion src) { this._bottomAngle = src._bottomAngle; this._bottomKnown = src._bottomKnown; this._bottomLine = src._bottomLine; this._bottomLoc = src._bottomLoc; this._boundMax = src._boundMax; this._boundMin = src._boundMin; this._finalNeg = src._finalNeg; this._finalPos = src._finalPos; this._fit2raw = new DmtxMatrix3(src._fit2raw); this._flowBegin = src._flowBegin; this._jumpToNeg = src._jumpToNeg; this._jumpToPos = src._jumpToPos; this._leftAngle = src._leftAngle; this._leftKnown = src._leftKnown; this._leftLine = src._leftLine; this._leftLoc = src._leftLoc; this._locR = src._locR; this._locT = src._locT; this._mappingCols = src._mappingCols; this._mappingRows = src._mappingRows; this._offColor = src._offColor; this._onColor = src._onColor; this._polarity = src._polarity; this._raw2fit = new DmtxMatrix3(src._raw2fit); this._rightAngle = src._rightAngle; this._rightKnown = src._rightKnown; this._rightLoc = src._rightLoc; this._sizeIdx = src._sizeIdx; this._stepR = src._stepR; this._stepsTotal = src._stepsTotal; this._stepT = src._stepT; this._symbolCols = src._symbolCols; this._symbolRows = src._symbolRows; this._topAngle = src._topAngle; this._topKnown = src._topKnown; this._topLoc = src._topLoc; }
DmtxBestLine FindBestSolidLine2(DmtxPixelLoc loc0, int tripSteps, int sign, int houghAvoid) { int[,] hough = new int[3, DmtxConstants.DmtxHoughRes]; int houghMin, houghMax; char[] houghTest = new char[DmtxConstants.DmtxHoughRes]; int i; int step; int angleBest; int hOffset, hOffsetBest; int xDiff, yDiff; int dH; DmtxBestLine line = new DmtxBestLine(); DmtxPixelLoc rHp; DmtxFollow follow; angleBest = 0; hOffset = hOffsetBest = 0; follow = FollowSeekLoc(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 < DmtxConstants.DmtxHoughRes; i++) { if (houghAvoid == DmtxConstants.DmtxUndefined) { houghTest[i] = (char)1; } else { houghMin = (houghAvoid + DmtxConstants.DmtxHoughRes / 6) % DmtxConstants.DmtxHoughRes; houghMax = (houghAvoid - DmtxConstants.DmtxHoughRes / 6 + DmtxConstants.DmtxHoughRes) % DmtxConstants.DmtxHoughRes; if (houghMin > houghMax) houghTest[i] = (i > houghMin || i < houghMax) ? (char)1 : (char)0; else houghTest[i] = (i > houghMin && i < houghMax) ? (char)1 : (char)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 < DmtxConstants.DmtxHoughRes; i++) { if ((int)houghTest[i] == 0) continue; dH = (DmtxConstants.rHvX[i] * yDiff) - (DmtxConstants.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; } } } follow = FollowStep2(follow, sign); } line.Angle = angleBest; line.HOffset = hOffsetBest; line.Mag = hough[hOffsetBest, angleBest]; return line; }
bool FindTravelLimits(DmtxRegion reg, ref DmtxBestLine line) { int i; int distSq, distSqMax; int xDiff, yDiff; bool 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(reg, line.StepBeg); loc0 = followPos.Loc; cosAngle = DmtxConstants.rHvX[line.Angle]; sinAngle = DmtxConstants.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 = (i < 10 || Math.Abs(posWander) < Math.Abs(posTravel)); negRunning = (i < 10 || Math.Abs(negWander) < Math.Abs(negTravel)); if (posRunning) { 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 = DmtxCommon.Min<int>(posWanderMin, posWander); posWanderMax = DmtxCommon.Max<int>(posWanderMax, posWander); } } else if (!negRunning) { break; } if (negRunning) { 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 = DmtxCommon.Min<int>(negWanderMin, negWander); negWanderMax = DmtxCommon.Max<int>(negWanderMax, negWander); } } else if (!posRunning) { break; } followPos = FollowStep(reg, followPos, +1); followNeg = FollowStep(reg, followNeg, -1); } line.Devn = DmtxCommon.Max<int>(posWanderMaxLock - posWanderMinLock, negWanderMaxLock - negWanderMinLock) / 256; line.DistSq = distSqMax; return true; }
DmtxBestLine FindBestSolidLine(DmtxRegion reg, int step0, int step1, int streamDir, int houghAvoid) { int[,] hough = new int[3, DmtxConstants.DmtxHoughRes]; int houghMin, houghMax; char[] houghTest = new char[DmtxConstants.DmtxHoughRes]; int i; int step; int sign = 0; int tripSteps = 0; int xDiff, yDiff; int dH; DmtxFollow follow; DmtxBestLine line = new DmtxBestLine(); DmtxPixelLoc rHp; int angleBest = 0; int hOffset = 0; int hOffsetBest = 0; /* Always follow path flowing away from the trail start */ if (step0 != 0) { if (step0 > 0) { sign = +1; tripSteps = (step1 - step0 + reg.StepsTotal) % reg.StepsTotal; } else { sign = -1; tripSteps = (step0 - step1 + reg.StepsTotal) % reg.StepsTotal; } if (tripSteps == 0) tripSteps = reg.StepsTotal; } else if (step1 != 0) { sign = (step1 > 0) ? +1 : -1; tripSteps = Math.Abs(step1); } else if (step1 == 0) { sign = +1; tripSteps = reg.StepsTotal; } if (sign != streamDir) { throw new Exception("Sign must equal stream direction!"); } follow = FollowSeek(reg, step0); rHp = follow.Loc; line.StepBeg = line.StepPos = line.StepNeg = step0; line.LocBeg = follow.Loc; line.LocPos = follow.Loc; line.LocNeg = follow.Loc; /* Predetermine which angles to test */ for (i = 0; i < DmtxConstants.DmtxHoughRes; i++) { if (houghAvoid == DmtxConstants.DmtxUndefined) { houghTest[i] = (char)1; } else { houghMin = (houghAvoid + DmtxConstants.DmtxHoughRes / 6) % DmtxConstants.DmtxHoughRes; houghMax = (houghAvoid - DmtxConstants.DmtxHoughRes / 6 + DmtxConstants.DmtxHoughRes) % DmtxConstants.DmtxHoughRes; if (houghMin > houghMax) houghTest[i] = (i > houghMin || i < houghMax) ? (char)1 : (char)0; else houghTest[i] = (i > houghMin && i < houghMax) ? (char)1 : (char)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 < DmtxConstants.DmtxHoughRes; i++) { if ((int)houghTest[i] == 0) continue; dH = (DmtxConstants.rHvX[i] * yDiff) - (DmtxConstants.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, 2); */ follow = FollowStep(reg, follow, sign); } line.Angle = angleBest; line.HOffset = hOffsetBest; line.Mag = hough[hOffsetBest, angleBest]; return line; }