예제 #1
0
        public static DmtxVector2 operator -(DmtxVector2 v1, DmtxVector2 v2)
        {
            DmtxVector2 result = new DmtxVector2(v1.X, v1.Y);

            result.X -= v2.X;
            result.Y -= v2.Y;
            return(result);
        }
예제 #2
0
        internal bool PointAlongRay2(DmtxRay2 ray, double t)
        {
            if (Math.Abs(1.0 - ray.V.Mag()) > DmtxConstants.DmtxAlmostZero)
            {
                throw new ArgumentException("PointAlongRay: The ray's V vector must be a unit vector");
            }
            DmtxVector2 tmp = new DmtxVector2(ray.V._x * t, ray.V._y * t);

            this._x = ray.P._x + tmp._x;
            this._y = ray.P._y + tmp._y;
            return(true);
        }
예제 #3
0
        public static DmtxVector2 operator *(DmtxVector2 vector, DmtxMatrix3 matrix)
        {
            double w = Math.Abs(vector.X * matrix[0, 2] + vector.Y * matrix[1, 2] + matrix[2, 2]);

            if (w <= DmtxConstants.DmtxAlmostZero)
            {
                throw new ArgumentException("Multiplication of vector and matrix resulted in invalid result");
            }
            DmtxVector2 result = new DmtxVector2((vector.X * matrix[0, 0] + vector.Y * matrix[1, 0] + matrix[2, 0]) / w,
                                                 (vector.X * matrix[0, 1] + vector.Y * matrix[1, 1] + matrix[2, 1]) / w);

            return(result);
        }
예제 #4
0
        internal static double RightAngleTrueness(DmtxVector2 c0, DmtxVector2 c1, DmtxVector2 c2, double angle)
        {
            DmtxVector2 vA, vB;


            vA = (c0 - c1);
            vB = (c2 - c1);
            vA.Norm();
            vB.Norm();

            DmtxMatrix3 m = DmtxMatrix3.Rotate(angle);

            vB *= m;

            return(vA.Dot(vB));
        }
예제 #5
0
 internal bool PointAlongRay2(DmtxRay2 ray, double t)
 {
     if (Math.Abs(1.0 - ray.V.Mag()) > DmtxConstants.DmtxAlmostZero)
     {
         throw new ArgumentException("PointAlongRay: The ray's V vector must be a unit vector");
     }
     DmtxVector2 tmp = new DmtxVector2(ray.V._x * t, ray.V._y * t);
     this._x = ray.P._x + tmp._x;
     this._y = ray.P._y + tmp._y;
     return true;
 }
예제 #6
0
 internal double Dot(DmtxVector2 v2)
 {
     return Math.Sqrt(_x * v2._x + _y * v2._y);
 }
예제 #7
0
 internal double Cross(DmtxVector2 v2)
 {
     return (this._x * v2._y - this._y * v2._x);
 }
예제 #8
0
 public static DmtxVector2 operator -(DmtxVector2 v1, DmtxVector2 v2)
 {
     DmtxVector2 result = new DmtxVector2(v1.X, v1.Y);
     result.X -= v2.X;
     result.Y -= v2.Y;
     return result;
 }
