public dynamic PreProcessImage(ref Mat image, Mat sourceImage)
        {
            var copy = new Mat();

            try
            {
                Cv2.BilateralFilter(image, copy, 9, 75, 75);
                Cv2.AdaptiveThreshold(copy, copy, 255, AdaptiveThresholdTypes.GaussianC, ThresholdTypes.Binary, 115, 4);
                Cv2.MedianBlur(copy, copy, 11);
                Cv2.CopyMakeBorder(copy, copy, 5, 5, 5, 5, BorderTypes.Constant, Scalar.Black);

                // TODO: Dispose new Mat()
                var otsu = Cv2.Threshold(copy, new Mat(), 0, 255, ThresholdTypes.Binary | ThresholdTypes.Otsu);
                Cv2.Canny(copy, copy, otsu, otsu * 2, 3, true);
            }
            catch
            {
                copy.Dispose();
                throw;
            }

            image.Dispose();
            image = copy;

            return(null);
        }
Exemple #2
0
        private IEnumerable <IEnumerable <Mat> > SplitImages(Mat image)
        {
            var dilate  = new Mat();
            var element = Cv2.GetStructuringElement(StructuringElementShape.Rect, new Size(image.Width / 40, 1));

            Cv2.Dilate(image.Threshold(127, 255, ThresholdType.BinaryInv), dilate, element);

            HierarchyIndex[] hierarchyIndices;
            Point[][]        contours;
            Cv2.FindContours(dilate, out contours, out hierarchyIndices, ContourRetrieval.External, ContourChain.ApproxNone);

            var contourRows = SortToRows(contours);

            var imageRows = contourRows.Select(r => r.Select(c =>
            {
                var img = new Mat();
                Cv2.CopyMakeBorder(img[Cv2.BoundingRect(c)], img, 10, 10, 10, 10, BorderType.Constant, Scalar.White);

                // using (new Window("image", segment)) { Cv2.WaitKey(); }

                return(img);
            }));

            return(imageRows);
        }
Exemple #3
0
        private void button1_Click(object sender, EventArgs e)
        {
            Mat src_Mat = new Mat("F:\\Microsoft Visual Studio\\project\\yoloaforge\\yoloaforge\\a.jpg", ImreadModes.AnyColor | ImreadModes.AnyDepth);
            Mat dst_Mat = new Mat();

            #region 边缘处理四个类型
            //定义四个方向像素,边缘宽度相对于源图像的 0.05
            int top    = (int)(0.05 * src_Mat.Rows);
            int botton = (int)(0.05 * src_Mat.Rows);
            int left   = (int)(0.05 * src_Mat.Cols);
            int right  = (int)(0.05 * src_Mat.Cols);

            //定义随机数
            RNG r = new RNG(12345);
            //int borderType =(int) BorderTypes.Default;
            BorderTypes borderType = new BorderTypes();
            borderType = BorderTypes.Default;
            //Cv2.ImShow("src", src);
            int ch = 0;
            while (true)
            {
                ch = Cv2.WaitKey(500);
                if ((char)ch == 27)// ESC建退出
                {
                    break;
                }
                else if ((char)ch == 'r')
                {
                    borderType = BorderTypes.Replicate;//填充边缘像素用已知的边缘像素值
                }
                else if ((char)ch == 'w')
                {
                    borderType = BorderTypes.Wrap;//用另外一边的像素来补偿填充
                }
                else if ((char)ch == 'c')
                {
                    borderType = BorderTypes.Constant;//填充边缘用指定像素值
                }

                else if ((char)ch == 'd')
                {
                    borderType = BorderTypes.Default;//默认边缘处理
                }

                Scalar color = new Scalar(r.Uniform(0, 255), r.Uniform(0, 255), r.Uniform(0, 255));

                Cv2.CopyMakeBorder(src_Mat, dst_Mat, top, botton, left, right, borderType, color);
                Window w = new Window("dst", WindowMode.Normal);
                Cv2.ImShow("dst", dst_Mat);
            }
            #endregion
            //Cv2.GaussianBlur(src, dst, new Size(5, 5), 5, 5, BorderTypes.Wrap);

            //using (new Window("dst", WindowMode.Normal, dst_Mat))
            //{
            //    Cv2.WaitKey(0);
            //}
        }
        public static SoftwareBitmap ExtendImageBorder(SoftwareBitmap Input, Color Colors, int Top, int Left, int Right, int Bottom)
        {
            using (Mat inputMat = Input.SoftwareBitmapToMat())
                using (Mat outputMat = new Mat(inputMat.Rows, inputMat.Cols, MatType.CV_8UC4))
                {
                    Cv2.CopyMakeBorder(inputMat, outputMat, Top, Bottom, Left, Right, BorderTypes.Constant, new Scalar(Colors.B, Colors.G, Colors.R));

                    return(outputMat.MatToSoftwareBitmap());
                }
        }
Exemple #5
0
        private void bernsen_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            if (load == true)
            {
                Mat src = new Mat(fileName, 0);
                Mat dst = Mat.Zeros(src.Size(), src.Type());

                int    r      = 15;
                double eps    = 15.0;
                int    border = (r - 1) / 2;
                Mat    result = new Mat(src.Rows, src.Cols, src.Type());
                Cv2.CopyMakeBorder(src, result, border, border, border, border, BorderTypes.Replicate);

                for (int i = border; i < result.Rows - border; i++)
                {
                    for (int j = border; j < result.Cols - border; j++)
                    {
                        Mat square = result.SubMat(new Rect(j - border, i - border, r, r));

                        double min, max;
                        Cv2.MinMaxLoc(square, out min, out max);
                        double c = max - min, t;

                        if (c > eps)
                        {
                            t = (min + max) / 2.0;
                        }
                        else
                        {
                            t = 0;
                        }

                        byte value = result.Get <byte>(i, j);

                        if (value > t)
                        {
                            value = 255;
                        }
                        else
                        {
                            value = 0;
                        }

                        dst.Set(i - border, j - border, value);
                    }
                }
                showWindow(dst, "bernsen");
            }
            else
            {
                textLoad.Foreground = System.Windows.Media.Brushes.OrangeRed;
            }
        }
