⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dmtxregion.c

📁 Linux系统下,二维码生成源代码.希望对大家有所帮助.
💻 C
📖 第 1 页 / 共 4 页
字号:
   matrixRegion->chain.bx1 = 100.0;   matrixRegion->chain.by0 = 100.0;   matrixRegion->chain.by1 = 100.0;   matrixRegion->chain.sz = 100.0;   MatrixRegionUpdateXfrms(matrixRegion);}/** * XXX * TODO: this function should really be static --- move "decode" functions into this file * * @param * @return XXX */extern voiddmtxMatrixRegionDeInit(DmtxMatrixRegion *matrixRegion){   if(matrixRegion->array != NULL)      free(matrixRegion->array);   if(matrixRegion->code != NULL)      free(matrixRegion->code);   if(matrixRegion->output != NULL)      free(matrixRegion->output);   memset(matrixRegion, 0x00, sizeof(DmtxMatrixRegion));}/** * XXX * * @param * @return XXX */static voidMatrix3ChainXfrm(DmtxMatrix3 m, DmtxChain *chain){   DmtxMatrix3 mtxy, mphi, mshx, mscxy, msky, mskx;   dmtxMatrix3Translate(mtxy, chain->tx, chain->ty);   dmtxMatrix3Rotate(mphi, chain->phi);   dmtxMatrix3Shear(mshx, chain->shx, 0.0);   dmtxMatrix3Scale(mscxy, chain->scx * chain->sz, chain->scy * chain->sz);   dmtxMatrix3LineSkewTop(msky, chain->by0, chain->by1, chain->sz);   dmtxMatrix3LineSkewSide(mskx, chain->bx0, chain->bx1, chain->sz);   dmtxMatrix3Multiply(m, mtxy, mphi);   dmtxMatrix3MultiplyBy(m, mshx);   dmtxMatrix3MultiplyBy(m, mscxy);   dmtxMatrix3MultiplyBy(m, msky);   dmtxMatrix3MultiplyBy(m, mskx);}/** * XXX * * @param * @return XXX */static voidMatrix3ChainXfrmInv(DmtxMatrix3 m, DmtxChain *chain){   DmtxMatrix3 mskx, msky, mscxy, mshx, mphi, mtxy;   dmtxMatrix3LineSkewSideInv(mskx, chain->bx0, chain->bx1, chain->sz);   dmtxMatrix3LineSkewTopInv(msky, chain->by0, chain->by1, chain->sz);   dmtxMatrix3Scale(mscxy, 1.0/(chain->scx * chain->sz), 1.0/(chain->scy * chain->sz));   dmtxMatrix3Shear(mshx, -chain->shx, 0.0);   dmtxMatrix3Rotate(mphi, -chain->phi);   dmtxMatrix3Translate(mtxy, -chain->tx, -chain->ty);   dmtxMatrix3Multiply(m, mskx, msky);   dmtxMatrix3MultiplyBy(m, mscxy);   dmtxMatrix3MultiplyBy(m, mshx);   dmtxMatrix3MultiplyBy(m, mphi);   dmtxMatrix3MultiplyBy(m, mtxy);}/** * XXX * * @param * @return XXX */static voidMatrixRegionUpdateXfrms(DmtxMatrixRegion *matrixRegion){   Matrix3ChainXfrm(matrixRegion->raw2fit, &(matrixRegion->chain));   Matrix3ChainXfrmInv(matrixRegion->fit2raw, &(matrixRegion->chain));}/** * XXX * * @param * @return XXX */static intMatrixRegionAlignFinderBars(DmtxMatrixRegion *matrixRegion, DmtxDecode *decode,      DmtxEdgeFollower *f0, DmtxEdgeFollower *f1){   int             success;   float           v1Length;   float           v2Length;   DmtxFinderBar   bar;   DmtxEdgeFollower *fTmp;   DmtxRay2        rPrimary, rSecondary;   DmtxVector2     pMin, pTmp;   DmtxVector2     v1, v2;   DmtxMatrix3     m;   DmtxChain       chain;/* XXX comment these cases bettercount   1st    2nd         0      0            return false         1      1            colinear?            yes: decide which is primary (longer secondary)                 verify other finder bar is co-linear            no:  finder bars are known         1      0         11     0            primary is known            verify that secondary is long enough         0      1         0     11            primary is known            verify that secondary is long enough*/   // Ensure that no secondary line is defined unless primary line is also defined   assert((f0->line1.isDefined) ? f0->line0.isDefined : 1);   assert((f1->line1.isDefined) ? f1->line0.isDefined : 1);   // We need at least 2 finder bar candidates to proceed   if(f0->line0.isDefined + f0->line1.isDefined + f1->line0.isDefined + f1->line1.isDefined < 2) {      return DMTX_FALSE;   }   // One direction contains both possible finder bar candidates (rare)   else if(f0->line0.isDefined + f1->line0.isDefined == 1) {      fTmp = (f0->line0.isDefined) ? f0 : f1;      rPrimary = fTmp->line0;   // Set primary to the defined one      rSecondary = fTmp->line1; // Set secondary to the defined one's dog-leg   }   // Each direction contains a finder bar candidate   else {      // Close to -1.0 means colinear (but opposite)      if(dmtxVector2Dot(&(f0->line0.v), &(f1->line0.v)) < -0.99) {         if(f0->line1.isDefined * (f0->line1.tMax - f0->line1.tMin) >               f1->line1.isDefined * (f1->line1.tMax - f1->line1.tMin)) {            // Primary is combination of both line0's (careful about direction / tMax handling)            rPrimary = f1->line0;            dmtxPointAlongRay2(&pMin, &(f0->line0), f0->line0.tMax);            rPrimary.tMin = dmtxDistanceAlongRay2(&rPrimary, &pMin);            rSecondary = f0->line1;         }         else {            // Primary is combination of both line0's (careful about direction / tMax handling)            rPrimary = f0->line0;            dmtxPointAlongRay2(&pMin, &(f1->line0), f1->line0.tMax);            rPrimary.tMin = dmtxDistanceAlongRay2(&rPrimary, &pMin);            rSecondary = f1->line1;         }      }      else {         // Set primary and secondary to line0's arbitrarily         rPrimary = f0->line0;         rSecondary = f1->line0;      }   }   // Check if we have to valid lines   if(rPrimary.isDefined == 0 || rSecondary.isDefined == 0) {      return DMTX_FALSE;   }   else if(rPrimary.tMax - rPrimary.tMin < 15 || rSecondary.tMax - rSecondary.tMin < 15) {      return DMTX_FALSE;   }   // Can't check lengths yet because length should be calculated from the   // true intersection of both lines   // Find intersection of 2 chosen rays   success = dmtxRay2Intersect(&(bar.p0), &rPrimary, &rSecondary);   if(!success) {      return DMTX_FALSE;   }   dmtxPointAlongRay2(&(bar.p2), &rPrimary, rPrimary.tMax);   dmtxPointAlongRay2(&(bar.p1), &rSecondary, rSecondary.tMax);   dmtxVector2Sub(&v1, &bar.p1, &bar.p0);   dmtxVector2Sub(&v2, &bar.p2, &bar.p0);   v1Length = dmtxVector2Mag(&v1);   v2Length = dmtxVector2Mag(&v2);   // Check that both lines are at least 10 pixels in length   if(v1Length < 10 || v2Length < 10) {//    fprintf(stdout, "Reject: At least one finder bar is too short.\n");      return DMTX_FALSE;   }   // Check matrix is not too "flat"   else if(min(v1Length, v2Length) / max(v1Length, v2Length) < 0.2) {//    fprintf(stdout, "Reject: Candidate region is too \"flat\" (%g).\n",//          min(v1Length, v2Length) / max(v1Length, v2Length));      return DMTX_FALSE;   }   // normalize(dir1) and normalize(dir2)   dmtxVector2Norm(&v1);   dmtxVector2Norm(&v2);   // Check that finder bars are not colinear   if(fabs(dmtxVector2Dot(&v1, &v2)) > cos(20.0*M_PI/180.0)) {//    fprintf(stdout, "Reject: Finder bars are too colinear.\n");      return DMTX_FALSE;   }   // XXX This is where we draw the 3 squares on the first pane: Replace with plotPoint callback   if(decode && decode->plotPointCallback) {      (*(decode->plotPointCallback))(bar.p0, 1, 1, DMTX_DISPLAY_SQUARE);      (*(decode->plotPointCallback))(bar.p1, 1, 1, DMTX_DISPLAY_SQUARE);      (*(decode->plotPointCallback))(bar.p2, 1, 1, DMTX_DISPLAY_SQUARE);   }   // Check for clockwise/ccw order of points and flip if necessary   if(dmtxVector2Cross(&v2, &v1) < 0.0) {      pTmp = bar.p1;      bar.p1 = bar.p2;      bar.p2 = pTmp;   }   chain.tx = -bar.p0.X;   chain.ty = -bar.p0.Y;   chain.phi = 0.0;   chain.shx = 0.0;   chain.scx = chain.scy = 1.0;   chain.bx0 = chain.bx1 = chain.by0 = chain.by1 = chain.sz = 1.0;   Matrix3ChainXfrm(m, &chain);   dmtxMatrix3VMultiply(&pTmp, &bar.p2, m);   chain.phi = -atan2(pTmp.Y, pTmp.X);   Matrix3ChainXfrm(m, &chain);   dmtxMatrix3VMultiply(&pTmp, &bar.p2, m);   chain.scx = 1.0/pTmp.X;   dmtxMatrix3VMultiply(&pTmp, &bar.p1, m);   assert(pTmp.Y > DMTX_ALMOST_ZERO);   chain.shx = -pTmp.X / pTmp.Y;   chain.scy = 1.0/pTmp.Y;   chain.bx0 = chain.bx1 = chain.by0 = chain.by1 = chain.sz = 100.0;   // Update transformations now that finders are set   matrixRegion->chain = chain;   MatrixRegionUpdateXfrms(matrixRegion);   // Now matrixRegion contains our best guess.  Next tighten it up.   if(decode && decode->buildMatrixCallback2)      (*(decode->buildMatrixCallback2))(&bar, matrixRegion);   return DMTX_TRUE;}/** * XXX * * @param * @return XXX */static intMatrixRegionAlignTop(DmtxMatrixRegion *matrixRegion, DmtxDecode *decode){   double t, m;   double stepSize;   int gapCount = 0, gapLength = 0, maxGapLength = 0;   DmtxVector2 p0, px0, px1;   DmtxColor3 color;   DmtxMatrix3 s, sInv, sReg, sRegInv, m0, m1;   DmtxVector2 prevHit, prevStep, highHit, highHitX;   dmtxMatrix3LineSkewTop(m0, 100.0, 75.0, 100.0);   dmtxMatrix3Scale(m1, 1.25, 1.0);   dmtxMatrix3Multiply(s, m0, m1);   dmtxMatrix3Multiply(sReg, matrixRegion->raw2fit, s);   dmtxMatrix3LineSkewTopInv(m0, 100.0, 75.0, 100.0);   dmtxMatrix3Scale(m1, 0.8, 1.0);   dmtxMatrix3Multiply(sInv, m1, m0);   dmtxMatrix3Multiply(sRegInv, sInv, matrixRegion->fit2raw);   if(decode && decode->buildMatrixCallback3)      (*(decode->buildMatrixCallback3))(sRegInv);   // Determine step size (90% of rough pixel length)   px0.X = 0.0;   px0.Y = 0.0;   px1.X = 0.0;   px1.Y = 100.0;   dmtxMatrix3VMultiplyBy(&px0, sRegInv);   dmtxMatrix3VMultiplyBy(&px1, sRegInv);   dmtxVector2SubFrom(&px1, &px0);   stepSize = dmtxVector2Mag(&px1);   assert(stepSize > DMTX_ALMOST_ZERO);   stepSize = 0.9 * (100.0/stepSize);   p0.X = 0.0;   p0.Y = 100.0;   prevStep = prevHit = p0;   highHit.X = highHit.Y = 100.0; // XXX add this for safety in case it's not found   while(p0.X < 100.0 && p0.Y < 300.0) { // XXX cap rise at 300.0 to prevent infinite loops      dmtxMatrix3VMultiply(&px0, &p0, sRegInv);      dmtxColor3FromImage(&color, &(decode->image), px0.X, px0.Y);      t = dmtxDistanceAlongRay3(&(matrixRegion->gradient.ray), &color);      if(decode && decode->xfrmPlotPointCallback)         (*(decode->xfrmPlotPointCallback))(px0, sReg, 4, DMTX_DISPLAY_POINT);      // Bad notation whereby:      //    prevStep captures every little step      //    prevHit captures the most recent edge boundary detection      // Need to move upward      if(t > matrixRegion->gradient.tMid) {         // Need to move up, and previous move was right         if(p0.X - prevStep.X > DMTX_ALMOST_ZERO) {            if(gapLength > 2*maxGapLength) {               maxGapLength = gapLength;               gapCount = 1;            }            else if(gapLength > maxGapLength/2) {               gapCount++;            }            gapLength = 0; // no matter what, reset gapLength         }         prevStep = p0;         p0.Y += stepSize;      }      // Need to advance to the right      else {         // Need to move right, and previous step was up         if(fabs(p0.Y - prevStep.Y) > DMTX_ALMOST_ZERO) {            // If it has been a while since previous hit            if(p0.X - prevHit.X >= 3) {               highHit = p0;               highHitX = px0;            }            // Recent had a hit            else {               prevHit = p0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -