Esempio n. 1
0
        public List <TextBox> GetTextBoxes(Mat src, ScaleParam scale, float boxScoreThresh, float boxThresh, float unClipRatio)
        {
            Mat srcResize = new Mat();

            CvInvoke.Resize(src, srcResize, new Size(scale.DstWidth, scale.DstHeight));
            Tensor <float> inputTensors = OcrUtils.SubstractMeanNormalize(srcResize, MeanValues, NormValues);
            var            inputs       = new List <NamedOnnxValue>
            {
                NamedOnnxValue.CreateFromTensor(inputNames[0], inputTensors)
            };

            try
            {
                using (IDisposableReadOnlyCollection <DisposableNamedOnnxValue> results = dbNet.Run(inputs))
                {
                    var resultsArray = results.ToArray();
                    Console.WriteLine(resultsArray);
                    var textBoxes = GetTextBoxes(resultsArray, srcResize.Rows, srcResize.Cols, scale, boxScoreThresh, boxThresh, unClipRatio);
                    return(textBoxes);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message + ex.StackTrace);
            }
            return(null);
        }
Esempio n. 2
0
        public OcrResult Detect(string img, int padding, int maxSideLen, float boxScoreThresh, float boxThresh,
                                float unClipRatio, bool doAngle, bool mostAngle)
        {
            Mat originSrc     = CvInvoke.Imread(img, ImreadModes.Color);//default : BGR
            int originMaxSide = Math.Max(originSrc.Cols, originSrc.Rows);

            int resize;

            if (maxSideLen <= 0 || maxSideLen > originMaxSide)
            {
                resize = originMaxSide;
            }
            else
            {
                resize = maxSideLen;
            }
            resize += 2 * padding;
            Rectangle paddingRect = new Rectangle(padding, padding, originSrc.Cols, originSrc.Rows);
            Mat       paddingSrc  = OcrUtils.MakePadding(originSrc, padding);

            ScaleParam scale = ScaleParam.GetScaleParam(paddingSrc, resize);

            return(DetectOnce(paddingSrc, paddingRect, scale, boxScoreThresh, boxThresh, unClipRatio, doAngle, mostAngle));
        }
Esempio n. 3
0
        public OcrResult Detect(string img, int padding, int imgResize, float boxScoreThresh, float boxThresh,
                                float unClipRatio, bool doAngle, bool mostAngle)
        {
            Mat brgSrc    = CvInvoke.Imread(img, ImreadModes.Color);//default : BGR
            Mat originSrc = new Mat();

            CvInvoke.CvtColor(brgSrc, originSrc, ColorConversion.Bgr2Rgb);// convert to RGB
            Rectangle originRect = new Rectangle(padding, padding, originSrc.Cols, originSrc.Rows);
            Mat       paddingSrc = OcrUtils.MakePadding(originSrc, padding);

            int resize;

            if (imgResize <= 0)
            {
                resize = Math.Max(paddingSrc.Cols, paddingSrc.Rows);
            }
            else
            {
                resize = imgResize;
            }
            ScaleParam scale = ScaleParam.GetScaleParam(paddingSrc, resize);

            return(DetectOnce(paddingSrc, originRect, scale, boxScoreThresh, boxThresh, unClipRatio, doAngle, mostAngle));
        }
