예제 #1
0
        public List <Rectangle> GetAllRects()
        {
            var list = new List <Rectangle>();

            //定位点
            list.Add(this.FixedPoint.LeftTop.Outer);
            list.Add(this.FixedPoint.LeftTop.Inner);
            list.Add(this.FixedPoint.RightTop.Outer);
            list.Add(this.FixedPoint.RightTop.Inner);
            list.Add(this.FixedPoint.LeftBottom.Outer);
            list.Add(this.FixedPoint.LeftBottom.Inner);
            list.Add(this.FixedPoint.RightBottom.Outer);
            list.Add(this.FixedPoint.RightBottom.Inner);
            //偏移块
            this.OffsetAreas.ForEach(a =>
            {
                list.Add(a.Area);
                list.AddRange(CVHelper.MoveRects(a.OffsetList, a.Area.X, a.Area.Y));
            });
            //选项区域
            this.OptionAreaList.ForEach(a =>
            {
                list.Add(a.Area);
                foreach (var item in a.Options.Values)
                {
                    list.AddRange(CVHelper.MoveRects(item, a.Area.X, a.Area.Y));
                }
            });
            return(list);
        }
예제 #2
0
        private void Btn_regMult_Click(object sender, EventArgs e)
        {
            CVHelper commonUse = new CVHelper();

            foreach (var filePath in this.multSelectPicPathList)
            {
                try
                {
                    var bitmap   = new Bitmap(filePath);
                    var rectList = commonUse.GetRectListFromBitmap(bitmap, Convert.ToInt32(this.minNum.Value), Convert.ToInt32(this.maxNum.Value), 0, 0, true, 2);
                    Mat src      = new Image <Bgr, byte>(bitmap).Mat;

                    foreach (var item in rectList)
                    {
                        CvInvoke.Rectangle(src, item, new MCvScalar(0, 0, 255));
                    }

                    commonUse.SaveMat(src, Path.GetFileName(filePath), false);

                    this.successNum++;
                }
                catch (Exception)
                {
                    this.failNum++;
                }
                finally
                {
                    this.lbl_regResul.Text   = this.failNum == 0?"":$"失败数量:{this.failNum}";
                    this.lbl_picNumInfo.Text = $"选择张数:{this.successNum}/{this.multSelectPicPathList?.Length}";
                }
            }
        }
예제 #3
0
        private void Btn_paintFormRect_Click(object sender, EventArgs e)
        {
            //for (int i = 0; i < 6; i++)
            //{
            //    Random r = new Random();
            //    var index= r.Next(0, Form1.OrginalRectList.Count - 1);
            //    Form1.OrginalRectList.RemoveAt(index);
            //}
            Console.WriteLine(Form1.OrginalRectList.Count);
            //Form1.OrginalRectList.RemoveAt(0);
            //Form1.OrginalRectList.RemoveAt(Form1.OrginalRectList.Count - 1);
            CVHelper common   = new CVHelper();
            var      tempList = common.FillFull(Form1.OrginalRectList);

            //var tempList = Form1.OrginalRectList;
            this.picBox.RegionInfo = new RegionInfo(this.picBox.Image.Width, this.picBox.Image.Height, tempList);
            Console.WriteLine(tempList.Count);
            this.picBox.CurrentSelectedRect = this.picBox.RegionInfo;

            //画出
            Mat matOrginal = new Image <Bgr, byte>((Bitmap)this.picBox.Image).Mat;

            foreach (var item in this.picBox.CurrentSelectedRect.RectList)
            {
                CvInvoke.Rectangle(matOrginal, Rectangle.Round(item), new MCvScalar(0, 0, 255));
            }
            CVHelper commonUse = new CVHelper();

            commonUse.SaveMat(matOrginal, "获取裁剪图中的所有轮廓边在原始图中ZoomForm");
        }
예제 #4
0
 public OffsetArea NewByOffset(int offsetX, int offsetY)
 {
     return(new OffsetArea(
                CVHelper.MoveRect(this.Area, offsetX, offsetY),
                this.OffsetList,
                this.OffsetType));
 }
예제 #5
0
        private void Btn_regWrap_Click(object sender, EventArgs e)
        {
            //思路:重新调整大小(根据四个定位点),获取扫描结果的定位点,获取答案结果

            //重新获取扫描结果的定位点
            var leftTopArea  = this.OriginalPaper.FixedPoint.LeftTop.GetEnlargeOuter();
            var cutBitmap    = PictureBoxReadCard.Cut(this.OriginalBitmap, leftTopArea.X, leftTopArea.Y, leftTopArea.Width, leftTopArea.Height);
            var leftTopInner = common.GetBigRectFromBitmap(cutBitmap, 2000, 6000, leftTopArea.X, leftTopArea.Y);

            CalcOffset(this.OriginalPaper.FixedPoint.LeftTop.Inner, leftTopInner, out int offsetX, out int offsetY);
            var scanPaper = this.OriginalPaper.NewPaperByOffset(offsetX, offsetY);


            var mat = new Image <Bgr, byte>(this.OriginalBitmap).Mat;
            //通过透视调整大小
            List <PointF> srcPoints = scanPaper.FixedPoint.GetPointsByClockwise();
            List <PointF> desPoints = new List <PointF>()
            {
                CVHelper.PointToPointF(scanPaper.FixedPoint.LeftTop.Inner.Location)
            };
            //右上
            var rightTopArea   = scanPaper.FixedPoint.RightTop.Outer;
            var rightTopBitmap = PictureBoxReadCard.Cut(this.OriginalBitmap, rightTopArea);
            var rightTopInner  = common.GetBigRectFromBitmap(rightTopBitmap, 2000, 6000, rightTopArea.X, rightTopArea.Y);

            desPoints.Add(CVHelper.PointToPointF(rightTopInner.Location));
            //右下
            var rightBottomArea   = scanPaper.FixedPoint.RightBottom.Outer;
            var rightBottomBitmap = PictureBoxReadCard.Cut(this.OriginalBitmap, rightBottomArea);
            var rightBottomInner  = common.GetBigRectFromBitmap(rightBottomBitmap, 2000, 6000, rightBottomArea.X, rightBottomArea.Y);

            desPoints.Add(CVHelper.PointToPointF(rightBottomInner.Location));
            //左下
            var leftBottomArea   = scanPaper.FixedPoint.LeftBottom.Outer;
            var leftBottomBitmap = PictureBoxReadCard.Cut(this.OriginalBitmap, leftBottomArea);
            var leftBottomInner  = common.GetBigRectFromBitmap(leftBottomBitmap, 2000, 6000, leftBottomArea.X, leftBottomArea.Y);

            desPoints.Add(CVHelper.PointToPointF(leftBottomInner.Location));

            //计算透视矩阵
            Mat data = CvInvoke.GetPerspectiveTransform(desPoints.ToArray(), srcPoints.ToArray());
            //进行透视操作
            //Mat src_gray = new Mat();
            Mat mat_Perspective = new Mat();

            CvInvoke.WarpPerspective(mat, mat_Perspective, data, this.OriginalBitmap.Size);

            //根据偏移块进行调整
            scanPaper = CalPaperByOffsetS(scanPaper, mat_Perspective.Bitmap);

            PaperRegResultShowForm.DrawPaperRect(mat_Perspective, scanPaper);


            this.picSrc.LoadImage(mat_Perspective.Bitmap);

            //保存
            string calOffsetStr = this.IsCalOffset.Checked ? "并模块偏移" : "";

            common.SaveMat(mat_Perspective, $"试卷结果校正透视后{calOffsetStr}在扫描模板中显示");
        }
