Asa_OpenCV.cs 8.9 KB
using OpenCvSharp;
using System;
using System.Drawing;
using System.Collections.Generic;

namespace Asa
{
    public class OpenCV
    {
        /// <summary>
        /// 提取矩形轮廓
        /// </summary>
        /// <param name="bmp"></param>
        /// <returns></returns>
        public List<AreaRect> extractRect(Bitmap bmp)
        {
            Mat src = OpenCvSharp.Extensions.BitmapConverter.ToMat(bmp);
            Mat gray = src.CvtColor(ColorConversionCodes.BGR2GRAY, 1);
            Cv2.PyrDown(gray, gray);  //模糊
            //Cv2.PyrDown(src, src);
            //Cv2.MedianBlur(gray, gray, 3);  //中值滤波
            //Cv2.Threshold(gray, gray, 200, 255, ThresholdTypes.Tozero);
            //Cv2.NamedWindow("qqq", WindowMode.Normal);
            //gray.PyrDown();
            //Cv2.ImShow("qqq", gray);

            //Cv2.Sobel(gray, gray, MatType.CV_16S, 0, 1);
            //Cv2.Sobel(gray, gray, MatType.CV_16S, 1, 0);
            Cv2.Canny(gray, gray, 20, 128);  //边缘     20,128
            //ShowImg("canny", gray);
            Mat[] contours = null;
            Mat hierarchy = new Mat();
            Cv2.FindContours(gray, out contours, hierarchy, RetrievalModes.CComp, ContourApproximationModes.ApproxSimple);  //寻找轮廓
            List<AreaRect> rtn = new List<AreaRect>();
            bool repeat = false;

            for (int index = 0; index < contours.Length; index++)
            {
                RotatedRect rect = Cv2.MinAreaRect(contours[index]);
                //去除过大过小的矩形
                if (rect.Size.Height < 100 || rect.Size.Width < 100) continue;
                if (rect.Size.Height > bmp.Height / 3 || rect.Size.Width > bmp.Width / 3) continue;

                AreaRect ar = new AreaRect();
                ar.Center = new PointF(rect.Center.X * 2, rect.Center.Y * 2);
                ar.Size = new SizeF(rect.Size.Width, rect.Size.Height);
                ar.Angle = rect.Angle;

                Point2f[] pf = rect.Points();
                ar.Points = new PointF[pf.Length];
                for (int i = 0; i < pf.Length; i++)
                    ar.Points[i] = new PointF(pf[i].X * 2, pf[i].Y * 2);

                //找重复
                repeat = false;
                for (int i = 0; i < rtn.Count; i++)
                {
                    if (Math.Abs(ar.Center.X - rtn[i].Center.X) < 10 &&
                        Math.Abs(ar.Center.Y - rtn[i].Center.Y) < 10 &&
                        Math.Abs(ar.Size.Width - rtn[i].Size.Width) < 10 &&
                        Math.Abs(ar.Size.Height - rtn[i].Size.Height) < 10 &&
                        Math.Abs(ar.Angle - rtn[i].Angle) < 5
                        )
                    {
                        repeat = true;
                        continue;
                    }
                }
                if (!repeat) rtn.Add(ar);
            }
            return rtn;

            //Cv2.GetRotationMatrix2D()
        }


        //public class faadfsadf
        //{
        //    public void extractRec(string imagePath)
        //    {
        //        Mat src = new Mat(imagePath, ImreadModes.GrayScale);
        //        Mat originalImg = new Mat(imagePath, ImreadModes.AnyColor);
        //        Cv2.PyrDown(src, src);  //模糊
        //        Cv2.PyrDown(originalImg, originalImg);
        //        Cv2.MedianBlur(src, src, 3);  //中值滤波
        //       //Cv2.Threshold(src, src, 50, 255, ThresholdTypes.BinaryInv);
        //        Cv2.Canny(src, src, 20, 128);  //边缘
        //        ShowImg("canny", src);

        //        Mat[] contours = null;
        //        Mat hierarchy = new Mat();
        //        Cv2.FindContours(src, out contours, hierarchy, RetrievalModes.External, ContourApproximationModes.ApproxSimple);  //寻找轮廓
        //        //Mat linePic = Mat.Zeros(src.Rows, src.Cols, MatType.CV_8UC3);
        //        int contoursSize = contours.Length;