Exemple #6
0
 private Mat GetPaddedBinary()
 {
     using (Mat tmp = GetInRangeBinary())
         using (Mat tmp2 = new Mat())
         {
             Mat tmp3 = new Mat();
             // median blue to get ride of the noise
             Cv2.MedianBlur(tmp, tmp2, 21);
             var padding = _v.img_padding;
             Cv2.CopyMakeBorder(tmp2, tmp3, padding, padding, padding, padding, BorderTypes.Constant, new Scalar(0, 0, 0));
             return(tmp3);
         }
 }
Exemple #7
0
        private void niblack_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            if (load == true)
            {
                Mat src = new Mat(fileName, 0);
                Mat dst = Mat.Zeros(src.Size(), src.Type());

                int    r      = 15;
                double k      = -0.2;
                int    border = (r - 1) / 2;
                Mat    result = new Mat(src.Rows, src.Cols, src.Type());
                Cv2.CopyMakeBorder(src, result, border, border, border, border, BorderTypes.Replicate);

                for (int i = border; i < result.Rows - border; i++)
                {
                    for (int j = border; j < result.Cols - border; j++)
                    {
                        Mat square = result.SubMat(new Rect(j - border, i - border, r, r));

                        Scalar mean = new Scalar();
                        Scalar dev  = new Scalar();
                        Cv2.MeanStdDev(square, out mean, out dev);

                        double t = mean.Val0 + k * dev.Val0;

                        byte value = result.Get <byte>(i, j);

                        if (value > t)
                        {
                            value = 255;
                        }
                        else
                        {
                            value = 0;
                        }

                        dst.Set(i - border, j - border, value);
                    }
                }
                showWindow(dst, "niblack");
            }
            else
            {
                textLoad.Foreground = System.Windows.Media.Brushes.OrangeRed;
            }
        }
        private Mat GetPaddedBinary()
        {
            using (Mat tmp = Mat.Ones(_graySrcImage.Size(), MatType.CV_8UC1) * 255)
            {
                Mat tmp2 = new Mat();
                var pts  = _regions.Select(p =>
                {
                    var points = new Point[4];
                    points[0]  = p.Location;
                    points[1]  = p.Location + new Point(p.Width, 0);
                    points[2]  = p.Location + new Point(p.Width, p.Height);
                    points[3]  = p.Location + new Point(0, p.Height);
                    return(points);
                });
                Cv2.FillPoly(tmp, pts, new Scalar(0, 0, 0));

                var padding = _v.img_padding;
                Cv2.CopyMakeBorder(tmp, tmp2, padding, padding, padding, padding, BorderTypes.Constant, new Scalar(0, 0, 0));
                return(tmp2);
            }
        }
Exemple #9
0
        public void CopyMakeBorder()
        {
            using var src = new Mat(10, 10, MatType.CV_8UC1, 0);
            using var dst = new Mat();
            const int top = 1, bottom = 2, left = 3, right = 4;

            Cv2.CopyMakeBorder(src, dst, top, bottom, left, right, BorderTypes.Constant, 255);

            using var expected = new Mat(src.Rows + top + bottom, src.Cols + left + right, src.Type(), 0);
            Cv2.Rectangle(expected, new Point(0, 0), new Point(expected.Cols, top - 1), 255, -1);
            Cv2.Rectangle(expected, new Point(0, expected.Rows - bottom), new Point(expected.Cols, expected.Rows), 255, -1);
            Cv2.Rectangle(expected, new Point(0, 0), new Point(left - 1, expected.Rows), 255, -1);
            Cv2.Rectangle(expected, new Point(expected.Cols - right, 0), new Point(expected.Cols, expected.Rows), 255, -1);

            if (Debugger.IsAttached)
            {
                Window.ShowImages(dst, expected);
            }

            ImageEquals(dst, expected);
        }
Exemple #10
0
        /**
         * 扩展图形边界
         */
        private static Mat CopyBorder(Mat Source)
        {
            // 图形形态学(腐蚀)
            var Eroded     = new Mat();
            Mat KernelOpen = Cv2.GetStructuringElement(MorphShapes.Rect, new Size(4, 4));

            Cv2.MorphologyEx(Source, Eroded, MorphTypes.Open, KernelOpen, new Point(-1, -1), 2);

            // 往四周扩展10个像素
            var CopyBordered = new Mat();

            Cv2.CopyMakeBorder(Eroded, CopyBordered, 10, 10, 10, 10, BorderTypes.Constant, new Scalar(0));

            // 图形形态学(膨胀)
            var Dilated     = new Mat();
            Mat KernelClose = Cv2.GetStructuringElement(MorphShapes.Rect, new Size(2, 2));

            Cv2.MorphologyEx(CopyBordered, Dilated, MorphTypes.Close, KernelClose, new Point(-1, -1), 6);

            return(Dilated);
        }
Exemple #11
0
        private static void Kuwahara(Mat src, Mat dst)
        {
            const int kernelSize = 5;
            const int margin     = kernelSize / 2 + 1;

            if (src.Type() != MatType.CV_8UC3)
            {
                throw new ArgumentException("src.Type() != 8UC3", nameof(src));
            }

            using var srcBorder = new Mat();
            Cv2.CopyMakeBorder(src, srcBorder, margin, margin, margin, margin, BorderTypes.Reflect);

            using var sum   = new Mat <Vec3i>();
            using var sqSum = new Mat <Vec3d>();
            Cv2.Integral(srcBorder, sum, sqSum);

            int w = src.Cols;
            int h = src.Rows;

            dst.Create(h, w, src.Type());
            var dstIndexer = dst.GetUnsafeGenericIndexer <Vec3b>();

            Parallel.For(margin, h + margin, y =>
            {
                for (int x = margin; x < w + margin; x++)
                {
                    var a   = MeanAndVariance(y - margin, x - margin, margin, sum, sqSum);
                    var b   = MeanAndVariance(y - margin, x - 0, margin, sum, sqSum);
                    var c   = MeanAndVariance(y - 0, x - 2, margin, sum, sqSum);
                    var d   = MeanAndVariance(y - 0, x - 0, margin, sum, sqSum);
                    var min = new[] { a, b, c, d }.OrderBy(mv => mv.Variance[0] + mv.Variance[1] + mv.Variance[2]).First();
                    dstIndexer[y - margin, x - margin] = new Vec3b(
                        (byte)min.Mean[0],
                        (byte)min.Mean[1],
                        (byte)min.Mean[2]);
                }
            });
        }