Esempio n. 4
0
        private OcrResult DetectOnce(Mat src, Rectangle originRect, ScaleParam scale, float boxScoreThresh, float boxThresh,
                                     float unClipRatio, bool doAngle, bool mostAngle)
        {
            Mat textBoxPaddingImg = src.Clone();
            int thickness         = OcrUtils.GetThickness(src);

            Console.WriteLine("=====Start detect=====");
            var startTicks = DateTime.Now.Ticks;

            Console.WriteLine("---------- step: dbNet getTextBoxes ----------");
            var textBoxes = dbNet.GetTextBoxes(src, scale, boxScoreThresh, boxThresh, unClipRatio);
            var dbNetTime = (DateTime.Now.Ticks - startTicks) / 10000F;

            Console.WriteLine($"TextBoxesSize({textBoxes.Count})");
            textBoxes.ForEach(x => Console.WriteLine(x));
            //Console.WriteLine($"dbNetTime({dbNetTime}ms)");

            Console.WriteLine("---------- step: drawTextBoxes ----------");
            OcrUtils.DrawTextBoxes(textBoxPaddingImg, textBoxes, thickness);
            //CvInvoke.Imshow("ResultPadding", textBoxPaddingImg);

            //---------- getPartImages ----------
            List <Mat> partImages = OcrUtils.GetPartImages(src, textBoxes);

            if (isPartImg)
            {
                for (int i = 0; i < partImages.Count; i++)
                {
                    CvInvoke.Imshow($"PartImg({i})", partImages[i]);
                }
            }

            Console.WriteLine("---------- step: angleNet getAngles ----------");
            List <Angle> angles = angleNet.GetAngles(partImages, doAngle, mostAngle);

            //angles.ForEach(x => Console.WriteLine(x));

            //Rotate partImgs
            for (int i = 0; i < partImages.Count; ++i)
            {
                if (angles[i].Index == 1)
                {
                    partImages[i] = OcrUtils.MatRotateClockWise180(partImages[i]);
                }
                if (isDebugImg)
                {
                    CvInvoke.Imshow($"DebugImg({i})", partImages[i]);
                }
            }

            Console.WriteLine("---------- step: crnnNet getTextLines ----------");
            List <TextLine> textLines = crnnNet.GetTextLines(partImages);
            //textLines.ForEach(x => Console.WriteLine(x));

            List <TextBlock> textBlocks = new List <TextBlock>();

            for (int i = 0; i < textLines.Count; ++i)
            {
                TextBlock textBlock = new TextBlock();
                textBlock.BoxPoints  = textBoxes[i].Points;
                textBlock.BoxScore   = textBoxes[i].Score;
                textBlock.AngleIndex = angles[i].Index;
                textBlock.AngleScore = angles[i].Score;
                textBlock.AngleTime  = angles[i].Time;
                textBlock.Text       = textLines[i].Text;
                textBlock.CharScores = textLines[i].CharScores;
                textBlock.CrnnTime   = textLines[i].Time;
                textBlock.BlockTime  = angles[i].Time + textLines[i].Time;
                textBlocks.Add(textBlock);
            }
            //textBlocks.ForEach(x => Console.WriteLine(x));

            var endTicks       = DateTime.Now.Ticks;
            var fullDetectTime = (endTicks - startTicks) / 10000F;
            //Console.WriteLine($"fullDetectTime({fullDetectTime}ms)");

            //cropped to original size
            Mat boxImg = new Mat(textBoxPaddingImg, originRect);

            StringBuilder strRes = new StringBuilder();

            textBlocks.ForEach(x => strRes.AppendLine(x.Text));

            OcrResult ocrResult = new OcrResult();

            ocrResult.TextBlocks = textBlocks;
            ocrResult.DbNetTime  = dbNetTime;
            ocrResult.BoxImg     = boxImg;
            ocrResult.DetectTime = fullDetectTime;
            ocrResult.StrRes     = strRes.ToString();

            return(ocrResult);
        }