예제 #6
0
        private void Btn_validate2_Click(object sender, EventArgs e)
        {
            //思路获取偏移量,
            List <PointF> srcPoints = this.OriginalPaper.FixedPoint.GetPointsByClockwise();
            List <PointF> desPoints = new List <PointF>();
            //重新获取扫描结果的全部定位点-》重新调整大小(根据四个定位点透视)
            //左上
            var leftTopArea  = this.OriginalPaper.FixedPoint.LeftTop.GetEnlargeOuter();
            var cutBitmap    = PictureBoxReadCard.Cut(this.OriginalBitmap, leftTopArea.X, leftTopArea.Y, leftTopArea.Width, leftTopArea.Height);
            var leftTopInner = common.GetBigRectFromBitmap(cutBitmap, 500, 6000, leftTopArea.X, leftTopArea.Y);

            desPoints.Add(leftTopInner.Location);
            //右上
            var rightTopArea   = this.OriginalPaper.FixedPoint.RightTop.GetEnlargeOuter();
            var rightTopBitmap = PictureBoxReadCard.Cut(this.OriginalBitmap, rightTopArea);
            var rightTopInner  = common.GetBigRectFromBitmap(rightTopBitmap, 500, 6000, rightTopArea.X, rightTopArea.Y);

            desPoints.Add(CVHelper.PointToPointF(rightTopInner.Location));
            //右下
            var rightBottomArea   = this.OriginalPaper.FixedPoint.RightBottom.GetEnlargeOuter();
            var rightBottomBitmap = PictureBoxReadCard.Cut(this.OriginalBitmap, rightBottomArea);
            var rightBottomInner  = common.GetBigRectFromBitmap(rightBottomBitmap, 500, 6000, rightBottomArea.X, rightBottomArea.Y);

            desPoints.Add(CVHelper.PointToPointF(rightBottomInner.Location));
            //左下
            var leftBottomArea   = this.OriginalPaper.FixedPoint.LeftBottom.GetEnlargeOuter();
            var leftBottomBitmap = PictureBoxReadCard.Cut(this.OriginalBitmap, leftBottomArea);
            var leftBottomInner  = common.GetBigRectFromBitmap(leftBottomBitmap, 500, 6000, leftBottomArea.X, leftBottomArea.Y);

            desPoints.Add(CVHelper.PointToPointF(leftBottomInner.Location));



            //计算透视矩阵
            Mat data = CvInvoke.GetPerspectiveTransform(desPoints.ToArray(), srcPoints.ToArray());
            //进行透视操作
            var mat             = new Image <Bgr, byte>(this.OriginalBitmap).Mat;
            Mat mat_Perspective = new Mat();

            CvInvoke.WarpPerspective(mat, mat_Perspective, data, this.OriginalBitmap.Size, Inter.Nearest, Warp.Default, BorderType.Constant, new MCvScalar(255, 255, 255));

            //根据偏移块进行调整
            var paper = CalPaperByOffsetS(this.OriginalPaper, mat_Perspective.Bitmap);

            PaperRegResultShowForm.DrawPaperRect(mat_Perspective, paper);


            this.picSrc.LoadImage(mat_Perspective.Bitmap);


            //保存
            string calOffsetStr = this.IsCalOffset.Checked ? "并模块偏移" : "";

            common.SaveMat(mat_Perspective, $"试卷结果直接透视后{calOffsetStr}在扫描模板中显示");
        }
예제 #7
0
        private void Btn_percentTest_Click(object sender, EventArgs e)
        {
            CVHelper common = new CVHelper();

            Rectangle r1 = new Rectangle(1, 1, 200, 200);
            Rectangle r2 = new Rectangle(2, 2, 190, 190);

            var percent = common.DecideOverlap(r2, r1, out Rectangle maxRect);

            MessageBox.Show(percent.ToString());
        }
예제 #8
0
        private void Btn_regBrokenRect_Click(object sender, EventArgs e)
        {
            //FastDetector
            if (this.ib_middleCut.Image == null)
            {
                MessageBox.Show("裁剪图片不能为空");
                return;
            }

            CVHelper commonUse = new CVHelper();

            var rectList = commonUse.GetRectListFromBitmap(this.ib_middleCut.Image.Bitmap, 40, 600, isAutoFillFull: true, optimizeTimes: 2, isBrokenOption: true);

            //排序
            var rectListDic = commonUse.OrderRectList(rectList);

            Mat src = new Image <Bgr, byte>(ib_middleCut.Image.Bitmap).Mat;

            foreach (var item in rectList)
            {
                CvInvoke.Rectangle(src, item, new MCvScalar(0, 0, 255));
            }

            commonUse.SaveMat(src, "获取裁剪图中的所有轮廓边界提取");

            this.ib_middle.Image = src;

            //在原始图片中画出矩形框
            var orginalRectList = new List <Rectangle>();

            foreach (var item in rectList)
            {
                var tmpRect = new Rectangle(new Point(this.destRect.X + item.X, this.destRect.Y + item.Y), item.Size);
                orginalRectList.Add(tmpRect);
            }
            Mat matOrginal = new Image <Bgr, byte>(this.ib_original.Image.Bitmap).Mat;

            foreach (var item in orginalRectList)
            {
                CvInvoke.Rectangle(matOrginal, Rectangle.Round(item), new MCvScalar(0, 0, 255));
            }
            commonUse.SaveMat(matOrginal, "获取裁剪图中的所有轮廓边在原始图中");
            this.ib_result.Image = matOrginal;

            //在原始的PictureBox中画出框

            this.DrawRectInPictureBox(this.ib_original, orginalRectList);

            //
            OrginalRectList = orginalRectList;
            CutedRectList   = rectList;
        }
예제 #9
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="rectList">相对图片0,0</param>
        /// <param name="area"></param>
        /// <returns></returns>
        public static List <Rectangle> GetRectsByAreaAndCol(List <Rectangle> rectList, Rectangle area)
        {
            var list = new List <Rectangle>();

            rectList.ForEach(r =>
            {
                if (r.Y > area.Y && r.Y < area.Y + area.Height)
                {
                    list.Add(CVHelper.MoveRect(r, -area.X, -area.Y));
                }
            });

            return(list);
        }