Exemple #12
0
        private int OpenT()
        {
            String filename = "F:\\b.png";

            //Mat I = (Bitmap)Image.FromFile(filename);
            Mat I      = new Mat(filename, ImreadModes.Color);
            Mat X      = new Mat();
            Mat padded = new Mat();                 //以0填充输入图像矩阵
            //Cv2.GetOptimalDFTSize();
            int m = Cv2.GetOptimalDFTSize(I.Rows);
            int n = Cv2.GetOptimalDFTSize(I.Cols);


            //填充输入图像I,输入矩阵为padded,上方和左方不做填充处理
            Cv2.CopyMakeBorder(I, padded, 0, m - I.Rows, 0, n - I.Cols, BorderTypes.Constant);


            pictureBox1.Image = ToolFunctions.GetThumbnail(X.ToBitmap(), pictureBox1.Height, pictureBox1.Width);



            return(0);
        }
Exemple #13
0
        /// <summary>
        /// Nickの手法による二値化処理を行う。
        /// </summary>
        /// <param name="imgSrc">入力画像</param>
        /// <param name="imgDst">出力画像</param>
        /// <param name="kernelSize">局所領域のサイズ</param>
        /// <param name="k">係数</param>
#else
        /// <summary>
        /// Binarizes by Nick's method
        /// </summary>
        /// <param name="src">Input image</param>
        /// <param name="dst">Output image</param>
        /// <param name="kernelSize">Window size</param>
        /// <param name="k">Adequate coefficient</param>
#endif
        public static void Nick(Mat src, Mat dst, int kernelSize, double k)
        {
            if (src == null)
            {
                throw new ArgumentNullException("src");
            }
            if (dst == null)
            {
                throw new ArgumentNullException("dst");
            }

            // グレースケールのみ
            if (src.Type() != MatType.CV_8UC1)
            {
                throw new ArgumentException("src must be gray scale image");
            }
            if (dst.Type() != MatType.CV_8UC1)
            {
                throw new ArgumentException("dst must be gray scale image");
            }

            // サイズのチェック
            if (kernelSize < 3)
            {
                throw new ArgumentOutOfRangeException("kernelSize", "size must be 3 and above");
            }
            if (kernelSize % 2 == 0)
            {
                throw new ArgumentOutOfRangeException("kernelSize", "size must be odd number");
            }

            int borderSize = kernelSize / 2;
            int width      = src.Width;
            int height     = src.Height;

            dst.Create(src.Size(), src.Type());

            using (var tempMat = new Mat(height + (borderSize * 2), width + (borderSize * 2), src.Type()))
                using (var sumMat = new Mat(tempMat.Height + 1, tempMat.Width + 1, MatType.CV_64FC1, 1))
                    using (var sqSumMat = new Mat(tempMat.Height + 1, tempMat.Width + 1, MatType.CV_64FC1, 1))
                    {
                        Cv2.CopyMakeBorder(src, tempMat, borderSize, borderSize, borderSize, borderSize, BorderTypes.Replicate, Scalar.All(0));
                        Cv2.Integral(tempMat, sumMat, sqSumMat);

                        using (var tSrcMat = new MatOfByte(src))
                            using (var tDstMat = new MatOfByte(dst))
                                using (var tSumMat = new MatOfDouble(sumMat))
                                    using (var tSqSumMat = new MatOfDouble(sqSumMat))
                                    {
                                        var tSrc   = tSrcMat.GetIndexer();
                                        var tDst   = tDstMat.GetIndexer();
                                        var tSum   = tSumMat.GetIndexer();
                                        var tSqSum = tSqSumMat.GetIndexer();

                                        int ylim         = height + borderSize;
                                        int xlim         = width + borderSize;
                                        int kernelPixels = kernelSize * kernelSize;
                                        for (int y = borderSize; y < ylim; y++)
                                        {
                                            for (int x = borderSize; x < xlim; x++)
                                            {
                                                int    x1    = x - borderSize;
                                                int    y1    = y - borderSize;
                                                int    x2    = x + borderSize + 1;
                                                int    y2    = y + borderSize + 1;
                                                double sum   = tSum[y2, x2] - tSum[y2, x1] - tSum[y1, x2] + tSum[y1, x1];
                                                double sqsum = tSqSum[y2, x2] - tSqSum[y2, x1] - tSqSum[y1, x2] + tSqSum[y1, x1];
                                                double mean  = sum / kernelPixels;
                                                double term  = (sqsum - mean * mean) / kernelPixels;
                                                if (term < 0.0)
                                                {
                                                    term = 0.0;
                                                }
                                                term = Math.Sqrt(term);

                                                double threshold = mean + k * term;
                                                if (tSrc[y - borderSize, x - borderSize] < threshold)
                                                {
                                                    tDst[y - borderSize, x - borderSize] = 0;
                                                }
                                                else
                                                {
                                                    tDst[y - borderSize, x - borderSize] = 255;
                                                }
                                            }
                                        }
                                    }
                    }
        }
Exemple #14
0
        /**
         * 识别的主流程
         * 返回识别后的数字
         * needSave是否输出中间图像
         */
        public static string Process(string Img, bool needSave = false)
        {
            // 图片路径
            // const string Img = @"D:\work\sharp\DigitalTube1\data\1873.jpg";
            string ImgPath = Path.GetDirectoryName(Img);
            string ImgName = Path.GetFileNameWithoutExtension(Img);
            string ImgPref = Path.Combine(ImgPath, ImgName);

            // 显示原始图片
            var OriginImg = Cv2.ImRead(Img);
            // ------------------- debug start
            //Cv2.NamedWindow("OriginImg", WindowMode.Normal);
            //Cv2.ImShow("OriginImg", OriginImg);
            // ------------------- debug end

            // 转化成灰度图
            var Grayscale = Cv2.ImRead(Img, ImreadModes.Grayscale);
            // ------------------- debug start
            //Cv2.NamedWindow("Grayscale", WindowMode.Normal);
            //Cv2.ImShow("Grayscale", Grayscale);
            // ------------------- debug end

            // 往四周扩展10个像素
            var CopyBordered = new Mat();

            Cv2.CopyMakeBorder(Grayscale, CopyBordered, 10, 10, 10, 10, BorderTypes.Constant, new Scalar(255));
            // ------------------- debug start
            //Cv2.NamedWindow("CopyBordered", WindowMode.Normal);
            //Cv2.ImShow("CopyBordered", CopyBordered);
            // ------------------- debug end

            // 进行高斯模糊变换(去噪)
            var Blured = new Mat();

            Cv2.GaussianBlur(CopyBordered, Blured, new Size(15, 15), 0);
            // ------------------- debug start
            //Cv2.NamedWindow("Blured", WindowMode.Normal);
            //Cv2.ImShow("Blured", Blured);
            // ------------------- debug end

            // 转化为二值图片(只有黑白无灰色)
            var Binary = new Mat();

            Cv2.Threshold(Blured, Binary, 128, 255, ThresholdTypes.Binary);
            // ------------------- debug start
            //Cv2.NamedWindow("Binary", WindowMode.Normal);
            //Cv2.ImShow("Binary", Binary);
            // ------------------- debug end

            // 去掉小数点(小块面积去噪)
            var DropNoise = DropSmallAreaNoise(Binary);
            // ------------------- debug start
            //Cv2.NamedWindow("DropNoise", WindowMode.Normal);
            //Cv2.ImShow("DropNoise", DropNoise);
            // ------------------- debug end

            // 图形形态学(腐蚀)
            var Eroded     = new Mat();
            Mat KernelOpen = Cv2.GetStructuringElement(MorphShapes.Rect, new Size(4, 4));

            Cv2.MorphologyEx(DropNoise, Eroded, MorphTypes.Open, KernelOpen, new Point(-1, -1), 7);
            // ------------------- debug start
            //Cv2.NamedWindow("Eroded", WindowMode.Normal);
            //Cv2.ImShow("Eroded", Eroded);
            // ------------------- debug end

            // 图形形态学(膨胀)
            var Dilated     = new Mat();
            Mat KernelClose = Cv2.GetStructuringElement(MorphShapes.Rect, new Size(3, 3));

            Cv2.MorphologyEx(Eroded, Dilated, MorphTypes.Close, KernelClose, new Point(-1, -1), 5);
            // ------------------- debug start
            //Cv2.NamedWindow("Dilated", WindowMode.Normal);
            //Cv2.ImShow("Dilated", Dilated);
            // ------------------- debug end

            // 图形取反变换(黑白颠倒)
            var Binary2 = new Mat();

            Cv2.BitwiseNot(Dilated, Binary2);
            // ------------------- debug start
            //Cv2.NamedWindow("Binary2", WindowMode.Normal);
            //Cv2.ImShow("Binary2", Binary2);
            // ------------------- debug end

            var Morphologyed = Binary2.Clone();

            // 识别图片轮廓(后续按照轮廓分割)
            var Rects = new List <Rect>();

            // 识别轮廓
            Point[][] Contours = Cv2.FindContoursAsArray(Binary2, RetrievalModes.External, ContourApproximationModes.ApproxSimple);
            Console.WriteLine("Contours Count = " + Contours.Length);
            foreach (Point[] Contour in Contours)
            {
                Rect Region = Cv2.BoundingRect(Contour);
                Cv2.Rectangle(Morphologyed, Region, new Scalar(193, 0, 0), 4);
                Rects.Add(Region);
            }
            // ------------------- debug start
            //Cv2.NamedWindow("Contours", WindowMode.Normal);
            //Cv2.ImShow("Contours", Morphologyed);
            // ------------------- debug start
            if (needSave)
            {
                Cv2.ImWrite(ImgPref + "__Contours.png", Morphologyed);
            }

            // 对轮廓进行排序(X轴方向,横写文字)
            Rects.Sort((a, b) => (a.X - b.X));

            // 对每个轮廓部分进行处理
            var ImgParts = new Mat[Rects.Count];

            for (var i = 0; i < Rects.Count; i++)
            {
                // 对图形进行边界扩充
                var ImgPart = Binary2[Rects[i]].Clone();
                ImgParts[i] = CopyBorder(ImgPart);
                // ------------------- debug start
                //Cv2.NamedWindow("Number" + (i + 1), WindowMode.Normal);
                //Cv2.ImShow("Number" + (i + 1), ImgParts[i]);
                // ------------------- debug end
                if (needSave)
                {
                    Cv2.ImWrite(ImgPref + "__Contours(" + (i + 1) + ").png", ImgParts[i]);
                }
            }

            // 用穿线法将图形识别成数字
            var Numbers = new char[Rects.Count];

            //如果有一个数字识别不出来,那么就t_number[0]标记为'e'
            for (var i = 0; i < Rects.Count; i++)
            {
                Numbers[i] = myIdentification(ImgParts[i]);
                // Console.WriteLine("Number" + (i + 1) + " = " + Numbers[i]);
            }

            // 将画面停留以便观察结果
            //Cv2.WaitKey();

            return(new string(Numbers));
        }
