先来c#的,

        private void button1_Click(object sender, EventArgs e)
        {
            var fileName = @"d:\Screenshot4.jpg";
            fileName = @"d:\Screenshot6.png";
            //mat = new Mat(fileName);
            //pictureBox1.SizeMode = PictureBoxSizeMode.Zoom;
            //pictureBox1.Image = mat.ToBitmap();


            var img = Cv2.ImRead(fileName);
            var pos = detect(img);
            foreach (var p in pos)
            {
                Debug.WriteLine(p);
            }

        }


        private List<OpenCvSharp.Point> detect(Mat img)
        {
            var pos = new List<OpenCvSharp.Point>();
            //1.转化成灰度图
            Mat gray = img.CvtColor(ColorConversionCodes.BGR2GRAY);
            //Cv2.CvtColor(img, gray, ColorConversionCodes.BGR2GRAY);
            //2. 形态学变换的预处理,得到可以查找矩形的图片
            Mat dilation = preprocess(gray);
            //3. 查找和筛选文字区域
            var region = findTextRegion(dilation);
            //4. 用绿线画出这些找到的轮廓
            var nrootdir = @"d:/cut_image/";
            var nrootdir2 = @"d:/cut_image2/";
            int i = 0;
            int j = 1;
            foreach (var item in region)
            {
                var newimage=img[item.Y>0?item.Y:0,  item.Y+item.Height,    item.X>0?item.X:0, item.X+item.Width];
                //放大4倍
                Mat img_gray = new Mat();
                //var img_gray = img.Resize(newimage.Size(), 4, 4, InterpolationFlags.Nearest);
                OpenCvSharp.Size size = new OpenCvSharp.Size();
                Cv2.Resize(newimage, img_gray, size, 4, 4, InterpolationFlags.Nearest);

                var file_name = nrootdir + i.ToString() + ".jpg";                
                Cv2.ImWrite(file_name, newimage);

                var file_sub = "";
                var gray2 = img_gray.CvtColor(ColorConversionCodes.BGR2GRAY);
                var dilation2 = preprocess(gray2);
                var region2 = findTextRegion(dilation2);
                foreach (var item2 in region2)
                {
                    var newimage2 = img_gray[item2.Y>0?item2.Y:0,item2.Y+item2.Height,   item2.X>0?item2.X:0, item2.X+item2.Width];
                    if (newimage2.Size().Width > 0)
                    {
                        file_sub = nrootdir2 + i.ToString() + "-" + j.ToString() + ".jpg";
                        Cv2.ImWrite(file_sub, newimage2);
                        j++;
                        pos.Add(new OpenCvSharp.Point(item.X+item2.X/4+item2.Width/8, item.Y+item2.Y/4+item2.Height/8));
                    }
                }
                //如果第一次检测只有一个文字区域,第二次放大再检测则没有。这样直接复制过去
                if (region2 == null || region2.Count == 0)
                {
                    file_sub = nrootdir2 + i.ToString() + "-0" + ".jpg";
                    Cv2.ImWrite(file_sub, newimage);
                    pos.Add(new OpenCvSharp.Point(item.X+item.Width/2, item.Y+item.Height/2));
                }
                i++;

                //画线
                //img.Rectangle(item, new Scalar(0, 255, 0), 2);
            }

            //Cv2.ImShow("img", img);

            return pos;
        }


        public List<Rect> findTextRegion(Mat dilation)
        {
            List<Rect> region = new List<Rect>();
            // 1. 查找轮廓
            OpenCvSharp.Point[][] contours;
            HierarchyIndex[] hierarchly;
            Rect biggestContourRect = new Rect();

            Cv2.FindContours(dilation, out contours, out hierarchly, RetrievalModes.CComp, ContourApproximationModes.ApproxSimple);

            // 2. 筛选那些面积小的
            int i = 0;
            foreach (OpenCvSharp.Point[] contour in contours)
            {
                double area = Cv2.ContourArea(contour);
                //面积小的都筛选掉
                if (area < 1000 || area> 10000)
                {
                    continue;
                }
                //轮廓近似,作用很小
                double epsilon = 0.001 * Cv2.ArcLength(contour, true);
                RotatedRect rect = Cv2.MinAreaRect(contour);

                //找到最小的矩形
                biggestContourRect = Cv2.BoundingRect(contour);

                if (biggestContourRect.Height > (biggestContourRect.Width * 1.2))
                {
                    continue;
                }
                region.Add(biggestContourRect);                
            }
            return region;
            //pictureBox1.Image = mat.ToBitmap();
            
        }

        private Mat preprocess(Mat gray)
        {
            //1.Sobel算子,x方向求梯度
            Mat sobel = new Mat();
            Cv2.Sobel(gray, sobel, MatType.CV_8U, 1, 0, 3);

            //2.二值化
            Mat binary = new Mat();
            Cv2.Threshold(sobel, binary, 0, 255, ThresholdTypes.Otsu | ThresholdTypes.Binary);

            //3. 膨胀和腐蚀操作的核函数
            Mat element1 = new Mat();
            Mat element2 = new Mat();
            OpenCvSharp.Size size1 = new OpenCvSharp.Size(36, 9);
            OpenCvSharp.Size size2 = new OpenCvSharp.Size(24, 6);

            element1 = Cv2.GetStructuringElement(MorphShapes.Rect, size1);
            element2 = Cv2.GetStructuringElement(MorphShapes.Rect, size2);

            //4. 膨胀一次,让轮廓突出
            Mat dilation = new Mat();
            Cv2.Dilate(binary, dilation, element2);

            //5. 腐蚀一次,去掉细节,如表格线等。注意这里去掉的是竖直的线
            Mat erosion = new Mat();
            Cv2.Erode(dilation, erosion, element1);

            //6. 再次膨胀,让轮廓明显一些
            Mat dilation2 = new Mat();
            Cv2.Dilate(erosion, dilation2, element2, null, 2);
            return dilation2;
        }
View Code

相关文章:

  • 2022-12-23
  • 2021-05-19
  • 2022-01-10
  • 2022-12-23
  • 2021-11-21
  • 2021-12-31
  • 2021-06-16
猜你喜欢
  • 2021-08-08
  • 2021-10-12
  • 2021-06-27
  • 2021-08-27
  • 2021-12-29
  • 2021-12-25
相关资源
相似解决方案