예제 #10
0
        public static List <Rectangle> GetRectsByAreaAndRow(List <Rectangle> rectList, Rectangle area)
        {
            var list = new List <Rectangle>();

            rectList.ForEach(r =>
            {
                if (r.X > area.X && r.X < area.X + area.Width)
                {
                    list.Add(CVHelper.MoveRect(r, -area.X, -area.Y));
                }
            });

            return(list);
        }
예제 #11
0
        private void Btn_answerReg3_Click(object sender, EventArgs e)
        {
            CVHelper commonUse = new CVHelper();
            var      src       = new Image <Gray, byte>(ib_middleCut.Image.Bitmap);

            var thresholdImage = src.CopyBlank();
            int myThreshold    = 210;

            CvInvoke.Threshold(src, thresholdImage, myThreshold, 255, Emgu.CV.CvEnum.ThresholdType.BinaryInv);
            commonUse.SaveMat(thresholdImage.Mat, "二值化后");
            //思路 close -腐蚀-腐蚀-膨胀
            //形态学膨胀
            Mat mat_dilate = commonUse.MyDilate(thresholdImage.Mat, Emgu.CV.CvEnum.MorphOp.Close);

            commonUse.SaveMat(mat_dilate, "形态学膨胀");
            //mat_dilate = commonUse.MyDilate(mat_dilate, Emgu.CV.CvEnum.MorphOp.Close);
            //commonUse.SaveMat(mat_dilate, "形态学膨胀1");
            mat_dilate = commonUse.MyDilate(mat_dilate, Emgu.CV.CvEnum.MorphOp.Erode);
            commonUse.SaveMat(mat_dilate, "形态学膨胀腐蚀1");
            mat_dilate = commonUse.MyDilate(mat_dilate, Emgu.CV.CvEnum.MorphOp.Erode);
            commonUse.SaveMat(mat_dilate, "形态学膨胀腐蚀2");

            mat_dilate = commonUse.MyDilate(mat_dilate, Emgu.CV.CvEnum.MorphOp.Dilate);
            commonUse.SaveMat(mat_dilate, "形态学膨胀2");

            var image_dilate = mat_dilate.ToImage <Gray, byte>();

            List <Rectangle> validRectList = new List <Rectangle>();

            CutedRectList.ForEach(rect =>
            {
                var newRect  = new Rectangle(Math.Max(0, rect.X - 8), Math.Max(0, rect.Y - 8), rect.Width, rect.Height);
                var tmpImage = image_dilate.Copy(newRect);

                var result = GetWhiteColorPercenter(tmpImage);
                if (result > 0.2)
                {
                    validRectList.Add(rect);
                }
                commonUse.SaveMat(tmpImage.Mat, "形态学后" + result);
            });

            validRectList.ForEach(r =>
            {
                CvInvoke.Rectangle(src, r, new MCvScalar(0, 0, 255));
            });

            new CVHelper().SaveMat(src.Mat, "通过比例计算获取的答案");
            this.ib_result.Image = src;
        }
예제 #12
0
        private void Btn_offset_Click(object sender, EventArgs e)
        {
            if (ib_original.Image == null)
            {
                MessageBox.Show("请先加载图片");
                return;
            }

            var cutedBitmap = this.ib_original.GetFirstRegionRect();

            if (cutedBitmap == null)
            {
                MessageBox.Show("将要识别的图片不能为空");
                return;
            }

            CVHelper commonUse = new CVHelper();

            var rectList = commonUse.GetRectListFromBitmap(cutedBitmap, Convert.ToInt32(this.minNum.Value), Convert.ToInt32(this.maxNum.Value), 0, 0, false, 0);

            //排序
            //var rectListDic = commonUse.OrderRectList(rectList);

            Mat src = new Image <Bgr, byte>(cutedBitmap).Mat;

            foreach (var item in rectList)
            {
                CvInvoke.Rectangle(src, item, new MCvScalar(0, 0, 255));
            }

            commonUse.SaveMat(src, "偏移量测试定位点");

            this.ib_result.Image = src.Bitmap;


            if (rectList?.Count == 0)
            {
                return;
            }

            this.Paper.OffsetAreas.Add(new OffsetArea(this.ib_original.RegionInfo.RectList.FirstOrDefault(), rectList, this.ckb_isRow.Checked? OffsetType.Rows: OffsetType.Column));
        }
예제 #13
0
        private static bool ValidateColumn(Rectangle area, List <Rectangle> offsetList)
        {
            /// 偏移量区域,规范,最高线和最低线距离最近的偏移测量点大于1.5个偏移高度
            /// 左右距离需要大于0.6个偏移点宽度
            bool isValidate = true;


            var averageWidth  = offsetList.Average(r => r.Width);
            var averageHeight = offsetList.Average(r => r.Height);
            var maxRect       = CVHelper.GetMaxRect(offsetList);

            if (averageWidth * 0.6 > maxRect.X || area.Width - averageWidth * 0.6 < maxRect.X + maxRect.Width ||
                averageHeight * 1.5 > maxRect.Y || area.Height < maxRect.Y + maxRect.Height + averageHeight * 1.5)
            {
                return(false);
            }


            return(isValidate);
        }
예제 #14
0
        private static bool ValidateRow(Rectangle area, List <Rectangle> offsetList)
        {
            //横向的,上下0.4个宽度,左右大于0.8个高度度即可
            bool isValidate = true;

            var averageWidth  = offsetList.Average(r => r.Width);
            var averageHeight = offsetList.Average(r => r.Height);
            var maxRect       = CVHelper.GetMaxRect(offsetList);


            if (maxRect.X < 0.4 * averageWidth || maxRect.X + maxRect.Width + 0.4 * averageWidth > area.Width ||
                maxRect.Y < 0.8 * averageHeight || maxRect.Y + maxRect.Height + 0.8 * averageHeight > area.Height)
            {
                return(false);
            }



            return(isValidate);
        }
예제 #15
0
        private void Btn_reg2All_Click(object sender, EventArgs e)
        {
            if (this.ib_original.Image == null)
            {
                MessageBox.Show("原始图片不能为空");
                return;
            }

            CVHelper commonUse = new CVHelper();


            var centerList = commonUse.GetCenterPointListFromBitmap(this.ib_original.Image.Bitmap, (int)this.num_threshold.Value);//300分辨率用200,150分辨率用45
            Mat tmpMat     = new Image <Bgr, byte>(this.ib_original.Image.Bitmap).Mat;

            centerList.ForEach(p =>
            {
                CvInvoke.Circle(tmpMat, p, 6, new MCvScalar(0, 0, 255), 2);
            });

            this.ib_result.Image = tmpMat;
        }