예제 #9
0
        internal DmtxMessage MatrixRegion(DmtxRegion reg, int fix)
        {
            DmtxMessage result = new DmtxMessage(reg.SizeIdx, DmtxFormat.Matrix);
            DmtxVector2 topLeft = new DmtxVector2();
            DmtxVector2 topRight = new DmtxVector2();
            DmtxVector2 bottomLeft = new DmtxVector2();
            DmtxVector2 bottomRight = new DmtxVector2();
            DmtxPixelLoc pxTopLeft = new DmtxPixelLoc();
            DmtxPixelLoc pxTopRight = new DmtxPixelLoc();
            DmtxPixelLoc pxBottomLeft = new DmtxPixelLoc();
            DmtxPixelLoc pxBottomRight = new DmtxPixelLoc();

            if (!PopulateArrayFromMatrix(reg, result))
            {
                throw new Exception("Populating Array from matrix failed!");
            }

            /* maybe place remaining logic into new dmtxDecodePopulatedArray()
               function so other people can pass in their own arrays */

            ModulePlacementEcc200(result.Array, result.Code,
                  reg.SizeIdx, DmtxConstants.DmtxModuleOnRed | DmtxConstants.DmtxModuleOnGreen | DmtxConstants.DmtxModuleOnBlue);

            if (DmtxCommon.DecodeCheckErrors(result.Code, 0, reg.SizeIdx, fix) != true)
            {
                return null;
            }

            topLeft.X = bottomLeft.X = topLeft.Y = topRight.Y = -0.1;
            topRight.X = bottomRight.X = bottomLeft.Y = bottomRight.Y = 1.1;

            topLeft *= reg.Fit2raw;
            topRight *= reg.Fit2raw;
            bottomLeft *= reg.Fit2raw;
            bottomLeft *= reg.Fit2raw;

            pxTopLeft.X = (int)(0.5 + topLeft.X);
            pxTopLeft.Y = (int)(0.5 + topLeft.Y);
            pxBottomLeft.X = (int)(0.5 + bottomLeft.X);
            pxBottomLeft.Y = (int)(0.5 + bottomLeft.Y);
            pxTopRight.X = (int)(0.5 + topRight.X);
            pxTopRight.Y = (int)(0.5 + topRight.Y);
            pxBottomRight.X = (int)(0.5 + bottomRight.X);
            pxBottomRight.Y = (int)(0.5 + bottomRight.Y);

            CacheFillQuad(pxTopLeft, pxTopRight, pxBottomRight, pxBottomLeft);

            result.DecodeDataStream(reg.SizeIdx, null);

            return result;
        }
예제 #10
0
        bool RegionUpdateXfrms(DmtxRegion reg)
        {
            double radians;
            DmtxRay2 rLeft = new DmtxRay2();
            DmtxRay2 rBottom = new DmtxRay2();
            DmtxRay2 rTop = new DmtxRay2();
            DmtxRay2 rRight = new DmtxRay2();
            DmtxVector2 p00 = new DmtxVector2();
            DmtxVector2 p10 = new DmtxVector2();
            DmtxVector2 p11 = new DmtxVector2();
            DmtxVector2 p01 = new DmtxVector2();

            if (!(reg.LeftKnown != 0 && reg.BottomKnown != 0))
            {
                throw new ArgumentException("Error updating Xfrms!");
            }

            /* Build ray representing left edge */
            rLeft.P.X = (double)reg.LeftLoc.X;
            rLeft.P.Y = (double)reg.LeftLoc.Y;
            radians = reg.LeftAngle * (Math.PI / DmtxConstants.DmtxHoughRes);
            rLeft.V.X = Math.Cos(radians);
            rLeft.V.Y = Math.Sin(radians);
            rLeft.TMin = 0.0;
            rLeft.TMax = rLeft.V.Norm();

            /* Build ray representing bottom edge */
            rBottom.P.X = (double)reg.BottomLoc.X;
            rBottom.P.Y = (double)reg.BottomLoc.Y;
            radians = reg.BottomAngle * (Math.PI / DmtxConstants.DmtxHoughRes);
            rBottom.V.X = Math.Cos(radians);
            rBottom.V.Y = Math.Sin(radians);
            rBottom.TMin = 0.0;
            rBottom.TMax = rBottom.V.Norm();

            /* Build ray representing top edge */
            if (reg.TopKnown != 0)
            {
                rTop.P.X = (double)reg.TopLoc.X;
                rTop.P.Y = (double)reg.TopLoc.Y;
                radians = reg.TopAngle * (Math.PI / DmtxConstants.DmtxHoughRes);
                rTop.V.X = Math.Cos(radians);
                rTop.V.Y = Math.Sin(radians);
                rTop.TMin = 0.0;
                rTop.TMax = rTop.V.Norm();
            }
            else
            {
                rTop.P.X = (double)reg.LocT.X;
                rTop.P.Y = (double)reg.LocT.Y;
                radians = reg.BottomAngle * (Math.PI / DmtxConstants.DmtxHoughRes);
                rTop.V.X = Math.Cos(radians);
                rTop.V.Y = Math.Sin(radians);
                rTop.TMin = 0.0;
                rTop.TMax = rBottom.TMax;
            }

            /* Build ray representing right edge */
            if (reg.RightKnown != 0)
            {
                rRight.P.X = (double)reg.RightLoc.X;
                rRight.P.Y = (double)reg.RightLoc.Y;
                radians = reg.RightAngle * (Math.PI / DmtxConstants.DmtxHoughRes);
                rRight.V.X = Math.Cos(radians);
                rRight.V.Y = Math.Sin(radians);
                rRight.TMin = 0.0;
                rRight.TMax = rRight.V.Norm();
            }
            else
            {
                rRight.P.X = (double)reg.LocR.X;
                rRight.P.Y = (double)reg.LocR.Y;
                radians = reg.LeftAngle * (Math.PI / DmtxConstants.DmtxHoughRes);
                rRight.V.X = Math.Cos(radians);
                rRight.V.Y = Math.Sin(radians);
                rRight.TMin = 0.0;
                rRight.TMax = rLeft.TMax;
            }

            /* Calculate 4 corners, real or imagined */
            if (!p00.Intersect(rLeft, rBottom))
                return false;

            if (!p10.Intersect(rBottom, rRight))
                return false;

            if (!p11.Intersect(rRight, rTop))
                return false;

            if (!p01.Intersect(rTop, rLeft))
                return false;

            if (!RegionUpdateCorners(reg, p00, p10, p11, p01))
                return false;

            return true;
        }
예제 #11
0
        bool RegionUpdateCorners(DmtxRegion reg, DmtxVector2 p00,
            DmtxVector2 p10, DmtxVector2 p11, DmtxVector2 p01)
        {
            double xMax, yMax;
            double tx, ty, phi, shx, scx, scy, skx, sky;
            double dimOT, dimOR, dimTX, dimRX, ratio;
            DmtxVector2 vOT, vOR, vTX, vRX, vTmp;

            xMax = (double)(this.Width - 1);
            yMax = (double)(this.Height - 1);

            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 || p01.Y > yMax ||
                  p10.X < 0.0 || p10.Y < 0.0 || p10.X > xMax || p10.Y > yMax)
                return false;

            vOT = p01 - p00;
            vOR = p10 - p00;
            vTX = p11 - p01;
            vRX = p11 - p10;
            dimOT = vOT.Mag(); /* XXX could use MagSquared() */
            dimOR = vOR.Mag();
            dimTX = vTX.Mag();
            dimRX = vRX.Mag();

            /* Verify that sides are reasonably long */
            if (dimOT <= 8.0 || dimOR <= 8.0 || dimTX <= 8.0 || dimRX <= 8.0)
                return false;

            /* Verify that the 4 corners define a reasonably fat quadrilateral */
            ratio = dimOT / dimRX;
            if (ratio <= 0.5 || ratio >= 2.0)
                return false;

            ratio = dimOR / dimTX;
            if (ratio <= 0.5 || ratio >= 2.0)
                return false;

            /* Verify this is not a bowtie shape */
            if (vOR.Cross(vRX) <= 0.0 || vOT.Cross(vTX) >= 0.0)
                return false;

            if (DmtxCommon.RightAngleTrueness(p00, p10, p11, Math.PI / 2.0) <= this._squareDevn)
                return false;
            if (DmtxCommon.RightAngleTrueness(p10, p11, p01, Math.PI / 2.0) <= this._squareDevn)
                return false;

            /* Calculate values needed for transformations */
            tx = -1 * p00.X;
            ty = -1 * p00.Y;
            DmtxMatrix3 mtxy = DmtxMatrix3.Translate(tx, ty);

            phi = Math.Atan2(vOT.X, vOT.Y);
            DmtxMatrix3 mphi = DmtxMatrix3.Rotate(phi);
            DmtxMatrix3 m = mtxy * mphi;

            vTmp = p10 * m;
            shx = -vTmp.Y / vTmp.X;
            DmtxMatrix3 mshx = DmtxMatrix3.Shear(0.0, shx);
            m *= mshx;

            scx = 1.0 / vTmp.X;
            DmtxMatrix3 mscx = DmtxMatrix3.Scale(scx, 1.0);
            m *= mscx;
            vTmp = p11 * m;

            scy = 1.0 / vTmp.Y;
            DmtxMatrix3 mscy = DmtxMatrix3.Scale(1.0, scy);
            m *= mscy;

            vTmp = p11 * m;
            skx = vTmp.X;
            DmtxMatrix3 mskx = DmtxMatrix3.LineSkewSide(1.0, skx, 1.0);
            m *= mskx;

            vTmp = p01 * m;
            sky = vTmp.Y;
            DmtxMatrix3 msky = DmtxMatrix3.LineSkewTop(sky, 1.0, 1.0);
            reg.Raw2fit = m * msky;

            /* Create inverse matrix by reverse (avoid straight matrix inversion) */
            msky = DmtxMatrix3.LineSkewTopInv(sky, 1.0, 1.0);
            mskx = DmtxMatrix3.LineSkewSideInv(1.0, skx, 1.0);
            m = msky * mskx;

            DmtxMatrix3 mscxy = DmtxMatrix3.Scale(1.0 / scx, 1.0 / scy);
            m *= mscxy;

            mshx = DmtxMatrix3.Shear(0.0, -shx);
            m *= mshx;

            mphi = DmtxMatrix3.Rotate(-phi);
            m *= mphi;

            mtxy = DmtxMatrix3.Translate(-tx, -ty);
            reg.Fit2raw = m * mtxy;

            return true;
        }
예제 #12
0
        private int ReadModuleColor(DmtxRegion reg, int symbolRow, int symbolCol, DmtxSymbolSize sizeIdx, int colorPlane)
        {
            int i;
            int symbolRows, symbolCols;
            int color, colorTmp;
            double[] sampleX = { 0.5, 0.4, 0.5, 0.6, 0.5 };
            double[] sampleY = { 0.5, 0.5, 0.4, 0.5, 0.6 };
            DmtxVector2 p = new DmtxVector2();

            symbolRows = DmtxCommon.GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribSymbolRows, sizeIdx);
            symbolCols = DmtxCommon.GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribSymbolCols, sizeIdx);

            colorTmp = color = 0;
            for (i = 0; i < 5; i++)
            {

                p.X = (1.0 / symbolCols) * (symbolCol + sampleX[i]);
                p.Y = (1.0 / symbolRows) * (symbolRow + sampleY[i]);

                p *= reg.Fit2raw;

                GetPixelValue((int)(p.X + 0.5), (int)(p.Y + 0.5), colorPlane, ref colorTmp);
                color += colorTmp;
            }

            return color / 5;
        }
예제 #13
0
        bool MatrixRegionAlignCalibEdge(DmtxRegion reg, DmtxEdge edgeLoc)
        {
            int streamDir;
            int steps;
            int avoidAngle;
            DmtxSymbolSize symbolShape;
            DmtxVector2 pTmp = new DmtxVector2();
            DmtxPixelLoc loc0 = new DmtxPixelLoc();
            DmtxPixelLoc loc1 = new DmtxPixelLoc();
            DmtxPixelLoc locOrigin = new DmtxPixelLoc();
            DmtxBresLine line;
            DmtxFollow follow;
            DmtxBestLine bestLine;

            /* Determine pixel coordinates of origin */
            pTmp.X = 0.0;
            pTmp.Y = 0.0;
            pTmp *= reg.Fit2raw;
            locOrigin.X = (int)(pTmp.X + 0.5);
            locOrigin.Y = (int)(pTmp.Y + 0.5);

            if (this._sizeIdxExpected == DmtxSymbolSize.DmtxSymbolSquareAuto ||
                  (this._sizeIdxExpected >= DmtxSymbolSize.DmtxSymbol10x10 &&
                  this._sizeIdxExpected <= DmtxSymbolSize.DmtxSymbol144x144))
                symbolShape = DmtxSymbolSize.DmtxSymbolSquareAuto;
            else if (this._sizeIdxExpected == DmtxSymbolSize.DmtxSymbolRectAuto ||
                  (this._sizeIdxExpected >= DmtxSymbolSize.DmtxSymbol8x18 &&
                  this._sizeIdxExpected <= DmtxSymbolSize.DmtxSymbol16x48))
                symbolShape = DmtxSymbolSize.DmtxSymbolRectAuto;
            else
                symbolShape = DmtxSymbolSize.DmtxSymbolShapeAuto;

            /* Determine end locations of test line */
            if (edgeLoc == DmtxEdge.DmtxEdgeTop)
            {
                streamDir = reg.Polarity * -1;
                avoidAngle = reg.LeftLine.Angle;
                follow = FollowSeekLoc(reg.LocT);
                pTmp.X = 0.8;
                pTmp.Y = (symbolShape == DmtxSymbolSize.DmtxSymbolRectAuto) ? 0.2 : 0.6;
            }
            else
            {
                streamDir = reg.Polarity;
                avoidAngle = reg.BottomLine.Angle;
                follow = FollowSeekLoc(reg.LocR);
                pTmp.X = (symbolShape == DmtxSymbolSize.DmtxSymbolSquareAuto) ? 0.7 : 0.9;
                pTmp.Y = 0.8;
            }

            pTmp *= reg.Fit2raw;
            loc1.X = (int)(pTmp.X + 0.5);
            loc1.Y = (int)(pTmp.Y + 0.5);

            loc0 = follow.Loc;
            line = new DmtxBresLine(loc0, loc1, locOrigin);
            steps = TrailBlazeGapped(reg, line, streamDir);

            bestLine = FindBestSolidLine2(loc0, steps, streamDir, avoidAngle);
            if (bestLine.Mag < 5)
            {
                ;
            }

            if (edgeLoc == DmtxEdge.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 true;
        }
예제 #14
0
        private void PrintPattern(Color? foreColor, Color? backColor)
        {
            int i, j;
            int symbolRow, symbolCol;
            int pixelRow, pixelCol;
            int moduleStatus;
            int rowSize, height;
            int[] rgb = new int[3];
            double sxy, txy;
            DmtxVector2 vIn, vOut;

            txy = this._marginSize;
            sxy = 1.0 / this._moduleSize;

            DmtxMatrix3 m1 = DmtxMatrix3.Translate(-txy, -txy);
            DmtxMatrix3 m2 = DmtxMatrix3.Scale(sxy, -sxy);
            DmtxMatrix3 xfrm = m1 * m2;

            m1 = DmtxMatrix3.Translate(txy, txy);
            m2 = DmtxMatrix3.Scale(this._moduleSize, this._moduleSize);
            DmtxMatrix3 rxfrm = m2 * m1;

            rowSize = this._image.RowSizeBytes;
            height = this._image.Height;

            for (int pxlIndex = 0; pxlIndex < rowSize * height; pxlIndex++)
            {
                this._image.Pxl[pxlIndex] = 0xff;
            }

            for (symbolRow = 0; symbolRow < this._region.SymbolRows; symbolRow++)
            {
                for (symbolCol = 0; symbolCol < this._region.SymbolCols; symbolCol++)
                {
                    vIn = new DmtxVector2(symbolCol, symbolRow);
                    vOut = vIn * rxfrm;

                    pixelCol = (int)(vOut.X);
                    pixelRow = (int)(vOut.Y);
                    moduleStatus = this._message.SymbolModuleStatus(this._region.SizeIdx, symbolRow, symbolCol);
                    if (moduleStatus != 7)
                    {
                        bool rgb0 = (moduleStatus & DmtxConstants.DmtxModuleOnRed) == 0;
                        bool rgb1 = (moduleStatus & DmtxConstants.DmtxModuleOnGreen) == 0;
                        bool rgb2 = (moduleStatus & DmtxConstants.DmtxModuleOnBlue) == 0;
                    }
                    for (i = pixelRow; i < pixelRow + this._moduleSize; i++)
                    {
                        for (j = pixelCol; j < pixelCol + this._moduleSize; j++)
                        {
                            if (foreColor.HasValue && backColor.HasValue)
                            {
                                rgb[0] = ((moduleStatus & DmtxConstants.DmtxModuleOnRed) != 0x00) ? foreColor.Value.B : backColor.Value.B;
                                rgb[1] = ((moduleStatus & DmtxConstants.DmtxModuleOnGreen) != 0x00) ? foreColor.Value.G : backColor.Value.G;
                                rgb[2] = ((moduleStatus & DmtxConstants.DmtxModuleOnBlue) != 0x00) ? foreColor.Value.R : backColor.Value.R;
                            }
                            else
                            {
                                rgb[0] = ((moduleStatus & DmtxConstants.DmtxModuleOnBlue) != 0x00) ? 0 : 255;
                                rgb[1] = ((moduleStatus & DmtxConstants.DmtxModuleOnGreen) != 0x00) ? 0 : 255;
                                rgb[2] = ((moduleStatus & DmtxConstants.DmtxModuleOnRed) != 0x00) ? 0 : 255;
                            }
                            /*             dmtxImageSetRgb(enc->image, j, i, rgb); */
                            this._image.SetPixelValue(j, i, 0, (byte)rgb[0]);
                            this._image.SetPixelValue(j, i, 1, (byte)rgb[1]);
                            this._image.SetPixelValue(j, i, 2, (byte)rgb[2]);
                        }
                    }

                }
            }
        }
예제 #15
0
 internal double Cross(DmtxVector2 v2)
 {
     return(this._x * v2._y - this._y * v2._x);
 }
예제 #16
0
 internal double Dot(DmtxVector2 v2)
 {
     return(Math.Sqrt(_x * v2._x + _y * v2._y));
 }