Exemple #15
0
        private void dealimage(String path, String savepath)
        {
            Mat    result = Cv2.ImRead(path);
            Scalar color  = new Scalar(0, 0, 0);

            Cv2.CopyMakeBorder(result, result, 10, 10, 10, 10, BorderTypes.Constant, color);

            Mat outp = new Mat();

            Cv2.CvtColor(result, outp, ColorConversionCodes.BGR2GRAY);

            Mat thresh = new Mat();

            Cv2.Threshold(outp, thresh, 0, 255, ThresholdTypes.Binary);

            /* Cv2.ImShow("2", thresh);
             * Cv2.WaitKey(-1);*/
            OpenCvSharp.Point[][] counts;
            HierarchyIndex[]      hierarchyIndices;
            Cv2.FindContours(thresh.Clone(), out counts, out hierarchyIndices, RetrievalModes.External, ContourApproximationModes.ApproxSimple);
            double max = 0;

            OpenCvSharp.Point[] point = null;
            foreach (var count in counts)
            {
                if (max < Cv2.ContourArea(count))
                {
                    point = count;
                    max   = Cv2.ContourArea(count);
                }
            }
            Console.WriteLine(thresh.Rows);
            Console.WriteLine(thresh.Cols);
            /*int** mask = new int[][];*/
            Rect rect = Cv2.BoundingRect(point);
            Mat  mat  = Mat.Zeros(thresh.Rows, thresh.Cols, thresh.Type());

            Cv2.Rectangle(mat, rect.TopLeft, rect.BottomRight, 255, -1);
            Mat minRect = mat.Clone();
            Mat sub     = mat.Clone();

            while (Cv2.CountNonZero(sub) > 0)
            {
                Cv2.Erode(minRect, minRect, null);
                Cv2.Subtract(minRect, thresh, sub);
            }
            Cv2.FindContours(minRect.Clone(), out counts, out hierarchyIndices, RetrievalModes.External, ContourApproximationModes.ApproxSimple);
            max = 0;
            foreach (var count in counts)
            {
                if (max < Cv2.ContourArea(count))
                {
                    point = count;
                    max   = Cv2.ContourArea(count);
                }
            }
            rect     = Cv2.BoundingRect(point);
            result   = new Mat(result, rect);
            savepath = savepath + "/" + "result.jpg";
            Cv2.ImWrite(savepath, result);
            try
            {
                pictureBox1.Image = Image.FromFile(savepath);
            }
            catch (Exception e)
            {
            }
            MessageBox.Show("拼接成功");
        }
        /// <summary>
        /// 材质识别
        /// </summary>
        public static List <string> TextureFind(Mat img, Point[] points)
        {
            Mat    src = img;
            Mat    hsv = new Mat(), threshold = new Mat();
            Mat    dst = new Mat(), dst2 = new Mat();
            Scalar HsvWhiteLow  = new Scalar(0, 0, 1);                //白 white
            Scalar HsvWhiteHigh = new Scalar(0.1156, 0.2480, 0.9804);
            Scalar HsvGraLow    = new Scalar(0, 0, 46);               //灰 gray
            Scalar HsvGraHigh   = new Scalar(180, 43, 220);
            Scalar HsvGrayLow   = new Scalar(0.4815, 0.0720, 0.4902); //深灰
            Scalar HsvGrayHigh  = new Scalar(0.4583, 0.0656, 0.2392);
            Scalar HsvGlassLow  = new Scalar(171, 1, 80);             //Glass gray
            Scalar HsvGlassHigh = new Scalar(171, 5, 60);
            Scalar HsvBlueLow   = new Scalar(100, 43, 46);            //蓝 blue
            Scalar HsvBlueHigh  = new Scalar(124, 255, 255);

            Cv2.CvtColor(src, hsv, ColorConversionCodes.BGR2HSV);
            Scalar[]  HsvLow    = { HsvWhiteLow, HsvGlassLow, HsvGraLow, HsvBlueLow, HsvGrayLow };
            Scalar[]  HsvHigh   = { HsvWhiteHigh, HsvGlassHigh, HsvGraHigh, HsvBlueHigh, HsvGrayHigh };
            string[]  textcolor = { "White", "Glass", "Blue", "Metal ash", "Gray" };
            Point[][] contours  = { points };
            int       cc        = 0;
            Point     center    = new Point();

            HierarchyIndex[] hierarchy;

            //List<string> Texture = new List<string>();
            //List<Point> Centerpoint = new List<Point>();
            for (int color = 0; color < HsvLow.Length; color++)
            {
                Cv2.InRange(hsv, HsvLow[color], HsvHigh[color], threshold);
                Cv2.Threshold(threshold, threshold, 1, 255, ThresholdTypes.Binary);
                Cv2.CopyMakeBorder(threshold, dst, 1, 1, 1, 1, BorderTypes.Constant, 0);
                //Cv2.FindContours(dst, out contours, out hierarchy, RetrievalModes.Tree, ContourApproximationModes.ApproxSimple);
                int count = 0;
                if (count < 1)
                {
                    Rect bound = Cv2.BoundingRect(points);

                    center = new Point(bound.X + bound.Width / 2, bound.Y + bound.Height / 2);
                    int[] vs = { center.X, center.Y };
                    char  x  = threshold.At <char>(vs);
                    if (x > 0)
                    {
                        //Cv2.DrawContours(src, contours, 0, Scalar.Red, 1, LineTypes.Link8);
                        //Cv2.PutText(src, textcolor[color], center, HersheyFonts.HersheyComplex,1, Scalar.Black, 1, LineTypes.Link8);
                        //Cv2.Circle(src, center, 10, Scalar.Gold);
                        cc = color;
                    }
                }
            }
            Centerpoint.Add(center);
            switch (textcolor[cc])
            {
            case "Gray":
            case "White": Texture.Add("石头"); break;

            case "Glass":
            case "Blue": Texture.Add("玻璃"); break;

            case "Metal ash": Texture.Add("金属"); break;

            default: Texture.Add("其他"); break;
            }
            //Console.WriteLine(textcolor[cc] + "区域数量:" + count);
            //Cv2.NamedWindow("result_txe", 0);
            //Cv2.ResizeWindow("result_txe", 500, 500);
            //Cv2.ImShow("result_txe", src);
            //
            //Window.WaitKey();
            return(Texture);
        }
Exemple #17
0
        /// <summary>
        /// Binarizes by Sauvola's method (This is faster but memory-hogging)
        /// </summary>
        /// <param name="src">Input image</param>
        /// <param name="dst">Output image</param>
        /// <param name="kernelSize">Window size</param>
        /// <param name="k">Adequate coefficient</param>
        /// <param name="r">Adequate coefficient</param>
        public static void Sauvola(Mat src, Mat dst, int kernelSize, double k, double r)
        {
            if (src == null)
            {
                throw new ArgumentNullException(nameof(src));
            }
            if (dst == null)
            {
                throw new ArgumentNullException(nameof(dst));
            }

            // グレースケールのみ
            if (src.Type() != MatType.CV_8UC1)
            {
                throw new ArgumentException("src must be gray scale image");
            }

            // サイズのチェック
            if (kernelSize < 3)
            {
                throw new ArgumentOutOfRangeException(nameof(kernelSize), "size must be 3 and above");
            }
            if (kernelSize % 2 == 0)
            {
                throw new ArgumentOutOfRangeException(nameof(kernelSize), "size must be odd number");
            }
            if (Math.Abs(r) < 1e-9f)
            {
                throw new ArgumentOutOfRangeException(nameof(r), "r == 0");
            }

            int borderSize = kernelSize / 2;
            int width      = src.Width;
            int height     = src.Height;

            dst.Create(src.Size(), src.Type());

            using (var tempMat = new Mat(height + (borderSize * 2), width + (borderSize * 2), src.Type()))
                using (var sumMat = new Mat())
                    using (var sqSumMat = new Mat())
                    {
                        Cv2.CopyMakeBorder(src, tempMat, borderSize, borderSize, borderSize, borderSize, BorderTypes.Replicate, Scalar.All(0));
                        Cv2.Integral(tempMat, sumMat, sqSumMat, MatType.CV_64FC1);

                        using (var tSrcMat = new Mat <byte>(src))
                            using (var tDstMat = new Mat <byte>(dst))
                                using (var tSumMat = new Mat <double>(sumMat))
                                    using (var tSqSumMat = new Mat <double>(sqSumMat))
                                    {
                                        var tSrc   = tSrcMat.GetIndexer();
                                        var tDst   = tDstMat.GetIndexer();
                                        var tSum   = tSumMat.GetIndexer();
                                        var tSqSum = tSqSumMat.GetIndexer();

                                        int ylim         = height + borderSize;
                                        int xlim         = width + borderSize;
                                        int kernelPixels = kernelSize * kernelSize;
                                        for (int y = borderSize; y < ylim; y++)
                                        {
                                            for (int x = borderSize; x < xlim; x++)
                                            {
                                                int    x1    = x - borderSize;
                                                int    y1    = y - borderSize;
                                                int    x2    = x + borderSize + 1;
                                                int    y2    = y + borderSize + 1;
                                                double sum   = tSum[y2, x2] - tSum[y2, x1] - tSum[y1, x2] + tSum[y1, x1];
                                                double sqsum = tSqSum[y2, x2] - tSqSum[y2, x1] - tSqSum[y1, x2] + tSqSum[y1, x1];
                                                double mean  = sum / kernelPixels;
                                                double var   = (sqsum / kernelPixels) - (mean * mean);
                                                if (var < 0.0)
                                                {
                                                    var = 0.0;
                                                }
                                                double stddev = Math.Sqrt(var);

                                                double threshold = mean * (1 + k * (stddev / r - 1));
                                                if (tSrc[y - borderSize, x - borderSize] < threshold)
                                                {
                                                    tDst[y - borderSize, x - borderSize] = 0;
                                                }
                                                else
                                                {
                                                    tDst[y - borderSize, x - borderSize] = 255;
                                                }
                                            }
                                        }
                                    }
                    }
        }
Exemple #18
0
        public static void type2()
        {
            Mat src = Cv2.ImRead(@"D:\OpenCV\ING\curtainwall\aaaaa.png");
            //src=Findarea(src);
            //Window.WaitKey();
            Mat hsv = new Mat(), threshold = new Mat();
            Mat dst = new Mat(), dst2 = new Mat();
            //Scalar HsvRedLow = new Scalar(0, 40, 40);
            //Scalar HsvRedHigh = new Scalar(40, 255, 255);
            //Scalar HsvGreenLow = new Scalar(41, 40, 40);
            //Scalar HsvGreenHigh = new Scalar(90, 255, 255);
            //Scalar HsvBlueLow = new Scalar(100, 40, 40);
            //Scalar HsvBlueHigh = new Scalar(140, 255, 255);
            Scalar HsvRedLow    = new Scalar(0, 0, 1);     //白 white
            Scalar HsvRedHigh   = new Scalar(0.1156, 0.2480, 0.9804);
            Scalar HsvGreenLow  = new Scalar(0, 0, 46);    //灰 gray
            Scalar HsvGreenHigh = new Scalar(180, 43, 220);
            Scalar HsvBlueLow   = new Scalar(100, 43, 46); //蓝 blue
            Scalar HsvBlueHigh  = new Scalar(124, 255, 255);

            Cv2.CvtColor(src, hsv, ColorConversionCodes.BGR2HSV);
            Cv2.NamedWindow("hsv", 0);
            Cv2.ResizeWindow("hsv", 500, 500);
            Cv2.ImShow("hsv", hsv);
            Scalar[]         HsvLow    = { HsvRedLow, HsvGreenLow, HsvBlueLow };
            Scalar[]         HsvHigh   = { HsvRedHigh, HsvGreenHigh, HsvBlueHigh };
            string[]         textcolor = { "White", "Gray", "Blue" };
            Point[][]        contours;  //= Findarea(src);
            HierarchyIndex[] hierarchy; // = hierarchys;
            for (int color = 0; color < 3; color++)
            {
                Cv2.InRange(hsv, HsvLow[color], HsvHigh[color], threshold);
                Cv2.Threshold(threshold, threshold, 1, 255, ThresholdTypes.Binary);
                Cv2.CopyMakeBorder(threshold, dst, 1, 1, 1, 1, BorderTypes.Constant, 0);

                Mat a = Cv2.GetStructuringElement(MorphShapes.Ellipse, new Size(5, 5));//5.23
                Cv2.MorphologyEx(dst, dst, MorphTypes.Open, a);
                //dst = threshold;

                //Cv2.CvtColor(src,dst2,ColorConversionCodes.BGR2GRAY);
                //Cv2.Threshold(dst2,dst2,100,255,ThresholdTypes.Binary);
                //Cv2.FindContours(dst2, out contours, out hierarchy, RetrievalModes.Tree, ContourApproximationModes.ApproxSimple);
                //Cv2.ImShow("ss",dst2);
                Cv2.NamedWindow(textcolor[color] + "轮廓", 0);
                Cv2.ResizeWindow(textcolor[color] + "轮廓", 500, 500);
                Cv2.ImShow(textcolor[color] + "轮廓", dst);
                Cv2.FindContours(dst, out contours, out hierarchy, RetrievalModes.Tree, ContourApproximationModes.ApproxSimple);
                //Console.WriteLine(contours.Length);
                int count = 0;
                for (int i = 0; i < contours.Length; i++)
                {
                    if (contours[i].Length < 200)
                    {
                        continue;
                    }
                    Rect bound = Cv2.BoundingRect(contours[i]);
                    //Cv2.DrawContours(src, contours, i, Scalar.Black, 1, LineTypes.Link8, hierarchy, 0, new Point(0, 0));
                    Point center = new Point(bound.X + bound.Width / 2, bound.Y + bound.Height / 2);

                    //int[] bc = { center.X, center.Y };
                    //char x = threshold.At<char>(bc);
                    //Console.WriteLine(x);
                    if (true)
                    {
                        count++;
                        Cv2.PutText(src, textcolor[color], center, HersheyFonts.HersheyComplex, 1, Scalar.Black, 1, LineTypes.Link8);
                        Cv2.Circle(src, center, 10, Scalar.Gray);
                    }
                }
                Console.WriteLine(textcolor[color] + "区域数量:" + count);
            }
            Cv2.NamedWindow("result", 0);
            Cv2.ResizeWindow("result", 500, 500);
            Cv2.ImShow("result", src);
            Window.WaitKey();
        }
Exemple #19
0
    public bool LoadShape(string shapePath)
    {
        if (!File.Exists(shapePath))
        {
            Debug.Log("Shape File do not exist!");
            return(false);
        }

        Mat shapeImage = Cv2.ImRead(shapePath, ImreadModes.GrayScale);

        if (shapeImage.Empty())
        {
            Debug.Log("No readable shape file: " + shapePath);
            return(false);
        }

        Cv2.CopyMakeBorder(shapeImage, shapeImage, 10, 10, 10, 10, BorderTypes.Constant);

        shapeImage = 255 - shapeImage;

        Cv2.Erode(shapeImage, shapeImage, new Mat(), new Point(-1, -1), 5);
        Cv2.Dilate(shapeImage, shapeImage, new Mat(), new Point(-1, -1), 5);

        Mat shapeEdges = new Mat();

        Cv2.Canny(shapeImage, shapeEdges, 100, 200, 3, false);

        HierarchyIndex[] contoure_hierarcyInd;

        generatorState = State.NotSet;

        Cv2.FindContours(shapeEdges, out contours,
                         out contoure_hierarcyInd,
                         RetrievalModes.External,
                         ContourApproximationModes.ApproxTC89L1);

        if (contours.Length > 1)
        {
            Debug.Log("Dont know witch contour to use.");
            return(false);
        }

        Point2f center;
        float   radius;

        Cv2.MinEnclosingCircle(contours [0], out center, out radius);

        float diameter = radius * 2;

        contourNormalized = new Point2f[contours [0].Length];
        contourScaled     = new Point2f[contours [0].Length];

        for (int i = 0; i < contours [0].Length; ++i)
        {
            contourNormalized [i] = new Point2f((contours [0] [i].X - center.X) / diameter,
                                                (contours [0] [i].Y - center.Y) / diameter);
            contourScaled [i] = new Point2f();
        }

        steam           = new Point2f[2];
        steamNormalized = new Point2f[2];
        steamScaled     = new Point2f[2];

        steam [0]    = new Point2f(center.X, center.Y);
        steam [0].Y += radius;
        steam [1]    = new Point2f(steam [0].X, steam[0].Y);
        steam [1].Y += diameter * maxSteamLengthRatio;

        for (int i = 0; i < steam.Length; ++i)
        {
            steamNormalized [i] = new Point2f((steam [i].X - center.X) / diameter,
                                              (steam [i].Y - center.Y) / diameter);
            steamScaled [i] = new Point2f();
        }

        generatorState = State.ShapeSet;

        return(true);
    }
Exemple #20
0
        /// <summary>
        /// 离散傅里叶变换
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static Bitmap Dft(this Bitmap source)
        {
            var fileName = Path.GetTempPath() + "\\" + Guid.NewGuid().ToString() + ".bmp";

            File.WriteAllBytes(fileName, source.GetBitmapFileData());

            using (var img = Cv2.ImRead(fileName, ImreadModes.Grayscale))
            {
                fileName = Path.GetTempPath() + "\\" + Guid.NewGuid().ToString() + ".bmp";

                var padded = new Mat();

                // 计算最佳 DFT 尺寸
                var m = Cv2.GetOptimalDFTSize(img.Rows);
                var n = Cv2.GetOptimalDFTSize(img.Cols);
                Cv2.CopyMakeBorder(img, padded, 0, m - img.Rows, 0, n - img.Cols, BorderTypes.Constant, Scalar.All(0));

                var paddedF32 = new Mat();
                padded.ConvertTo(paddedF32, MatType.CV_32F);
                Mat[] planes  = { paddedF32, Mat.Zeros(padded.Size(), MatType.CV_32F) };
                var   complex = new Mat();
                Cv2.Merge(planes, complex);

                // 执行 dft
                var dft = new Mat();
                Cv2.Dft(complex, dft);

                // log(1 + sqrt(Re(DFT(I))^2 + Im(DFT(I))^2))
                Cv2.Split(dft, out var dftPlanes); // planes[0] = Re(DFT(I), planes[1] = Im(DFT(I))

                // planes[0] = magnitude
                var magnitude = new Mat();
                Cv2.Magnitude(dftPlanes[0], dftPlanes[1], magnitude);

                magnitude += Scalar.All(1);
                Cv2.Log(magnitude, magnitude);

                var spectrum = magnitude[
                    new Rect(0, 0, magnitude.Cols & -2, magnitude.Rows & -2)];

                // 交换象限
                var cx = spectrum.Cols / 2;
                var cy = spectrum.Rows / 2;

                var q0 = new Mat(spectrum, new Rect(0, 0, cx, cy));   // 左上
                var q1 = new Mat(spectrum, new Rect(cx, 0, cx, cy));  // 右上
                var q2 = new Mat(spectrum, new Rect(0, cy, cx, cy));  // 左下
                var q3 = new Mat(spectrum, new Rect(cx, cy, cx, cy)); // 右下

                var tmp = new Mat();
                q0.CopyTo(tmp);
                q3.CopyTo(q0);
                tmp.CopyTo(q3);
                q1.CopyTo(tmp);
                q2.CopyTo(q1);
                tmp.CopyTo(q2);

                // 归一化到 0~255
                Cv2.Normalize(spectrum, spectrum, 0, 255, NormTypes.MinMax);
                var result = new Mat();
                spectrum.ConvertTo(result, MatType.CV_8U);

                result.SaveImage(fileName);

                return(new Bitmap(fileName));
            }
        }