예제 #16
0
        public OptionArea NewByOffsetS(List <OffsetInfo> offsetInfos)
        {
            var newOptionArea = new OptionArea()
            {
                Options        = this.Options,
                WidthInterval  = this.WidthInterval,
                HeightInterval = this.HeightInterval
            };
            var offsetCol = OffsetInfo.GetNearestByColumn(offsetInfos, this.Area);
            var offsetRow = OffsetInfo.GetNearestByRow(offsetInfos, this.Area);
            int xAvgCount = 0, yavgCount = 0;

            xAvgCount += offsetCol.offsetX == 0 ? 0 : 1;
            xAvgCount += offsetRow.offsetX == 0 ? 0 : 1;
            yavgCount += offsetCol.offsetY == 0 ? 0 : 1;
            yavgCount += offsetRow.offsetY == 0 ? 0 : 1;

            newOptionArea.Area = CVHelper.MoveRect(this.Area, (offsetCol.offsetX + offsetRow.offsetX), (offsetCol.offsetY + offsetRow.offsetY));

            return(newOptionArea);
        }
예제 #17
0
        /// <summary>
        /// 计算占用比
        /// </summary>
        /// <param name="image">所在区域的图片</param>
        public void CalAreaPercent(Image <Gray, byte> image, string saveName = "")
        {
            //image.Save("ssss.jpg");
            int maxX = image.Width, maxY = image.Height;
            int width = this.Rectangle.Width, height = this.Rectangle.Height;
            int xExtensionDis = width / CVArea.extensionWBase, yExtensionDis = height / CVArea.extensionHBase;
            var extensionRect = new Rectangle(Math.Max(0, this.Rectangle.X - xExtensionDis), Math.Max(0, this.Rectangle.Y - yExtensionDis), this.Rectangle.Width + 2 * xExtensionDis, this.Rectangle.Height + 2 * yExtensionDis);


            var newRect = new Rectangle(new Point(this.Rectangle.X - extensionRect.X, this.Rectangle.Y - extensionRect.Y), this.Rectangle.Size);

            if (extensionRect.Right > maxX)
            {
                extensionRect.Width -= extensionRect.Right - maxX;
            }
            if (extensionRect.Bottom > maxY)
            {
                extensionRect.Height -= extensionRect.Bottom - maxY;
            }
            using (var extOptionRectImage = image.Copy(extensionRect))
            {
                var thresholdMat = extOptionRectImage.CopyBlank().Mat;
                //CvInvoke.Threshold(CVHelper.Filter( extOptionRectImage.Mat), thresholdMat, this.Threshold, 255, Emgu.CV.CvEnum.ThresholdType.BinaryInv);

                CvInvoke.Threshold(extOptionRectImage, thresholdMat, this.Threshold, 255, Emgu.CV.CvEnum.ThresholdType.BinaryInv);

                Mat mat_dilate = CVHelper.MyDilateS(thresholdMat, Emgu.CV.CvEnum.MorphOp.Open);
                mat_dilate = CVHelper.MyDilateS(mat_dilate, Emgu.CV.CvEnum.MorphOp.Dilate);

                new CVHelper().SaveMat(extOptionRectImage.Mat, $"原始选项原图行学后-{saveName}");
                new CVHelper().SaveMat(mat_dilate, $"异常选项原图行学后-{saveName}");
                using (var originalImage = this.Max(mat_dilate.ToImage <Gray, byte>(), newRect))
                {
                    this.AreaPercent = CVHelper.GetWhiteColorPercenterS(originalImage);
                    Console.WriteLine($"{this.Threshold}下的白色所占比:{this.AreaPercent}");
                }
            }
        }
예제 #18
0
        private void Btn_reg_Click(object sender, EventArgs e)
        {
            if (this.picSrc.Image == null)
            {
                MessageBox.Show("请先加载图片");
                return;
            }

            CVHelper         commonUse   = new CVHelper();
            List <Rectangle> posRectList = new List <Rectangle>();

            for (int i = 0; i < this.picSrc.RegionInfo.RectList.Count; i++)
            {
                var tmpRect = this.picSrc.RegionInfo.RectList[i];

                var cutedBitmap = PictureBoxReadCard.Cut(this.picSrc.orignalBitmap, tmpRect.X, tmpRect.Y, tmpRect.Width, tmpRect.Height);

                if (cutedBitmap == null)
                {
                    MessageBox.Show("将要识别的图片不能为空");
                    return;
                }



                var rectList = commonUse.GetRectListFromBitmap(cutedBitmap, 200, 6000, tmpRect.X, tmpRect.Y, false, 0);

                posRectList.AddRange(rectList);
            }

            //获取定位点信息
            var dic       = commonUse.OrderRectList(posRectList, true, false);
            var tempList1 = dic[1].OrderBy(r => r.X).ToList();
            var tempList2 = dic[2].OrderBy(r => r.X).ToList();

            //四个点
            var p1 = tempList1[0];
            var p2 = new Point(tempList1[1].X, p1.Y);

            lbl1.Text = $"左上角:X:{tempList1[0].X},Y:{tempList1[0].Y},Width:{tempList1[0].Width},Height:{tempList1[0].Height}";
            lbl2.Text = $"右上角:X:{tempList1[1].X},Y:{tempList1[1].Y},Width:{tempList1[1].Width},Height:{tempList1[1].Height}";
            lbl3.Text = $"左下角:X:{tempList2[0].X},Y:{tempList2[0].Y},Width:{tempList2[0].Width},Height:{tempList2[0].Height}";
            lbl4.Text = $"右下角:X:{tempList2[1].X},Y:{tempList2[1].Y},Width:{tempList2[1].Width},Height:{tempList2[1].Height}";

            var width  = tempList1[1].X - tempList1[0].X;
            var height = tempList2[0].Y - tempList1[0].Y;

            lbl5.Text = $"W:{width},H:{height}";

            Console.WriteLine($"{lbl1.Text};{lbl5.Text}");

            //画出所有定位点
            //排序
            //var rectListDic = commonUse.OrderRectList(rectList);

            using (Mat src = new Image <Bgr, byte>((Bitmap)this.picSrc.orignalBitmap.Clone()).Mat)
            {
                foreach (var item in posRectList)
                {
                    CvInvoke.Rectangle(src, item, new MCvScalar(0, 0, 255));
                }

                CvInvoke.Line(src, tempList1[0].Location, tempList1[1].Location, new MCvScalar(0, 0, 255), 2);
                CvInvoke.Line(src, tempList2[0].Location, tempList1[0].Location, new MCvScalar(0, 0, 255), 2);
                CvInvoke.PutText(src, lbl5.Text, tempList1[0].Location, FontFace.HersheyComplex, 3, new MCvScalar(0, 0, 255), 2);


                commonUse.SaveMat(src, "定位点画出后");
            }
        }
예제 #19
0
        private void BtStart_Click(object sender, EventArgs e)
        {
            //this.Start();

            CVHelper commonUse = new CVHelper();

            if (this.ib_middleCut.Image != null)
            {
                //Mat src1 = new Image<Bgr, byte>(ib_middleCut.Image.Bitmap).Mat;
                Mat src = new Image <Bgr, byte>(ib_middleCut.Image.Bitmap).Mat;// new Mat();

                //CvInvoke.PyrMeanShiftFiltering(src1, src, 25, 10, 1, new MCvTermCriteria(5, 1));
                //commonUse.SaveMat(src, "降噪后");
                //commonUse.SaveMat(src1, "降噪后原始");

                Mat dst      = new Mat();
                Mat src_gray = new Mat();
                CvInvoke.CvtColor(src, src_gray, Emgu.CV.CvEnum.ColorConversion.Bgr2Gray);
                //存储灰度图片
                commonUse.SaveMat(src_gray, "灰度");

                #region 二值化
                //二值化
                Mat mat_threshold = new Mat();
                int myThreshold   = Convert.ToInt32(num_threshold.Value);
                CvInvoke.Threshold(src_gray, mat_threshold, myThreshold, 255, Emgu.CV.CvEnum.ThresholdType.BinaryInv);
                commonUse.SaveMat(mat_threshold, "二值化");
                //形态学膨胀
                Mat mat_dilate = commonUse.MyDilate(mat_threshold, Emgu.CV.CvEnum.MorphOp.Close);
                commonUse.SaveMat(mat_dilate, "形态学膨胀");
                mat_dilate = commonUse.MyDilate(mat_threshold, Emgu.CV.CvEnum.MorphOp.Open);
                commonUse.SaveMat(mat_dilate, "形态学膨胀1");
                mat_dilate = commonUse.MyDilate(mat_threshold, Emgu.CV.CvEnum.MorphOp.Erode);
                commonUse.SaveMat(mat_dilate, "形态学膨胀");
                #endregion

                //边缘检测
                CvInvoke.Canny(mat_dilate, dst, Convert.ToInt32(this.num_Min.Value), Convert.ToInt32(this.num_Max.Value), Convert.ToInt32(this.num_apertureSize.Value));
                commonUse.SaveMat(dst, "边缘检测");

                //寻找答题卡矩形边界(所有的矩形)
                VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();      //创建VectorOfVectorOfPoint数据类型用于存储轮廓

                VectorOfVectorOfPoint validContours = new VectorOfVectorOfPoint(); //有效的,所有的选项的

                CvInvoke.FindContours(dst, contours, null, Emgu.CV.CvEnum.RetrType.Ccomp,
                                      Emgu.CV.CvEnum.ChainApproxMethod.ChainApproxSimple);//提取轮廓

                //CvInvoke.ApproxPolyDP

                //画出所有矩形
                Mat middleMat = new Image <Bgr, byte>(this.ib_middleCut.Image.Bitmap).Mat;
                CvInvoke.DrawContours(middleMat, contours, -1, new MCvScalar(0, 0, 255), 1);
                this.ib_result.Image = middleMat;
                commonUse.SaveMat(middleMat, "画出所有轮廓的");


                //获取矩形边界另一种方法
                //var tempRect=CvInvoke.BoundingRectangle(contours);
                //CvInvoke.Rectangle(src, tempRect, new MCvScalar(0, 0, 255));
                //this.ib_middle.Image = src;
                //return;


                //打印所以后矩形面积和周长
                int size = contours.Size;
                //for (int i = 0; i < size; i++)
                //{
                //    var item = contours[i];
                //    var tempArea = CvInvoke.ContourArea(item);
                //    var tempArc = CvInvoke.ArcLength(item, true);
                //    Console.WriteLine($"面积:{tempArea};周长:{tempArc}"); ;
                //    if (tempArea > 200 && tempArea<1000)
                //    {
                //        validContours.Push(item);
                //    }
                //}

                //画出符合要求的所有矩形
                //CvInvoke.DrawContours(src, validContours, -1, new MCvScalar(0, 0, 255), 1);

                //var rectList = commonUse.GetRectList(validContours);
                //foreach (var item in rectList)
                //{
                //    //宽高比例不能>4或者0.24
                //    if (item.Width * 1.0 / item.Height > 4 || item.Width * 1.0 / item.Height < 0.25)
                //    {
                //        continue;
                //    }
                //    CvInvoke.Rectangle(src, item, new MCvScalar(0, 0, 255));
                //}

                //commonUse.SaveMat(src, "带有所有轮廓边界的");

                //this.ib_middle.Image = src;
            }
            else
            {
                MessageBox.Show("请先加载图片");
            }
        }
예제 #20
0
        private void Btn_reg_Click(object sender, EventArgs e)
        {
            if (ib_original.Image == null)
            {
                MessageBox.Show("请先加载图片");
                return;
            }

            var cutedBitmap = this.ib_original.GetFirstRegionRect();

            if (cutedBitmap == null)
            {
                MessageBox.Show("将要识别的图片不能为空");
                return;
            }

            CVHelper commonUse = new CVHelper();

            var rectList = commonUse.GetRectListFromBitmap(cutedBitmap, Convert.ToInt32(this.minNum.Value), Convert.ToInt32(this.maxNum.Value), 0, 0, true, 2);

            //排序
            //var rectListDic = commonUse.OrderRectList(rectList);

            Mat src = new Image <Bgr, byte>(cutedBitmap).Mat;

            foreach (var item in rectList)
            {
                CvInvoke.Rectangle(src, item, new MCvScalar(0, 0, 255));
            }

            commonUse.SaveMat(src, "获取裁剪图中的所有轮廓边界提取");

            this.ib_result.Image = src.Bitmap;

            //填充试卷内容
            if (rectList?.Count == 0)
            {
                return;
            }

            //填充试卷内容
            var firstRect = this.ib_original.RegionInfo.RectList.FirstOrDefault();

            if (!isFixedPointReg)
            {
                commonUse.CaculateRectInfo(rectList, out double averageWidth, out double averageHeight, out double intervalWidth, out double intervalHeight);
                this.Paper.OptionAreaList.Add(new OptionArea()
                {
                    Area = firstRect, Options = commonUse.OrderRectList(rectList, true, false), WidthInterval = (int)intervalWidth, HeightInterval = (int)intervalHeight
                });
            }
            else
            {
                var fixedPointDetail = rectList.FirstOrDefault();
                fixedPointDetail.X += firstRect.X;
                fixedPointDetail.Y += firstRect.Y;

                var fixedType = this.GetFixedType(this.ib_original.orignalBitmap.Width, this.ib_original.orignalBitmap.Height, fixedPointDetail);
                switch (fixedType)
                {
                case FixedType.LeftTop:
                    this.Paper.FixedPoint.LeftTop = new FixedPointDetail()
                    {
                        Outer = firstRect, Inner = fixedPointDetail
                    };
                    break;

                case FixedType.RightTop:
                    this.Paper.FixedPoint.RightTop = new FixedPointDetail()
                    {
                        Outer = firstRect, Inner = fixedPointDetail
                    };

                    break;

                case FixedType.LeftBottom:
                    this.Paper.FixedPoint.LeftBottom = new FixedPointDetail()
                    {
                        Outer = firstRect, Inner = fixedPointDetail
                    };

                    break;

                case FixedType.RightBottom:
                    this.Paper.FixedPoint.RightBottom = new FixedPointDetail()
                    {
                        Outer = firstRect, Inner = fixedPointDetail
                    };

                    break;

                default:
                    break;
                }
            }
        }