        //        int n = 0;
        //        for (int index = 0; index < contoursSize; index++)
        //        {
        //            //Cv2.DrawContours(linePic, contours, index, Scalar.RandomColor());
        //            //找出完整包含轮廓的最小矩形
        //            //Rect rect = Cv2.BoundingRect(contours[index]);
        //            RotatedRect rect = Cv2.MinAreaRect(contours[index]);
        //            if (rect.Size.Height < 100 || rect.Size.Width < 100)
        //            {
        //                continue;
        //            }
        //            //Cv2.Rectangle(originalImg, rect, Scalar.Red);
        //            Point2f[] pf = rect.Points();
        //            Point[] ps = new Point[pf.Length];
        //            for (int i = 0; i < pf.Length; i++)
        //            {
        //                ps[i] = new Point(pf[i].X, pf[i].Y);
        //            }
        //            Cv2.Line(originalImg, ps[0], ps[1], Scalar.Red);
        //            Cv2.Line(originalImg, ps[1], ps[2], Scalar.Red);
        //            Cv2.Line(originalImg, ps[2], ps[3], Scalar.Red);
        //            Cv2.Line(originalImg, ps[3], ps[0], Scalar.Red);
        //            n++;
        //        }

        //        ShowImg("Line", originalImg);
        //        return;


        //        Mat[] polyContours = new Mat[contoursSize];
        //        double maxArea = 0;
        //        int maxAreaIndex = 0;

        //        for (int index = 0; index < contoursSize; index++)
        //        {

        //            Mat contour = contours[index];
        //            double currentArea = Cv2.ContourArea(contour);
        //            if (currentArea > maxArea)
        //            {
        //                maxAreaIndex = index;
        //                maxArea = currentArea;
        //            }
        //            Mat polyMat = Mat.Zeros(src.Size(), MatType.CV_8UC3);
        //            Cv2.ApproxPolyDP(contour, polyMat, 10, true);
        //            polyContours[index] = polyMat;

        //            Rect rect = Cv2.BoundingRect(polyContours[index]);
        //            originalImg.Rectangle(rect, Scalar.Red);
        //            //if (approx.size() == 4 &&
        //            //    fabs(contourArea(Mat(approx))) > 1000 &&
        //            //    isContourConvex(Mat(approx)))
        //            //{
        //            //    double maxCosine = 0;

        //            //    for (int j = 2; j < 5; j++)
        //            //    {
        //            //        double cosine = fabs(angle(approx[j % 4], approx[j - 2], approx[j - 1]));
        //            //        maxCosine = MAX(maxCosine, cosine);
        //            //    }

        //            //    if (maxCosine < 0.3)
        //            //        squares.push_back(approx);
        //            //}
        //        }
        //        //Mat polyPic = Mat.Zeros(src.Size(),MatType.CV_32SC2);
        //        //Cv2.DrawContours(polyPic, polyContours,maxAreaIndex,Scalar.Red);
        //        //Cv2.DrawContours(dst, polyContours, maxAreaIndex, Scalar.Red,2);
        //        Rect rec = Cv2.BoundingRect(polyContours[maxAreaIndex]);
        //        //originalImg.Rectangle(rec, Scalar.Red) ;
        //        ShowImg("Rec", originalImg);

        //        //originalImg.Rectangle(new Rect(rec.X* 2, rec.Y* 2, rec.Width * 2, rec.Height *2), Scalar.Red);
        //        //投影变换
        //        Point2f[] srcPoints = new Point2f[4];
        //        //左上,右上,右下,左下

        //        srcPoints[0] = new Point2f(rec.TopLeft.X * 2, rec.TopLeft.Y * 2);
        //        srcPoints[1] = new Point2f(rec.Right * 2, rec.Top * 2);
        //        srcPoints[2] = new Point2f(rec.BottomRight.X * 2, rec.BottomRight.Y * 2);
        //        srcPoints[3] = new Point2f(rec.Left * 2, rec.Bottom * 2);
        //        Point2f[] dstPoints = new Point2f[4];
        //        dstPoints[0] = new Point2f(0, 0);
        //        dstPoints[1] = new Point2f(rec.Width * 2, 0);
        //        dstPoints[2] = new Point2f(rec.Width * 2, rec.Height * 2);
        //        dstPoints[3] = new Point2f(0, rec.Height * 2);

        //        Mat transMat = Cv2.GetPerspectiveTransform(srcPoints, dstPoints); //得到变换矩阵
        //        Mat outPutImg = Mat.Zeros(new Size(rec.Width * 2, rec.Height * 2), MatType.CV_16UC1);
        //        Cv2.WarpPerspective(originalImg, outPutImg, transMat, outPutImg.Size()); //进行坐标变换
        //        Cv2.ImShow("Show Img", outPutImg);
        //    }

        private void ShowImg(string winName, Mat img)
        {

            Cv2.NamedWindow(winName, WindowMode.Normal);

            img.PyrDown();
            Cv2.ImShow(winName, img);
            //if (img.Width > 3800)
            //{
            //    Rect roi = new Rect(1000, 1000, 800, 800);

            //    // 复制图像
            //    //Mat roiImg = new Mat(img, roi);
            //    Cv2.ImShow(winName, roiImg);
            //}
            //else
            //{Cv2.ImShow(winName, img);
            //}

        }
        //}
    }


}