Exemple #21
0
        public void Run()
        {
            Mat img = Cv2.ImRead(FilePath.Image.Lenna, ImreadModes.GrayScale);

            // expand input image to optimal size
            Mat padded = new Mat();
            int m      = Cv2.GetOptimalDFTSize(img.Rows);
            int n      = Cv2.GetOptimalDFTSize(img.Cols); // on the border add zero values

            Cv2.CopyMakeBorder(img, padded, 0, m - img.Rows, 0, n - img.Cols, BorderTypes.Constant, Scalar.All(0));

            // Add to the expanded another plane with zeros
            Mat paddedF32 = new Mat();

            padded.ConvertTo(paddedF32, MatType.CV_32F);
            Mat[] planes  = { paddedF32, Mat.Zeros(padded.Size(), MatType.CV_32F) };
            Mat   complex = new Mat();

            Cv2.Merge(planes, complex);

            // this way the result may fit in the source matrix
            Mat dft = new Mat();

            Cv2.Dft(complex, dft);

            // compute the magnitude and switch to logarithmic scale
            // => log(1 + sqrt(Re(DFT(I))^2 + Im(DFT(I))^2))
            Mat[] dftPlanes;
            Cv2.Split(dft, out dftPlanes);  // planes[0] = Re(DFT(I), planes[1] = Im(DFT(I))

            // planes[0] = magnitude
            Mat magnitude = new Mat();

            Cv2.Magnitude(dftPlanes[0], dftPlanes[1], magnitude);

            magnitude += Scalar.All(1);  // switch to logarithmic scale
            Cv2.Log(magnitude, magnitude);

            // crop the spectrum, if it has an odd number of rows or columns
            Mat spectrum = magnitude[
                new Rect(0, 0, magnitude.Cols & -2, magnitude.Rows & -2)];

            // rearrange the quadrants of Fourier image  so that the origin is at the image center
            int cx = spectrum.Cols / 2;
            int cy = spectrum.Rows / 2;

            Mat q0 = new Mat(spectrum, new Rect(0, 0, cx, cy));   // Top-Left - Create a ROI per quadrant
            Mat q1 = new Mat(spectrum, new Rect(cx, 0, cx, cy));  // Top-Right
            Mat q2 = new Mat(spectrum, new Rect(0, cy, cx, cy));  // Bottom-Left
            Mat q3 = new Mat(spectrum, new Rect(cx, cy, cx, cy)); // Bottom-Right

            // swap quadrants (Top-Left with Bottom-Right)
            Mat tmp = new Mat();

            q0.CopyTo(tmp);
            q3.CopyTo(q0);
            tmp.CopyTo(q3);

            // swap quadrant (Top-Right with Bottom-Left)
            q1.CopyTo(tmp);
            q2.CopyTo(q1);
            tmp.CopyTo(q2);

            // Transform the matrix with float values into a
            Cv2.Normalize(spectrum, spectrum, 0, 1, NormTypes.MinMax);

            // Show the result
            Cv2.ImShow("Input Image", img);
            Cv2.ImShow("Spectrum Magnitude", spectrum);

            // calculating the idft
            Mat inverseTransform = new Mat();

            Cv2.Dft(dft, inverseTransform, DftFlags.Inverse | DftFlags.RealOutput);
            Cv2.Normalize(inverseTransform, inverseTransform, 0, 1, NormTypes.MinMax);
            Cv2.ImShow("Reconstructed by Inverse DFT", inverseTransform);
            Cv2.WaitKey();
        }
Exemple #22
0
        public Mat fourier(Mat img)
        {
            Mat padded = new Mat();
            int m      = Cv2.GetOptimalDFTSize(img.Rows);
            int n      = Cv2.GetOptimalDFTSize(img.Cols); // on the border add zero values

            Cv2.CopyMakeBorder(img, padded, 0, m - img.Rows, 0, n - img.Cols, BorderTypes.Constant, Scalar.All(0));

            // Add to the expanded another plane with zeros
            Mat paddedF32 = new Mat();

            padded.ConvertTo(paddedF32, MatType.CV_32F);
            Mat[] planes  = { paddedF32, Mat.Zeros(padded.Size(), MatType.CV_32F) };
            Mat   complex = new Mat();

            Cv2.Merge(planes, complex);

            // this way the result may fit in the source matrix
            Mat dft = new Mat();

            Cv2.Dft(complex, dft);

            // compute the magnitude and switch to logarithmic scale
            // => log(1 + sqrt(Re(DFT(I))^2 + Im(DFT(I))^2))
            Mat[] dftPlanes;
            Cv2.Split(dft, out dftPlanes);  // planes[0] = Re(DFT(I), planes[1] = Im(DFT(I))

            // planes[0] = magnitude
            Mat magnitude = new Mat();

            Cv2.Magnitude(dftPlanes[0], dftPlanes[1], magnitude);

            magnitude += Scalar.All(1);  // switch to logarithmic scale
            Cv2.Log(magnitude, magnitude);

            // crop the spectrum, if it has an odd number of rows or columns
            Mat spectrum = magnitude[
                new OpenCvSharp.Rect(0, 0, magnitude.Cols & -2, magnitude.Rows & -2)];

            // rearrange the quadrants of Fourier image  so that the origin is at the image center
            int cx = spectrum.Cols / 2;
            int cy = spectrum.Rows / 2;

            Mat q0 = new Mat(spectrum, new OpenCvSharp.Rect(0, 0, cx, cy));   // Top-Left - Create a ROI per quadrant
            Mat q1 = new Mat(spectrum, new OpenCvSharp.Rect(cx, 0, cx, cy));  // Top-Right
            Mat q2 = new Mat(spectrum, new OpenCvSharp.Rect(0, cy, cx, cy));  // Bottom-Left
            Mat q3 = new Mat(spectrum, new OpenCvSharp.Rect(cx, cy, cx, cy)); // Bottom-Right

            // swap quadrants (Top-Left with Bottom-Right)
            Mat tmp = new Mat();

            q0.CopyTo(tmp);
            q3.CopyTo(q0);
            tmp.CopyTo(q3);

            // swap quadrant (Top-Right with Bottom-Left)
            q1.CopyTo(tmp);
            q2.CopyTo(q1);
            tmp.CopyTo(q2);

            // Transform the matrix with float values into a
            Cv2.Normalize(spectrum, spectrum, 0, 1, NormTypes.MinMax);

            // calculating the idft
            Mat inverseTransform = new Mat();

            Cv2.Dft(dft, inverseTransform, DftFlags.Inverse | DftFlags.RealOutput);
            Cv2.Normalize(inverseTransform, inverseTransform, 0, 1, NormTypes.MinMax);

            double minVal = 0.0, maxVal = 0.0;

            Cv2.MinMaxIdx(inverseTransform, out minVal, out maxVal);
            Cv2.ConvertScaleAbs(inverseTransform, inverseTransform, 255.0 / (maxVal - minVal), -minVal * 255.0 / (maxVal - minVal));

            return(inverseTransform);
        }