Пример #1
0
        /// <summary>
        /// Returns the LOCATION of each ItemAlt (midpoint, relative: 0 to 1)
        /// </summary>
        public static PointF[,] RotateAndCrop(Test test, ref byte[,] image, ref byte[] barCodeBytes, float resize, int searchSize)
        {
            var ansList = new PointF[test.Paper.Blocks.X, test.Paper.Blocks.Y];

            image = Processing.Resize(image, resize);
            List <PointF> calibrationPointsRotate = Rotate(test, ref image, searchSize);

            if (calibrationPointsRotate.Count == test.Paper.CalibrationCircles.X + test.Paper.CalibrationCircles.Y - 1)
            {
                byte[,] imgBarCode = new byte[0, 0];
                List <PointF> calibrationPointsCrop = Crop(test, ref image, ref imgBarCode, searchSize);

                if (calibrationPointsCrop.Count == test.Paper.CalibrationCircles.X + test.Paper.CalibrationCircles.Y - 1)
                {
                    barCodeBytes = BarCode.Read(imgBarCode);

                    // Calculate the answerpoints
                    var xList = new List <float>();
                    for (int i = 0; i < test.Paper.CalibrationCircles.X - 1; i++)
                    {
                        float obsW            = calibrationPointsCrop[i + 1].X - calibrationPointsCrop[i].X;
                        int   blocksLeft      = 7;
                        float pixelsPerBlockW = obsW / blocksLeft;
                        if (i == test.Paper.CalibrationCircles.X - 2)
                        {
                            blocksLeft      = test.Paper.Blocks.X - ((test.Paper.CalibrationCircles.X - 2) * 7);
                            pixelsPerBlockW = obsW / (blocksLeft + .5f);
                        }
                        for (int j = 0; j < blocksLeft; j++)
                        {
                            xList.Add(calibrationPointsCrop[i].X + (j * pixelsPerBlockW));
                        }
                    }
                    for (int i = calibrationPointsCrop.Count - 1; i >= test.Paper.CalibrationCircles.X; i--)
                    {
                        float obsH            = calibrationPointsCrop[i - 1].Y - calibrationPointsCrop[i].Y;
                        int   blocksLeft      = 7;
                        float pixelsPerBlockH = obsH / blocksLeft;
                        if (i <= test.Paper.CalibrationCircles.X)
                        {
                            blocksLeft      = test.Paper.Blocks.Y - ((test.Paper.CalibrationCircles.Y - 2) * 7);
                            pixelsPerBlockH = obsH / (blocksLeft + 1);
                        }
                        int i2 = (calibrationPointsCrop.Count - i - 1) * 7;
                        for (int ii = 0; ii < blocksLeft; ii++)
                        {
                            float yVal = calibrationPointsCrop[i].Y + (ii * pixelsPerBlockH);
                            for (int j = 0; j < xList.Count; j++)
                            {
                                ansList[j, i2 + ii] = new PointF(xList[j] / image.GetLength(0), yVal / image.GetLength(1));
                            }
                        }
                    }
                }
            }
            return(ansList);
        }
Пример #2
0
        // Persumed to be rotated correctly (but not yet cropped)
        public static byte[] Read(byte[,] imageData)
        {
            byte[,] array = new byte[19, 4];

            if (imageData != null)
            {
                if (imageData.GetLength(0) > 0 && imageData.GetLength(1) > 0)
                {
                    imageData = Processing.FloatToByte(Processing.Gaussian(imageData));
                    imageData = Processing.Binarize(imageData, 200);

                    int minBlack = Math.Min(4, Math.Min(imageData.GetLength(0) / 19, imageData.GetLength(1) / 4));

                    Point p1 = new Point(-1, -1);
                    Point p2 = new Point(-1, -1);

                    for (int i = 0; i < (imageData.GetLength(0) / 2); i++)
                    {
                        int sum1 = 0;
                        int sum2 = 0;
                        for (int j = 0; j < imageData.GetLength(1); j++)
                        {
                            sum1 += imageData[i, j] > 0 ? 0 : 1;
                            sum2 += imageData[imageData.GetLength(0) - i - 1, j] > 0 ? 0 : 1;
                        }
                        if (p1.X == -1 && sum1 >= minBlack)
                        {
                            p1.X = i;
                        }
                        if (p2.X == -1 && sum2 >= minBlack)
                        {
                            p2.X = imageData.GetLength(0) - i - 1;
                        }
                        if (p1.X != -1 && p2.X != -1)
                        {
                            break;
                        }
                    }

                    for (int j = 0; j < (imageData.GetLength(1) / 2); j++)
                    {
                        int sum1 = 0;
                        int sum2 = 0;
                        for (int i = 0; i < imageData.GetLength(0); i++)
                        {
                            sum1 += imageData[i, j] > 0 ? 0 : 1;
                            sum2 += imageData[i, imageData.GetLength(1) - j - 1] > 0 ? 0 : 1;
                        }
                        if (p1.Y == -1 && sum1 >= minBlack)
                        {
                            p1.Y = j;
                        }
                        if (p2.Y == -1 && sum2 >= minBlack)
                        {
                            p2.Y = imageData.GetLength(1) - j - 1;
                        }
                        if (p1.Y != -1 && p2.Y != -1)
                        {
                            break;
                        }
                    }

                    if (p1.X != -1 && p1.Y != -1 && p2.X != -1 && p2.Y != -1)
                    {
                        imageData = Processing.Crop(imageData, new Rectangle(p1.X, p1.Y, p2.X - p1.X + 1, p2.Y - p1.Y + 1));

                        int blockWidth  = (int)Math.Floor((double)imageData.GetLength(0) / 19);
                        int blockHeight = (int)Math.Floor((double)imageData.GetLength(1) / 4);

                        int newWidth  = blockWidth * 19;
                        int newHeight = blockHeight * 4;

                        imageData = Processing.Resize(imageData, newWidth, newHeight);
                        int threshold = (blockWidth * blockHeight) / 2;

                        for (int j = 0; j < 4; j++)
                        {
                            for (int i = 0; i < 19; i++)
                            {
                                double sum = 0;
                                for (int k = 0; k < blockHeight; k++)
                                {
                                    for (int l = 0; l < blockWidth; l++)
                                    {
                                        sum += (int)imageData[(i * blockWidth) + l, (j * blockHeight) + k] > 1 ? 1 : 0;
                                    }
                                }
                                array[i, j] = sum < threshold ? (byte)0 : (byte)1;
                            }
                        }
                    }
                    else
                    {
                        Logger.LogLow("Could not crop barcode.");
                    }
                }
            }
            return(ReadFrom2DArray(array));
        }