예제 #21
0
        public Paper NewPaperByOffsetS(List <OffsetArea> newOffsetAreaList)
        {
            var paper = new Paper();

            //列偏移模块
            var newColOffsetList      = new List <Rectangle>(); //相对0,0
            var originalColOffsetList = new List <Rectangle>(); //相对0,0
            //行偏移模块
            var newRowOffsetList      = new List <Rectangle>(); //相对0,0
            var originalRowOffsetList = new List <Rectangle>(); //相对0,0

            newOffsetAreaList.ForEach(a =>
            {
                if (a.OffsetType == OffsetType.Column)
                {
                    newColOffsetList.AddRange(CVHelper.MoveRects(a.OffsetList, a.Area.X, a.Area.Y));
                }
                else
                {
                    newRowOffsetList.AddRange(CVHelper.MoveRects(a.OffsetList, a.Area.X, a.Area.Y));
                }
            });
            //tmpColOffsetList = tmpColOffsetList.OrderBy(r => r.Y).ToList();
            this.OffsetAreas.ForEach(a =>
            {
                if (a.OffsetType == OffsetType.Column)
                {
                    originalColOffsetList.AddRange(CVHelper.MoveRects(a.OffsetList, a.Area.X, a.Area.Y));
                }
                else
                {
                    originalRowOffsetList.AddRange(CVHelper.MoveRects(a.OffsetList, a.Area.X, a.Area.Y));
                }
            });
            //originalColOffsetList = originalColOffsetList.OrderBy(r => r.Y).ToList();
            var offsetInfoList = OffsetInfo.NewListByColumn(originalColOffsetList, newColOffsetList);

            offsetInfoList.AddRange(OffsetInfo.NewListByRow(originalRowOffsetList, newRowOffsetList));

            //定位点 暂不处理
            paper.FixedPoint = this.FixedPoint.NewFixedPointByOffset(0, 0);

            //选项区域
            this.OptionAreaList.ForEach(o =>
            {
                paper.OptionAreaList.Add(o.NewByOffsetS(offsetInfoList));
            });
            //偏移量
            this.OffsetAreas.ForEach(a =>
            {
                if (a.OffsetType == OffsetType.Column)
                {
                    var tmpList = OffsetInfo.GetRectsByAreaAndCol(newColOffsetList, a.Area);
                    paper.OffsetAreas.Add(new OffsetArea(a.Area, tmpList, a.OffsetType));
                }
                else
                {
                    var tmpList = OffsetInfo.GetRectsByAreaAndRow(newRowOffsetList, a.Area);
                    paper.OffsetAreas.Add(new OffsetArea(a.Area, tmpList, a.OffsetType));
                }
            });


            return(paper);
        }
예제 #22
0
        public void Start()
        {
            CVHelper commonUse = new CVHelper();

            if (ib_original.Image != null)
            {
                //Mat src = new Image<Bgr, byte>(ib_original.Image.Bitmap).Mat;
                Mat src = ib_original.Image.GetInputArray().GetMat();
                //1.获取当前图像的最大矩形边界
                VectorOfVectorOfPoint max_contour = commonUse.GetBoundaryOfPic(src);

                //2.对图像进行矫正
                Mat mat_Perspective = commonUse.MyWarpPerspective(src, max_contour);
                //规范图像大小
                CvInvoke.Resize(mat_Perspective, mat_Perspective, new Size(590, 384), 0, 0, Emgu.CV.CvEnum.Inter.Cubic);
                //3.二值化处理(大于阈值取0,小于阈值取255。其中白色为0,黑色为255)
                Mat mat_threshold = new Mat();
                int myThreshold   = Convert.ToInt32(num_threshold.Value);
                CvInvoke.Threshold(mat_Perspective, mat_threshold, myThreshold, 255, Emgu.CV.CvEnum.ThresholdType.BinaryInv);
                //ib_middle.Image = mat_threshold;

                //形态学膨胀
                Mat mat_dilate = commonUse.MyDilate(mat_threshold);
                //ib_middle.Image = mat_dilate;

                //筛选长宽比大于2的轮廓
                VectorOfVectorOfPoint selected_contours = commonUse.GetUsefulContours(mat_dilate, 1);
                //画出轮廓
                Mat color_mat = commonUse.DrawContours(mat_Perspective, selected_contours);
                ib_middle.Image = color_mat;


                ib_result.Image = mat_Perspective;
                //准考证号,x=230+26*5,y=40+17*10
                //tb_log.Text = commonUse.GetValueAndDrawGrid(ib_result, selected_contours, 230, 26, 5, 40, 17, 10, "准考证号:");

                ////答题区1-5题,x=8+25*5,y=230+16*4
                //tb_log.Text += commonUse.GetValueAndDrawGrid(ib_result, selected_contours, 8, 25, 5, 230, 16, 4, "1-5:");

                ////答题区6-10题,x=159+25*5,y=230+16*4
                //tb_log.Text += commonUse.GetValueAndDrawGrid(ib_result, selected_contours, 159, 25, 5, 230, 16, 4, "6-10:");

                ////答题区11-15题,x=310+25*5,y=230+16*4
                //tb_log.Text += commonUse.GetValueAndDrawGrid(ib_result, selected_contours, 310, 25, 5, 230, 16, 4, "11-15:");

                ////答题区16-20题,x=461+25*5,y=230+16*4
                //tb_log.Text += commonUse.GetValueAndDrawGrid(ib_result, selected_contours, 461, 25, 5, 230, 16, 4, "16-20:");

                ////答题区21-25题,x=8+25*5,y=312+16*4
                //tb_log.Text += commonUse.GetValueAndDrawGrid(ib_result, selected_contours, 8, 25, 5, 312, 16, 4, "21-25:");

                ////答题区26-30题,x=159+25*5,y=312+16*4
                //tb_log.Text += commonUse.GetValueAndDrawGrid(ib_result, selected_contours, 159, 25, 5, 312, 16, 4, "26-30:");

                ////答题区31-35题,x=310+25*5,y=312+16*4
                //tb_log.Text += commonUse.GetValueAndDrawGrid(ib_result, selected_contours, 310, 25, 5, 312, 16, 4, "31-35:");
            }
            else
            {
                MessageBox.Show("请先加载图片");
            }
        }