Esempio n. 5
0
        private static List <TextBox> GetTextBoxes(DisposableNamedOnnxValue[] outputTensor, int rows, int cols, ScaleParam s, float boxScoreThresh, float boxThresh, float unClipRatio)
        {
            float          maxSideThresh = 3.0f;//长边门限
            List <TextBox> rsBoxes       = new List <TextBox>();

            //-----Data preparation-----
            float[]     predData = outputTensor[0].AsEnumerable <float>().ToArray();
            List <byte> cbufData = new List <byte>();

            foreach (float data in predData)
            {
                var val = data * 255;
                cbufData.Add(Convert.ToByte(val));
            }
            Mat predMat = new Mat(rows, cols, DepthType.Cv32F, 1);

            predMat.SetTo(predData);

            Mat cbufMat = new Mat(rows, cols, DepthType.Cv8U, 1);

            cbufMat.SetTo(cbufData.ToArray());

            //-----boxThresh-----
            Mat thresholdMat = new Mat();

            CvInvoke.Threshold(cbufMat, thresholdMat, boxThresh * 255.0, 255.0, ThresholdType.Binary);

            //-----dilate-----
            Mat dilateMat     = new Mat();
            Mat dilateElement = CvInvoke.GetStructuringElement(ElementShape.Rectangle, new Size(2, 2), new Point(-1, -1));

            CvInvoke.Dilate(thresholdMat, dilateMat, dilateElement, new Point(-1, -1), 1, BorderType.Default, new MCvScalar(128, 128, 128));

            VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();

            CvInvoke.FindContours(dilateMat, contours, null, RetrType.List, ChainApproxMethod.ChainApproxSimple);

            for (int i = 0; i < contours.Size; i++)
            {
                if (contours[i].Size <= 2)
                {
                    continue;
                }
                float         maxSide = 0;
                List <PointF> minBox  = GetMiniBox(contours[i], out maxSide);
                if (maxSide < maxSideThresh)
                {
                    continue;
                }
                double score = GetScore(contours[i], predMat);
                if (score < boxScoreThresh)
                {
                    continue;
                }
                List <Point> clipBox = Unclip(minBox, unClipRatio);
                if (clipBox == null)
                {
                    continue;
                }

                List <PointF> clipMinBox = GetMiniBox(clipBox, out maxSide);
                if (maxSide < maxSideThresh + 2)
                {
                    continue;
                }
                List <Point> finalPoints = new List <Point>();
                foreach (var item in clipMinBox)
                {
                    int x   = (int)(item.X / s.ScaleWidth);
                    int ptx = Math.Min(Math.Max(x, 0), s.SrcWidth);

                    int   y     = (int)(item.Y / s.ScaleHeight);
                    int   pty   = Math.Min(Math.Max(y, 0), s.SrcHeight);
                    Point dstPt = new Point(ptx, pty);
                    finalPoints.Add(dstPt);
                }

                TextBox textBox = new TextBox();
                textBox.Score  = (float)score;
                textBox.Points = finalPoints;
                rsBoxes.Add(textBox);
            }
            rsBoxes.Reverse();
            return(rsBoxes);
        }
Esempio n. 6
0
        private static List <TextBox> GetTextBoxes(DisposableNamedOnnxValue[] outputTensor, int rows, int cols, ScaleParam s, float boxScoreThresh, float boxThresh, float unClipRatio)
        {
            float          minArea = 3.0f;
            List <TextBox> rsBoxes = new List <TextBox>();

            float[]     outputData = outputTensor[0].AsEnumerable <float>().ToArray();
            List <byte> norf       = new List <byte>();

            foreach (float data in outputData)
            {
                int val = data > boxThresh ? 255 : 0;
                norf.Add((byte)val);
            }
            Mat fMapMat = new Mat(rows, cols, DepthType.Cv32F, 1);

            fMapMat.SetTo(outputData);
            Console.WriteLine(fMapMat);

            Mat norfMapMat = new Mat(rows, cols, DepthType.Cv8U, 1);

            norfMapMat.SetTo(norf.ToArray());
            Console.WriteLine(norfMapMat);

            VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();

            CvInvoke.FindContours(norfMapMat, contours, null, RetrType.List, ChainApproxMethod.ChainApproxSimple);
            for (int i = 0; i < contours.Size; i++)
            {
                float         minEdgeSize = 0;
                List <PointF> box         = GetMiniBox(contours[i], out minEdgeSize);
                if (minEdgeSize < minArea)
                {
                    continue;
                }
                double score = GetScore(contours[i], fMapMat);
                if (score < boxScoreThresh)
                {
                    continue;
                }
                List <Point> newBox = Unclip(box, unClipRatio);
                if (newBox == null)
                {
                    continue;
                }

                List <PointF> minBox = GetMiniBox(newBox, out minEdgeSize);
                if (minEdgeSize < minArea + 2)
                {
                    continue;
                }
                List <Point> finalPoints = new List <Point>();
                foreach (var item in minBox)
                {
                    int x   = (int)(item.X / s.ScaleWidth);
                    int ptx = Math.Min(Math.Max(x, 0), s.SrcWidth);

                    int   y     = (int)(item.Y / s.ScaleHeight);
                    int   pty   = Math.Min(Math.Max(y, 0), s.SrcHeight);
                    Point dstPt = new Point(ptx, pty);
                    finalPoints.Add(dstPt);
                }

                TextBox textBox = new TextBox();
                textBox.Score  = (float)score;
                textBox.Points = finalPoints;
                rsBoxes.Add(textBox);
            }
            rsBoxes.Reverse();
            return(rsBoxes);
        }