opencv 寻找图像中黑色方块区域

流程

/// <summary>
        /// 寻找图像中的轮廓
        /// </summary>
        /// <param name="resMat">原图</param>
        /// <param name="maxArea">最大面积</param>
        /// <param name="minArea">最小面积</param>
        /// <param name="minWidth">最小宽度</param>
        /// <param name="maxHeight">最大高度</param>
        /// <returns></returns>
        private static List<Point[]> FindImgLunKuo(Mat resMat, int maxArea, int minArea, int minWidth, int maxHeight)
        {
            // 读取灰度图
            Mat grayMat = new Mat();
            Cv2.CvtColor(resMat, grayMat, ColorConversionCodes.BGR2GRAY);

            // 二值化
            Mat binary = new Mat();
            Cv2.Threshold(grayMat, binary, 127, 255, ThresholdTypes.Binary);//转换为二值图像
            //binary.SaveImage(@"C:\Users\Administrator\Desktop\桌面文件夹\images\scanfile\题卡合一\0227-1\binary1.jpg");
            // 图片反色
            Cv2.BitwiseNot(binary, binary);
            //binary.SaveImage(@"C:\Users\Administrator\Desktop\桌面文件夹\images\scanfile\题卡合一\0227-1\binary2.jpg");

            // 腐蚀去除较细的线条
            Mat result = new Mat();
            InputArray kernel = Cv2.GetStructuringElement(MorphShapes.Rect, new Size(5, 5), new Point(-1, -1));
            Cv2.Erode(binary, result, kernel);
            //result.SaveImage(@"C:\Users\Administrator\Desktop\桌面文件夹\images\scanfile\题卡合一\0227-1\bitnot.jpg");

            // 边缘检测
            Mat cyMat = new Mat();
            Cv2.Canny(result, cyMat, 50, 150);
            //cyMat.SaveImage(@"C:\Users\Administrator\Desktop\桌面文件夹\images\scanfile\题卡合一\0227-1\cnn.jpg");

            // 过滤出合适点的轮廓
            List<Point[]> resShaixuan = new List<Point[]>();

            // 寻找轮廓
            Cv2.FindContours(cyMat, out Point[][] contours, out HierarchyIndex[] hierarchies, RetrievalModes.CComp, ContourApproximationModes.ApproxSimple, new Point());

            //int j = 0;
            for (int i = 0; i < contours.Length; i++)
            {
                // 检测点是否为 0 0
                bool flag = CheckZeroPoint(contours[i]);
                if (!flag)
                {
                    continue;
                }

                // 连接最小矩形 过滤出合适面积的数组
                RotatedRect rotatedRect = Cv2.MinAreaRect(contours[i]);
                Point2f[] point2s = Cv2.BoxPoints(rotatedRect);
                List<float> point2fXList = new List<float>();
                List<float> point2fYList = new List<float>();
                for (int j = point2s.Length - 1; j >= 0; j--)
                {
                    //Console.WriteLine("point2s:" + j + "==" + point2s[j]);
                    point2fXList.Add(point2s[j].X);
                    point2fYList.Add(point2s[j].Y);
                }
                point2fXList.Sort();// 升序排序
                point2fYList.Sort();// 升序排序
                // 过滤宽度过小
                if (point2fXList[point2fXList.Count - 1] - point2fXList[0] < minWidth)
                {
                    continue;
                }
                // 过滤高度过高
                if (point2fYList[point2fYList.Count - 1] - point2fYList[0] > maxHeight)
                {
                    continue;
                }
                // 过滤边缘
                if (Math.Abs(resMat.Width - point2fXList[point2fXList.Count - 1]) < 3 || Math.Abs(resMat.Height - point2fXList[point2fYList.Count - 1]) < 3)
                {
                    continue;
                }

                // 面积过滤
                Rect rect = rotatedRect.BoundingRect();
                int recWidth = rect.Width;
                int recHeight = rect.Height;
                int mianji = recWidth * recHeight;
                if (mianji > minArea && mianji < maxArea)
                {
                    Console.WriteLine("mianji == " + mianji);
                    resShaixuan.Add(contours[i]);

                    // 根据点画线
                    //Cv2.DrawContours(resMat, resShaixuan, -1, new Scalar(0, 0, 255), 3, LineTypes.Link4);

                    //resMat.SaveImage(@"C:\Users\Administrator\Desktop\桌面文件夹\images\scanfile\题卡合一\0227-1\draw.jpg");
                    break;
                }
            }

            return resShaixuan;
        }

  • 7
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值