26#define DMTX_HOUGH_RES 180
37 if (regCopy == NULL) {
53 if (reg == NULL || *reg == NULL) {
102 unsigned char *cache;
115 if ((
int)(*cache & 0x80) != 0x00) {
121 if (flowBegin.
mag < (
int)(dec->edgeThresh * 7.65 + 0.5)) {
185 channelCount = dec->image->channelCount;
189 for (i = 0; i < channelCount; i++) {
191 if (i > 0 && flowPlane[i].mag > flowPlane[strongIdx].mag) {
196 if (flowPlane[strongIdx].mag < 10) {
200 flow = flowPlane[strongIdx];
211 if (flowPos.
mag != 0 && flowNeg.
mag != 0) {
264 maxDiagonal = (int)(1.23 * dec->edgeMax + 0.5);
266 maxDiagonal = (int)(1.56 * dec->edgeMax + 0.5);
284 minArea = (dec->edgeMin * dec->edgeMin) / (scale * scale);
286 minArea = (2 * dec->edgeMin * dec->edgeMin) / (scale * scale);
297 if (line1x.
mag < 5) {
320 if (line2p.
mag > line2n.
mag) {
414 return (xDelta * xDelta) + (yDelta * yDelta);
425 double tx, ty, phi, shx, scx, scy, skx, sky;
426 double dimOT, dimOR, dimTX, dimRX, ratio;
428 DmtxMatrix3 m, mtxy, mphi, mshx, mscx, mscy, mscxy, msky, mskx;
433 if (p00.
x < 0.0 || p00.
y < 0.0 || p00.
x > xMax || p00.
y > yMax || p01.
x < 0.0 || p01.
y < 0.0 || p01.
x > xMax ||
434 p01.
y > yMax || p10.
x < 0.0 || p10.
y < 0.0 || p10.
x > xMax || p10.
y > yMax) {
444 if (dimOT <= 8.0 || dimOR <= 8.0 || dimTX <= 8.0 || dimRX <= 8.0) {
449 ratio = dimOT / dimRX;
450 if (ratio <= 0.5 || ratio >= 2.0) {
454 ratio = dimOR / dimTX;
455 if (ratio <= 0.5 || ratio >= 2.0) {
476 phi = atan2(vOT.
x, vOT.
y);
481 shx = -vTmp.
y / vTmp.
x;
531 DmtxRay2 rLeft, rBottom, rTop, rRight;
540 rLeft.
v.
x = cos(radians);
541 rLeft.
v.
y = sin(radians);
549 rBottom.
v.
x = cos(radians);
550 rBottom.
v.
y = sin(radians);
559 rTop.
v.
x = cos(radians);
560 rTop.
v.
y = sin(radians);
564 rTop.
p.
x = (double)reg->
locT.
x;
565 rTop.
p.
y = (double)reg->
locT.
y;
567 rTop.
v.
x = cos(radians);
568 rTop.
v.
y = sin(radians);
578 rRight.
v.
x = cos(radians);
579 rRight.
v.
y = sin(radians);
583 rRight.
p.
x = (double)reg->
locR.
x;
584 rRight.
p.
y = (double)reg->
locR.
y;
586 rRight.
v.
x = cos(radians);
587 rRight.
v.
y = sin(radians);
649 int symbolRows, symbolCols;
651 double sampleX[] = {0.5, 0.4, 0.5, 0.6, 0.5};
652 double sampleY[] = {0.5, 0.5, 0.4, 0.5, 0.6};
660 for (i = 0; i < 5; i++) {
661 p.
x = (1.0 / symbolCols) * (symbolCol + sampleX[i]);
662 p.
y = (1.0 / symbolRows) * (symbolRow + sampleY[i]);
691 int sizeIdxBeg, sizeIdxEnd;
692 int sizeIdx, bestSizeIdx;
693 int symbolRows, symbolCols;
694 int jumpCount, errors;
696 int colorOnAvg, bestColorOnAvg;
697 int colorOffAvg, bestColorOffAvg;
698 int contrast, bestContrast;
704 bestColorOnAvg = bestColorOffAvg = 0;
716 sizeIdxBeg = dec->sizeIdxExpected;
717 sizeIdxEnd = dec->sizeIdxExpected + 1;
721 for (sizeIdx = sizeIdxBeg; sizeIdx < sizeIdxEnd; sizeIdx++) {
724 colorOnAvg = colorOffAvg = 0;
727 row = symbolRows - 1;
728 for (col = 0; col < symbolCols; col++) {
730 if ((col & 0x01) != 0x00) {
731 colorOffAvg += color;
738 col = symbolCols - 1;
739 for (row = 0; row < symbolRows; row++) {
741 if ((row & 0x01) != 0x00) {
742 colorOffAvg += color;
748 colorOnAvg = (colorOnAvg * 2) / (symbolRows + symbolCols);
749 colorOffAvg = (colorOffAvg * 2) / (symbolRows + symbolCols);
751 contrast = abs(colorOnAvg - colorOffAvg);
757 if (contrast > bestContrast) {
758 bestContrast = contrast;
759 bestSizeIdx = sizeIdx;
760 bestColorOnAvg = colorOnAvg;
761 bestColorOffAvg = colorOffAvg;
790 errors = abs(1 + jumpCount - reg->
symbolCols);
791 if (jumpCount < 0 || errors > 2) {
808 errors = abs(1 + jumpCount - reg->
symbolRows);
809 if (jumpCount < 0 || errors > 2) {
824 if (jumpCount < 0 || errors > 2) {
841 if (errors < 0 || errors > 2) {
857 if (errors < 0 || errors > 2) {
872 if (errors < 0 || errors > 2) {
886 if (errors < 0 || errors > 2) {
901 if (errors < 0 || errors > 2) {
944 jumpThreshold = abs((
int)(0.4 * (reg->
onColor - reg->
offColor) + 0.5));
948 for (x = xStart + xInc, y = yStart + yInc;
950 x += xInc, y += yInc) {
956 if (tModule > tPrev + jumpThreshold) {
961 if (tModule < tPrev - jumpThreshold) {
976 static const int coefficient[] = {0, 1, 2, 1, 0, -1, -2, -1};
978 int patternIdx, coefficientIdx;
979 int compass, compassMax;
981 int xAdjust, yAdjust;
982 int color, colorPattern[8];
993 for (patternIdx = 0; patternIdx < 8; patternIdx++) {
1004 for (compass = 0; compass < 4; compass++) {
1006 for (patternIdx = 0; patternIdx < 8; patternIdx++) {
1007 coefficientIdx = (patternIdx - compass + 8) % 8;
1008 if (coefficient[coefficientIdx] == 0) {
1012 color = colorPattern[patternIdx];
1014 switch (coefficient[coefficientIdx]) {
1016 mag[compass] += color;
1019 mag[compass] += color;
1022 mag[compass] -= color;
1025 mag[compass] -= color;
1031 if (compass != 0 && abs(mag[compass]) > abs(mag[compassMax])) {
1032 compassMax = compass;
1037 flow.
plane = colorPlane;
1039 flow.
depart = (mag[compassMax] > 0) ? compassMax + 4
1041 flow.
mag = abs(mag[compassMax]);
1055 int attempt, attemptDiff;
1057 unsigned char *cache;
1061 attempt = (sign < 0) ? center.
depart : (center.
depart + 4) % 8;
1065 for (i = 0; i < 8; i++) {
1070 if (cache == NULL) {
1074 if ((
int)(*cache & 0x80) != 0x00) {
1075 if (++occupied > 2) {
1081 attemptDiff = abs(attempt - i);
1082 if (attemptDiff > 4) {
1083 attemptDiff = 8 - attemptDiff;
1085 if (attemptDiff > 1) {
1091 if (strongIdx ==
DmtxUndefined || flow[i].mag > flow[strongIdx].mag ||
1092 (flow[i].mag == flow[strongIdx].mag && ((i & 0x01) != 0))) {
1123 follow.neighbor = *follow.ptr;
1125 sign = (seek > 0) ? +1 : -1;
1126 for (i = 0; i != seek; i += sign) {
1146 follow.neighbor = *follow.ptr;
1167 DmtxAssert((
int)(followBeg.neighbor & 0x40) != 0x00);
1171 stepMod = (factor + (followBeg.step % factor)) % factor;
1173 stepMod = (factor - (followBeg.step % factor)) % factor;
1177 if (sign > 0 && stepMod == reg->
jumpToNeg) {
1181 else if (sign < 0 && stepMod == reg->jumpToPos) {
1186 patternIdx = (sign < 0) ? followBeg.neighbor & 0x07 : ((followBeg.neighbor & 0x38) >> 3);
1187 follow.loc.x = followBeg.loc.x +
dmtxPatternX[patternIdx];
1188 follow.loc.y = followBeg.loc.y +
dmtxPatternY[patternIdx];
1191 follow.step = followBeg.step + sign;
1194 follow.neighbor = *follow.ptr;
1209 DmtxAssert((
int)(followBeg.neighbor & 0x40) != 0x00);
1211 patternIdx = (sign < 0) ? followBeg.neighbor & 0x07 : ((followBeg.neighbor & 0x38) >> 3);
1212 follow.loc.x = followBeg.loc.x +
dmtxPatternX[patternIdx];
1213 follow.loc.y = followBeg.loc.y +
dmtxPatternY[patternIdx];
1215 follow.step = followBeg.step + sign;
1218 follow.neighbor = *follow.ptr;
1236 int posAssigns, negAssigns, clears;
1239 unsigned char *cache, *cacheNext, *cacheBeg;
1243 boundMin = boundMax = flowBegin.
loc;
1245 if (cacheBeg == NULL) {
1248 *cacheBeg = (0x80 | 0x40);
1252 posAssigns = negAssigns = 0;
1253 for (sign = 1; sign >= -1; sign -= 2) {
1257 for (steps = 0;; steps++) {
1260 (boundMax.
x - boundMin.
x > maxDiagonal || boundMax.
y - boundMin.
y > maxDiagonal)) {
1266 if (flowNext.
mag < 50) {
1272 if (cacheNext == NULL) {
1280 *cache |= (sign < 0) ? flowNext.
arrive : flowNext.
arrive << 3;
1285 *cacheNext = (sign < 0) ? (((flowNext.
arrive + 4) % 8) << 3) : ((flowNext.
arrive + 4) % 8);
1286 *cacheNext |= (0x80 | 0x40);
1295 if (flow.
loc.
x > boundMax.
x) {
1296 boundMax.
x = flow.
loc.
x;
1297 }
else if (flow.
loc.
x < boundMin.
x) {
1298 boundMin.
x = flow.
loc.
x;
1300 if (flow.
loc.
y > boundMax.
y) {
1301 boundMax.
y = flow.
loc.
y;
1302 }
else if (flow.
loc.
y < boundMin.
y) {
1303 boundMin.
y = flow.
loc.
y;
1325 DmtxAssert(posAssigns + negAssigns == clears - 1);
1329 (boundMax.
x - boundMin.
x > maxDiagonal || boundMax.
y - boundMin.
y > maxDiagonal)) {
1343 unsigned char *beforeCache, *afterCache;
1345 int distSq, distSqMax;
1346 int travel, outward;
1349 int stepDir, dirMap[] = {0, 1, 2, 7, 8, 3, 6, 5, 4};
1358 distSqMax = (line.xDelta * line.xDelta) + (line.yDelta * line.yDelta);
1364 if (beforeCache == NULL) {
1367 *beforeCache = 0x00;
1381 if (flowNext.
mag < 50 || outward < 0 || (outward == 0 && travel < 0)) {
1392 if (flow.
mag > 50) {
1397 afterStep = line.loc;
1399 if (afterCache == NULL) {
1404 xStep = afterStep.
x - beforeStep.
x;
1405 yStep = afterStep.
y - beforeStep.
y;
1406 DmtxAssert(abs(xStep) <= 1 && abs(yStep) <= 1);
1407 stepDir = dirMap[3 * yStep + xStep + 4];
1410 if (streamDir < 0) {
1411 *beforeCache |= (0x40 | stepDir);
1412 *afterCache = (((stepDir + 4) % 8) << 3);
1414 *beforeCache |= (0x40 | (stepDir << 3));
1415 *afterCache = ((stepDir + 4) % 8);
1419 xDiff = line.loc.x - loc0.
x;
1420 yDiff = line.loc.y - loc0.
y;
1421 distSq = (xDiff * xDiff) + (yDiff * yDiff);
1423 beforeStep = line.loc;
1424 beforeCache = afterCache;
1427 }
while (distSq < distSqMax);
1446 while (abs(follow.step) <= reg->
stepsTotal) {
1447 DmtxAssert((
int)(*follow.ptr & clearMask) != 0x00);
1448 *follow.ptr &= (clearMask ^ 0xff);
1475 int houghMin, houghMax;
1482 int hOffset, hOffsetBest;
1491 memset(&rH, 0x00,
sizeof(
DmtxRay2));
1493 hOffset = hOffsetBest = 0;
1506 if (tripSteps == 0) {
1509 }
else if (step1 != 0) {
1510 sign = (step1 > 0) ? +1 : -1;
1511 tripSteps = abs(step1);
1512 }
else if (step1 == 0) {
1522 line.
locBeg = follow.loc;
1523 line.
locPos = follow.loc;
1524 line.
locNeg = follow.loc;
1533 if (houghMin > houghMax) {
1534 houghTest[i] = (i > houghMin || i < houghMax) ? 1 : 0;
1536 houghTest[i] = (i > houghMin && i < houghMax) ? 1 : 0;
1542 for (step = 0; step < tripSteps; step++) {
1543 xDiff = follow.loc.x - rHp.
x;
1544 yDiff = follow.loc.y - rHp.
y;
1548 if ((
int)houghTest[i] == 0) {
1552 dH = (
rHvX[i] * yDiff) - (
rHvY[i] * xDiff);
1553 if (dH >= -384 && dH <= 384) {
1556 }
else if (dH >= -128) {
1562 hough[hOffset][i]++;
1565 if (hough[hOffset][i] > hough[hOffsetBest][angleBest]) {
1567 hOffsetBest = hOffset;
1573 cbPlotPoint(follow.loc, (sign > 1) ? 120.0F + step : 300.0F + step, 1, 2);
1579 line.
angle = angleBest;
1581 line.
mag = hough[hOffsetBest][angleBest];
1593 int houghMin, houghMax;
1598 int hOffset, hOffsetBest;
1607 memset(&rH, 0x00,
sizeof(
DmtxRay2));
1609 hOffset = hOffsetBest = 0;
1622 if (houghMin > houghMax) {
1623 houghTest[i] = (i > houghMin || i < houghMax) ? 1 : 0;
1625 houghTest[i] = (i > houghMin && i < houghMax) ? 1 : 0;
1631 for (step = 0; step < tripSteps; step++) {
1632 xDiff = follow.loc.x - rHp.
x;
1633 yDiff = follow.loc.y - rHp.
y;
1637 if ((
int)houghTest[i] == 0) {
1641 dH = (
rHvX[i] * yDiff) - (
rHvY[i] * xDiff);
1642 if (dH >= -384 && dH <= 384) {
1645 }
else if (dH >= -128) {
1651 hough[hOffset][i]++;
1654 if (hough[hOffset][i] > hough[hOffsetBest][angleBest]) {
1656 hOffsetBest = hOffset;
1662 cbPlotPoint(follow.loc, (sign > 1) ? 300.0F : 120.0F , 1, 2);
1668 line.
angle = angleBest;
1670 line.
mag = hough[hOffsetBest][angleBest];
1682 int distSq, distSqMax;
1684 int posRunning, negRunning;
1685 int posTravel, negTravel;
1686 int posWander, posWanderMin, posWanderMax, posWanderMinLock, posWanderMaxLock;
1687 int negWander, negWanderMin, negWanderMax, negWanderMinLock, negWanderMaxLock;
1688 int cosAngle, sinAngle;
1694 loc0 = followPos.loc;
1700 posMax = negMax = followPos.loc;
1702 posTravel = negTravel = 0;
1703 posWander = posWanderMin = posWanderMax = posWanderMinLock = posWanderMaxLock = 0;
1704 negWander = negWanderMin = negWanderMax = negWanderMinLock = negWanderMaxLock = 0;
1707 posRunning = (int)(i < 10 || abs(posWander) < abs(posTravel));
1708 negRunning = (int)(i < 10 || abs(negWander) < abs(negTravel));
1710 if (posRunning != 0) {
1711 xDiff = followPos.loc.x - loc0.
x;
1712 yDiff = followPos.loc.y - loc0.
y;
1713 posTravel = (cosAngle * xDiff) + (sinAngle * yDiff);
1714 posWander = (cosAngle * yDiff) - (sinAngle * xDiff);
1716 if (posWander >= -3 * 256 && posWander <= 3 * 256) {
1718 if (distSq > distSqMax) {
1719 posMax = followPos.loc;
1721 line->
stepPos = followPos.step;
1722 line->
locPos = followPos.loc;
1723 posWanderMinLock = posWanderMin;
1724 posWanderMaxLock = posWanderMax;
1727 posWanderMin =
min(posWanderMin, posWander);
1728 posWanderMax =
max(posWanderMax, posWander);
1730 }
else if (!negRunning) {
1734 if (negRunning != 0) {
1735 xDiff = followNeg.loc.x - loc0.
x;
1736 yDiff = followNeg.loc.y - loc0.
y;
1737 negTravel = (cosAngle * xDiff) + (sinAngle * yDiff);
1738 negWander = (cosAngle * yDiff) - (sinAngle * xDiff);
1740 if (negWander >= -3 * 256 && negWander < 3 * 256) {
1742 if (distSq > distSqMax) {
1743 negMax = followNeg.loc;
1745 line->
stepNeg = followNeg.step;
1746 line->
locNeg = followNeg.loc;
1747 negWanderMinLock = negWanderMin;
1748 negWanderMaxLock = negWanderMax;
1751 negWanderMin =
min(negWanderMin, negWander);
1752 negWanderMax =
max(negWanderMax, negWander);
1754 }
else if (!posRunning) {
1763 followPos =
followStep(dec, reg, followPos, +1);
1764 followNeg =
followStep(dec, reg, followNeg, -1);
1766 line->
devn =
max(posWanderMaxLock - posWanderMinLock, negWanderMaxLock - negWanderMinLock) / 256;
1767 line->
distSq = distSqMax;
1797 locOrigin.
x = (int)(pTmp.
x + 0.5);
1798 locOrigin.
y = (int)(pTmp.
y + 0.5);
1827 loc1.
x = (int)(pTmp.
x + 0.5);
1828 loc1.
y = (int)(pTmp.
y + 0.5);
1835 if (bestLine.
mag < 5) {
1867 line.xStep = (loc0.
x < loc1.
x) ? +1 : -1;
1868 line.yStep = (loc0.
y < loc1.
y) ? +1 : -1;
1869 line.xDelta = abs(loc1.
x - loc0.
x);
1870 line.yDelta = abs(loc1.
y - loc0.
y);
1871 line.steep = (int)(line.yDelta > line.xDelta);
1874 if (line.steep != 0) {
1876 if (loc0.
y < loc1.
y) {
1883 cp = (((locEnd->
x - locBeg->
x) * (locInside.
y - locEnd->
y)) -
1884 ((locEnd->
y - locBeg->
y) * (locInside.
x - locEnd->
x)));
1886 line.xOut = (cp > 0) ? +1 : -1;
1890 if (loc0.
x > loc1.
x) {
1897 cp = (((locEnd->
x - locBeg->
x) * (locInside.
y - locEnd->
y)) -
1898 ((locEnd->
y - locBeg->
y) * (locInside.
x - locEnd->
x)));
1901 line.yOut = (cp > 0) ? +1 : -1;
1908 line.error = (line.steep) ? line.yDelta / 2 : line.xDelta / 2;
1925 if (line.steep != 0) {
1926 *travel = (line.yStep > 0) ? target.
y - line.loc.y : line.loc.y - target.
y;
1928 *outward = (line.xOut > 0) ? target.
x - line.loc.x : line.loc.x - target.
x;
1931 *travel = (line.xStep > 0) ? target.
x - line.loc.x : line.loc.x - target.
x;
1933 *outward = (line.yOut > 0) ? target.
y - line.loc.y : line.loc.y - target.
y;
1957 if (lineNew.steep != 0) {
1958 lineNew.loc.y += lineNew.yStep;
1959 lineNew.error -= lineNew.xDelta;
1960 if (lineNew.error < 0) {
1961 lineNew.loc.x += lineNew.xStep;
1962 lineNew.error += lineNew.yDelta;
1965 lineNew.loc.x += lineNew.xStep;
1966 lineNew.error -= lineNew.yDelta;
1967 if (lineNew.error < 0) {
1968 lineNew.loc.y += lineNew.yStep;
1969 lineNew.error += lineNew.xDelta;
1972 }
else if (travel < 0) {
1974 if (lineNew.steep != 0) {
1975 lineNew.loc.y -= lineNew.yStep;
1976 lineNew.error += lineNew.xDelta;
1977 if (lineNew.error >= lineNew.yDelta) {
1978 lineNew.loc.x -= lineNew.xStep;
1979 lineNew.error -= lineNew.yDelta;
1982 lineNew.loc.x -= lineNew.xStep;
1983 lineNew.error += lineNew.yDelta;
1984 if (lineNew.error >= lineNew.xDelta) {
1985 lineNew.loc.y -= lineNew.yStep;
1986 lineNew.error -= lineNew.xDelta;
1991 for (i = 0; i < outward; i++) {
1994 lineNew.loc.x += lineNew.xOut;
1995 lineNew.loc.y += lineNew.yOut;
2012 unsigned char *cache;
2020 fp = fopen(imagePath,
"wb");
2031 for (row = 0; row < height; row++) {
2032 for (col = 0; col < width; col++) {
2034 if (cache == NULL) {
2047 if (p.X < 0.0 || p.X > 1.0 || p.Y < 0.0 || p.Y > 1.0) {
2051 }
else if (p.X + p.Y > 1.0) {
2052 rgb[0] += (0.4 * (255 - rgb[0]));
2053 rgb[1] += (0.4 * (255 - rgb[1]));
2054 rgb[2] += (0.4 * (255 - rgb[2]));
2058 dmtxImageSetRgb(img, col, row, rgb);
2066 dmtxImageSetRgb(img, reg->toploc.x, reg->toploc.y, rgb);
2067 dmtxImageSetRgb(img, reg->rightloc.x, reg->rightloc.y, rgb);
2070 fprintf(fp,
"P6\n%d %d\n255\n", width, height);
2071 for (row = height - 1; row >= 0; row--) {
2072 for (col = 0; col < width; col++) {
2073 dmtxImageGetRgb(img, col, row, rgb);
2074 fwrite(rgb,
sizeof(
char), 3, fp);
libdmtx - Data Matrix Encoding/Decoding Library Copyright 2008, 2009 Mike Laughton.
DmtxPassFail dmtxMatrix3VMultiply(OUT DmtxVector2 *vOut, DmtxVector2 *vIn, DmtxMatrix3 m)
将向量与矩阵相乘
double dmtxVector2Cross(const DmtxVector2 *v1, const DmtxVector2 *v2)
二维向量叉积
void dmtxMatrix3LineSkewSide(OUT DmtxMatrix3 m, double b0, double b1, double sz)
Generate side line skew transformation.
int dmtxGetSymbolAttribute(int attribute, int sizeIdx)
根据规格索引返回二维码规格各个参数
enum DmtxDirection_enum DmtxDirection
int dmtxTimeExceeded(DmtxTime timeout)
Determine whether the received timeout has been exceeded.
double DmtxMatrix3[3][3]
DmtxMatrix3 类型定义,表示一个3x3的双精度浮点数矩阵
void dmtxMatrix3Multiply(OUT DmtxMatrix3 mOut, DmtxMatrix3 m0, DmtxMatrix3 m1)
矩阵相乘
@ DmtxSymAttribSymbolRows
二维码码元总行数(包括L形框和点线)
@ DmtxSymAttribSymbolCols
二维码码元总列数(包括L形框和点线)
@ DmtxSymAttribMappingMatrixRows
二维码数据区码元总行数(不包括L形框和点线)
@ DmtxSymAttribMappingMatrixCols
二维码数据区码元总列数(不包括L形框和点线)
void dmtxMatrix3LineSkewTop(OUT DmtxMatrix3 m, double b0, double b1, double sz)
生成顶部线倾斜变换矩阵
DmtxPassFail dmtxImageDestroy(DmtxImage **img)
Free libdmtx image memory.
double dmtxVector2Mag(const DmtxVector2 *v)
二维向量的模
void dmtxMatrix3Rotate(OUT DmtxMatrix3 m, double angle)
生成旋转变换矩阵
DmtxPassFail dmtxMatrix3VMultiplyBy(INOUT DmtxVector2 *v, DmtxMatrix3 m)
将向量与矩阵相乘
DmtxPassFail dmtxRay2Intersect(OUT DmtxVector2 *point, const DmtxRay2 *p0, const DmtxRay2 *p1)
判断两条直线是否相交,并计算交点。
void dmtxMatrix3Translate(OUT DmtxMatrix3 m, double tx, double ty)
生成平移变换矩阵
double dmtxVector2Norm(DmtxVector2 *v)
DmtxImage * dmtxImageCreate(unsigned char *pxl, int width, int height, int pack)
libdmtx stores image data as a large one-dimensional array of packed pixels, reading from the array w...
#define DmtxSymbolRectCount
长方形二维码种类个数
void dmtxMatrix3LineSkewSideInv(OUT DmtxMatrix3 m, double b0, double b1, double sz)
Generate side line skew transformation (inverse)
void dmtxMatrix3Shear(OUT DmtxMatrix3 m, double shx, double shy)
生成剪切变换矩阵
#define DmtxSymbolSquareCount
正方形二维码种类个数
DmtxVector2 * dmtxVector2Sub(OUT DmtxVector2 *vOut, const DmtxVector2 *v1, const DmtxVector2 *v2)
向量相减
void dmtxMatrix3MultiplyBy(INOUT DmtxMatrix3 m0, DmtxMatrix3 m1)
矩阵相乘
double dmtxVector2Dot(const DmtxVector2 *v1, const DmtxVector2 *v2)
二维向量点积
void dmtxMatrix3Scale(OUT DmtxMatrix3 m, double sx, double sy)
生成缩放变换矩阵
#define DmtxModuleOff
bit0
void dmtxMatrix3LineSkewTopInv(OUT DmtxMatrix3 m, double b0, double b1, double sz)
Generate top line skew transformation (inverse)
unsigned char * dmtxDecodeGetCache(DmtxDecode *dec, int x, int y)
Returns xxx.
DmtxPassFail dmtxDecodeGetPixelValue(DmtxDecode *dec, int x, int y, int channel, OUT int *value)
获取图像像素
int dmtxDecodeGetProp(DmtxDecode *dec, int prop)
Get decoding behavior property.
DmtxRegion * dmtxRegionScanPixel(DmtxDecode *dec, int x, int y)
将坐标点(x,y)作为二维码L型框的边缘点去匹配二维码包围框
DmtxPassFail dmtxRegionUpdateXfrms(DmtxDecode *dec, DmtxRegion *reg)
static DmtxPointFlow findStrongestNeighbor(DmtxDecode *dec, DmtxPointFlow center, int sign)
static DmtxPassFail matrixRegionAlignCalibEdge(DmtxDecode *dec, DmtxRegion *reg, int edgeLoc)
static DmtxPassFail matrixRegionFindSize(DmtxDecode *dec, DmtxRegion *reg)
确定二维码尺寸(点线中黑白点的总数)
DmtxRegion * dmtxRegionFindNext(DmtxDecode *dec, DmtxTime *timeout)
寻找下一个二维码区域
static double rightAngleTrueness(DmtxVector2 c0, DmtxVector2 c1, DmtxVector2 c2, double angle)
static DmtxBestLine findBestSolidLine2(DmtxDecode *dec, DmtxPixelLoc loc0, int tripSteps, int sign, int houghAvoid)
DmtxPassFail dmtxRegionDestroy(DmtxRegion **reg)
Destroy region struct.
static DmtxBestLine findBestSolidLine(DmtxDecode *dec, DmtxRegion *reg, int step0, int step1, int streamDir, int houghAvoid)
查找最佳实线
static DmtxPointFlow getPointFlow(DmtxDecode *dec, int colorPlane, DmtxPixelLoc loc, int arrive)
从像素坐标寻找其在指定颜色平面的梯度方向
static DmtxPassFail bresLineStep(DmtxBresLine *line, int travel, int outward)
static DmtxFollow followSeek(DmtxDecode *dec, DmtxRegion *reg, int seek)
根据指定步数从当前区域的起始点追踪到新位置
DmtxRegion * dmtxRegionCreate(DmtxRegion *reg)
Create copy of existing region struct.
static DmtxPassFail trailBlazeContinuous(DmtxDecode *dec, DmtxRegion *reg, DmtxPointFlow flowBegin, int maxDiagonal)
从flowBegin点出发,分别从正负方向寻找连续的边界线
static DmtxPassFail findTravelLimits(DmtxDecode *dec, DmtxRegion *reg, DmtxBestLine *line)
static DmtxFollow followStep2(DmtxDecode *dec, DmtxFollow followBeg, int sign)
DmtxPassFail dmtxRegionUpdateCorners(DmtxDecode *dec, DmtxRegion *reg, DmtxVector2 p00, DmtxVector2 p10, DmtxVector2 p11, DmtxVector2 p01)
static long distanceSquared(DmtxPixelLoc a, DmtxPixelLoc b)
计算两个像素点之间的欧几里得距离的平方
static int readModuleColor(DmtxDecode *dec, DmtxRegion *reg, int symbolRow, int symbolCol, int sizeIdx, int colorPlane)
读取模块(码元)颜色值
static DmtxFollow followSeekLoc(DmtxDecode *dec, DmtxPixelLoc loc)
根据指定像素坐标初始化追踪起始信息
static int trailClear(DmtxDecode *dec, DmtxRegion *reg, int clearMask)
static DmtxBresLine bresLineInit(DmtxPixelLoc loc0, DmtxPixelLoc loc1, DmtxPixelLoc locInside)
static int countJumpTally(DmtxDecode *dec, DmtxRegion *reg, int xStart, int yStart, DmtxDirection dir)
计算一个方向上颜色跳变次数
static int trailBlazeGapped(DmtxDecode *dec, DmtxRegion *reg, DmtxBresLine line, int streamDir)
recives bresline, and follows strongest neighbor unless it involves ratcheting bresline inward or bac...
static DmtxPassFail bresLineGetStep(DmtxBresLine line, DmtxPixelLoc target, int *travel, int *outward)
static DmtxFollow followStep(DmtxDecode *dec, DmtxRegion *reg, DmtxFollow followBeg, int sign)
寻找followBeg的下一个点
static DmtxPassFail matrixRegionOrientation(DmtxDecode *dec, DmtxRegion *reg, DmtxPointFlow begin)
确定数据矩阵区域的方向和关键边界
static DmtxPointFlow matrixRegionSeekEdge(DmtxDecode *dec, DmtxPixelLoc loc)
寻找指定像素位置梯度流向,并检查该点是否能形成闭环。如果成功暂定该点在DataMatrix的'L'型边上
static int popGridLocation(DmtxScanGrid *grid, DmtxPixelLoc *locPtr)
Return the next good location (which may be the current location), and advance grid progress one posi...
libdmtx - Data Matrix Encoding/Decoding Library Copyright 2008, 2009 Mike Laughton.
static const DmtxPointFlow dmtxBlankEdge
static const int dmtxPatternX[]
static const int dmtxPatternY[]
static const int dmtxNeighborNone
static DmtxCallbackPlotModule cbPlotModule
static DmtxCallbackPlotPoint cbPlotPoint
static DmtxCallbackBuildMatrixRegion cbBuildMatrixRegion
DmtxPixelLoc locPos
正方向点(线段端点)
DmtxPixelLoc locNeg
负方向点(线段端点)
int leftAngle
hough angle of left edge
int bottomKnown
known == 1; unknown == 0
int bottomAngle
hough angle of bottom edge
int rightKnown
known == 1; unknown == 0
DmtxPixelLoc rightLoc
known (arbitrary) location on right edge
DmtxMatrix3 raw2fit
3x3 变换矩阵,从图像坐标系到二维码坐标系
int mappingCols
二维码数据区码元列数
int sizeIdx
二维码类型索引,总共有 DmtxSymbolSquareCount + DmtxSymbolRectCount 种
int mappingRows
二维码数据区码元行数
int leftKnown
known == 1; unknown == 0
DmtxPointFlow flowBegin
搜索起点,十字搜索抛出的点
int symbolRows
二维码码元行数(包括L形框和点线)
int symbolCols
二维码码元列数(包括L形框和点线)
DmtxPixelLoc bottomLoc
known (arbitrary) location on bottom edge
int topKnown
known == 1; unknown == 0
int rightAngle
hough angle of right edge
DmtxPixelLoc leftLoc
known (arbitrary) location on left edge
DmtxPixelLoc locT
remove if stepT works above
DmtxPixelLoc topLoc
known (arbitrary) location on top edge
int topAngle
hough angle of top edge
DmtxPixelLoc locR
remove if stepR works above
DmtxMatrix3 fit2raw
3x3 变换矩阵,从二维码坐标系到图像坐标系