예제 #23
0
        /// <summary>
        /// 该区域的图片
        /// </summary>
        /// <param name="src"></param>
        /// <param name="myThreshold"></param>
        public void Recognition(Image <Gray, byte> src, int myThreshold = 180)
        {
            ////思路:第一次正常识别--->初步智能筛选---->再次智能筛选---》再次智能(如果未选,继续多次,如果多选)
            ////var src = new Image<Gray, byte>(bitmap);

            var thresholdMat = src.CopyBlank().Mat;

            CvInvoke.Threshold(src, thresholdMat, myThreshold, 255, Emgu.CV.CvEnum.ThresholdType.BinaryInv);

            new CVHelper().SaveMat(src.Mat, "原始的");
            //思路 open -膨胀
            //形态学膨胀
            Mat mat_dilate = CVHelper.MyDilateS(thresholdMat, Emgu.CV.CvEnum.MorphOp.Open);

            new CVHelper().SaveMat(mat_dilate, "Open行学");
            mat_dilate = CVHelper.MyDilateS(mat_dilate, Emgu.CV.CvEnum.MorphOp.Dilate);
            new CVHelper().SaveMat(mat_dilate, "Dilate行学");

            //补充偏移置换
            //src = Max(src);

            foreach (var question in this.CVQuestionList)
            {
                for (int i = 0; i < question.OptionRectList.Count; i++)
                {
                    var cvRect = question.OptionRectList[i];
                    //计算平均灰度值
                    //var fileName = $"{this.Name}第";
                    cvRect.CalVagGrayValueAndHist(src);


                    //计算面积比
                    cvRect.CalAreaPercent(src);
                    if (cvRect.AreaPercent > CVArea.valAreaPercent)
                    {
                        question.Results.Add(i);
                    }
                }
            }
            //打印初步识别的
            //new CommonUse().DrawRectCircleAndSave(src.Mat.Clone(), this.GetRectList(), $"{this.Name}-初步识别的", -this.Area.X, -this.Area.Y, points: this.GetResultPointList(false));
            this.DrawDetail(src.Clone(), this.Name);
            //初步筛选
            this.Check();
            new CVHelper().DrawRectCircleAndSave(src.Mat.Clone(), this.GetRectList(false), $"{this.Name}-初步筛选结果", points: this.GetResultPointList(false));

            //再次智能处理异常的
            this.CVQuestionList.ForEach(q =>
            {
                this.IntelligentChose(src, q);

                int total = 11;
                for (int i = 2; i <= total; i++)
                {
                    if (q.ResultStatus == QuestionResultStatus.Right)
                    {
                        break;
                    }
                    else if (q.ResultStatus == QuestionResultStatus.Absence)
                    {
                        q.IntelligentChoseByAbsence(src, i);
                    }
                }
            });

            //再次通过神经网络识别

            //this.RecognitionByML();
            for (int i = 0; i < this.CVQuestionList.Count; i++)
            {
                var q = this.CVQuestionList[i];
                if (q.ResultStatus != QuestionResultStatus.Absence)
                {
                    continue;
                }
                //针对只有一个的选框的不适用人工智能网络)
                //if (this.GetOptionCount() == 1)
                //{
                //    continue;
                //}

                for (int j = 0; j < q.OptionRectList.Count; j++)
                {
                    var rect = q.OptionRectList[j];
                    if (rect.AreaPercent == 0 && rect.AvgGrayValue == 0)
                    {
                        continue;
                    }
                    //智能识别
                    var queRect = rect.Rectangle;
                    using (var copy = src.Copy(queRect))
                    {
                        var isAnswer = MLearner.IsAnswer(copy);
                        if (!q.Results.Contains(j) && isAnswer)
                        {
                            q.Results.Add(j);
                        }
                        new CVHelper().SaveMat(copy.Mat, "需要智能之别的" + isAnswer, dictory: "MLReg\\");
                    }
                }
            }

            //脱离原rectangle,再次智能筛选
            try {
                DoMLAgain(src);
            }
            catch (Exception ex)
            {
                Console.WriteLine("再次智能之别是,发生错误");
                Console.WriteLine(ex);
            }
        }
예제 #24
0
        /// <summary>
        /// 再次智能识别
        /// </summary>
        /// <param name="src"></param>
        private void DoMLAgain(Image <Gray, byte> src)
        {
            //正对使用了偏移块还不准的区域再次识别
            if (!this.IsAbsence())
            {
                return;
            }

            var cvHelper = new CVHelper();
            var rectList = cvHelper.GetRectListFromBitmap(src.Bitmap, isAutoFillFull: true);

            if (rectList.Count != this.GetOptionCount())// || rectList.Count==1 针对只有一个的选框的不适用
            {
                return;
            }
            var rectListDic = cvHelper.OrderRectList(rectList, this.IsOrderByRow());
            var anwserDir   = new Dictionary <int, List <int> >();

            foreach (var key in rectListDic.Keys)
            {
                var queOptions = rectListDic[key];
                var tmpResult  = new List <int>();
                for (int i = 0; i < queOptions.Count; i++)
                {
                    var queRect = queOptions[i];
                    using (var copy = src.Copy(queRect))
                    {
                        var isAnswer = MLearner.IsAnswer(copy);
                        if (isAnswer)
                        {
                            tmpResult.Add(i);
                        }

#if DEBUG
                        new CVHelper().SaveMat(copy.Mat, "再次智能之别的" + isAnswer, dictory: "MLReg2\\");
#endif
                    }
                }
                anwserDir.Add(key, tmpResult);
            }
            //合并答案

            foreach (var key in anwserDir.Keys)
            {
                var result = anwserDir[key];
                if (this.CVQuestionList[key - 1].ResultStatus == QuestionResultStatus.Absence)
                {
                    this.CVQuestionList[key - 1].Results = result;
                }
            }



#if DEBUG
            //画出再次智能出来的框和识别出来的中心点
            var tmpRectList  = new List <Rectangle>();
            var tmpPointList = new List <Point>();
            foreach (var key in rectListDic.Keys)
            {
                tmpRectList.AddRange(rectListDic[key]);
                anwserDir[key].ForEach(i =>
                {
                    var rect  = rectListDic[key][i];
                    var point = rect.Location;
                    point.Offset(rect.Width / 2, rect.Height / 2);
                    tmpPointList.Add(point);
                });
            }

            cvHelper.DrawRectCircleAndSave(src.Mat, tmpRectList, "再次智能后", points: tmpPointList, dictory: "MLReg2\\");
#endif
        }
예제 #25
0
        private void Btn_anwserReg_Click(object sender, EventArgs e)
        {
            if (this.ib_middleCut.Image == null)
            {
                MessageBox.Show("裁剪图片不能为空");
                return;
            }

            CVHelper commonUse = new CVHelper();

            Mat src = new Image <Bgr, byte>(ib_middleCut.Image.Bitmap).Mat;// new Mat();

            //CvInvoke.PyrMeanShiftFiltering(src1, src, 25, 10, 1, new MCvTermCriteria(5, 1));
            //commonUse.SaveMat(src, "降噪后");
            //commonUse.SaveMat(src1, "降噪后原始");

            Mat dst      = new Mat();
            Mat src_gray = new Mat();

            CvInvoke.CvtColor(src, src_gray, Emgu.CV.CvEnum.ColorConversion.Bgr2Gray);
            //存储灰度图片
            commonUse.SaveMat(src_gray, "灰度");

            #region 二值化
            //二值化
            Mat mat_threshold = new Mat();
            int myThreshold   = Convert.ToInt32(num_threshold.Value);
            CvInvoke.Threshold(src_gray, mat_threshold, myThreshold, 255, Emgu.CV.CvEnum.ThresholdType.BinaryInv);
            commonUse.SaveMat(mat_threshold, "二值化");
            //思路 close -腐蚀-腐蚀-膨胀
            //形态学膨胀
            Mat mat_dilate = commonUse.MyDilate(mat_threshold, Emgu.CV.CvEnum.MorphOp.Close);
            commonUse.SaveMat(mat_dilate, "形态学膨胀");
            //mat_dilate = commonUse.MyDilate(mat_dilate, Emgu.CV.CvEnum.MorphOp.Close);
            //commonUse.SaveMat(mat_dilate, "形态学膨胀1");
            mat_dilate = commonUse.MyDilate(mat_dilate, Emgu.CV.CvEnum.MorphOp.Erode);
            commonUse.SaveMat(mat_dilate, "形态学膨胀腐蚀1");
            mat_dilate = commonUse.MyDilate(mat_dilate, Emgu.CV.CvEnum.MorphOp.Erode);
            commonUse.SaveMat(mat_dilate, "形态学膨胀腐蚀2");

            mat_dilate = commonUse.MyDilate(mat_dilate, Emgu.CV.CvEnum.MorphOp.Dilate);
            commonUse.SaveMat(mat_dilate, "形态学膨胀2");
            #endregion

            //边缘检测
            CvInvoke.Canny(mat_dilate, dst, Convert.ToInt32(this.num_Min.Value), Convert.ToInt32(this.num_Max.Value), Convert.ToInt32(this.num_apertureSize.Value));
            commonUse.SaveMat(dst, "边缘检测");

            //寻找答题卡矩形边界(所有的矩形)
            VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();      //创建VectorOfVectorOfPoint数据类型用于存储轮廓

            VectorOfVectorOfPoint validContours = new VectorOfVectorOfPoint(); //有效的,所有的选项的

            CvInvoke.FindContours(dst, contours, null, Emgu.CV.CvEnum.RetrType.Ccomp,
                                  Emgu.CV.CvEnum.ChainApproxMethod.ChainApproxSimple, new Point(8, 8));//提取轮廓

            //打印所以后矩形面积和周长
            int size = contours.Size;
            for (int i = 0; i < size; i++)
            {
                var item     = contours[i];
                var tempArea = CvInvoke.ContourArea(item);
                var tempArc  = CvInvoke.ArcLength(item, true);
                Console.WriteLine($"面积:{tempArea};周长:{tempArc}");;
                if (tempArea > 200 && tempArea < 2000)
                {
                    validContours.Push(item);
                }
            }

            //CvInvoke.ApproxPolyDP

            //画出所有轮廓
            Mat middleMat = new Image <Bgr, byte>(this.ib_middleCut.Image.Bitmap).Mat;
            CvInvoke.DrawContours(middleMat, validContours, -1, new MCvScalar(0, 0, 255), 1);
            this.ib_result.Image = middleMat;
            commonUse.SaveMat(middleMat, "画出所有轮廓的");

            //画出所有矩形
            Mat tmpMat = new Image <Bgr, byte>(this.ib_middleCut.Image.Bitmap).Mat;
            List <Rectangle> rectangles = commonUse.GetRectList(validContours, false);

            rectangles.ForEach(rect =>
            {
                CvInvoke.Rectangle(tmpMat, rect, new MCvScalar(0, 0, 255));
            });

            commonUse.SaveMat(tmpMat, "画出所有矩形轮廓的");

            this.ib_result.Image = tmpMat;
        }
예제 #26
0
        private void Btn_answerReg4_Click(object sender, EventArgs e)
        {
            if (this.ib_middleCut.Image == null)
            {
                MessageBox.Show("裁剪图片不能为空");
                return;
            }

            CVHelper commonUse  = new CVHelper();
            var      centerList = new List <Point>();

            if (!this.ck_IsIntell.Checked && !this.ckb_ANN.Checked)
            {
                centerList = commonUse.GetCenterPointListFromBitmapByWhiteArea(this.ib_middleCut.Image.Bitmap, CutedRectList);

                Mat tmpMat = new Image <Bgr, byte>(this.ib_middleCut.Image.Bitmap).Mat;
                centerList.ForEach(p =>
                {
                    CvInvoke.Circle(tmpMat, p, 6, new MCvScalar(0, 0, 255), 2);
                });

                this.ib_result.Image = tmpMat;
            }
            else
            {
                var rectList = new List <Rectangle>();
                CutedRectList.ForEach(r =>
                {
                    r.Offset(destRect.Location);
                    //int offsetX = Math.Min(5, r.X), offsetY = Math.Min(5, r.Y);
                    //r.Offset(-offsetX, -offsetY);
                    rectList.Add(r);
                });
                CVArea area = new CVArea(this.destRect, commonUse.OrderRectList(rectList, IsFillFull: false), name: "测试卷");
                if (this.ck_IsIntell.Checked)
                {
                    centerList = commonUse.GetCenterPointListFromBitmapByWhiteArea(this.ib_original.Image.Bitmap, new List <CVArea>()
                    {
                        area
                    });
                }
                else if (this.ckb_ANN.Checked)
                {
                    centerList = commonUse.GetCenterPointListFromBitmapByWhiteAreaByML(this.ib_original.Image.Bitmap, new List <CVArea>()
                    {
                        area
                    });
                }

                Mat tmpMat = new Image <Bgr, byte>(this.ib_original.Image.Bitmap).Mat;
                centerList.ForEach(p =>
                {
                    CvInvoke.Circle(tmpMat, p, 6, new MCvScalar(0, 0, 255), 2);
                });

                this.ib_result.Image = tmpMat;

                this.CurrentArea = area;
                return;
            }
        }