public IplImage BitwiseMat(IplImage src)
        {
            Mat Input1  = new Mat(src);
            Mat Input2  = new Mat(this.Binary(src, 150));
            Mat bitwise = new Mat();

            Window win_src1 = new Window("src1", WindowMode.StretchImage, Input1);
            Window win_src2 = new Window("src2", WindowMode.StretchImage, Input2);

            Cv2.BitwiseNot(Input1, bitwise);
            Window win_Not = new Window("BitwiseNot", WindowMode.StretchImage, bitwise);

            Cv2.BitwiseAnd(Input1, Input2.CvtColor(ColorConversion.GrayToBgr), bitwise);
            Window win_And = new Window("BitwiseAnd", WindowMode.StretchImage, bitwise);

            Cv2.BitwiseOr(Input1, Input2.CvtColor(ColorConversion.GrayToBgr), bitwise);
            Window win_Or = new Window("BitwiseOr", WindowMode.StretchImage, bitwise);

            Cv2.BitwiseXor(Input1, Input2.CvtColor(ColorConversion.GrayToBgr), bitwise);
            Window win_Xor = new Window("BitwiseXor", WindowMode.StretchImage, bitwise);

            //IplImage 형식//

            //Cv.Not();
            //Cv.And();
            //Cv.Or();
            //Cv.Xor();

            //IplImage 형식//

            return(Input2.ToIplImage());
        }
Exemple #2
0
        public void Bitwise()
        {
            const int count  = 256;
            var       random = new Random(0);
            var       array1 = Enumerable.Range(0, count).Select(i => (byte)i).OrderBy(_ => random.Next()).ToArray();
            var       array2 = Enumerable.Range(0, count).Select(i => (byte)i).OrderBy(_ => random.Next()).ToArray();

            using var mat1 = new Mat(count, 1, MatType.CV_8UC1, array1);
            using var mat2 = new Mat(count, 1, MatType.CV_8UC1, array2);
            using var and  = new Mat();
            using var or   = new Mat();
            using var xor  = new Mat();
            using var not  = new Mat();
            Cv2.BitwiseAnd(mat1, mat2, and);
            Cv2.BitwiseOr(mat1, mat2, or);
            Cv2.BitwiseXor(mat1, mat2, xor);
            Cv2.BitwiseNot(mat1, not);

            for (int i = 0; i < count; i++)
            {
                Assert.Equal((byte)(array1[i] & array2[i]), and.Get <byte>(i));
                Assert.Equal((byte)(array1[i] | array2[i]), or.Get <byte>(i));
                Assert.Equal((byte)(array1[i] ^ array2[i]), xor.Get <byte>(i));
                Assert.Equal((byte)(~array1[i]), not.Get <byte>(i));
            }
        }
Exemple #3
0
        private Mat GetSceleton(Mat grayImage)
        {
            var binary = new Mat();

            Cv2.Threshold(grayImage, binary, 240, 255, ThresholdType.BinaryInv);

            var skel = Mat.Zeros(binary.Rows, binary.Cols, MatType.CV_8UC1).ToMat();
            var temp = new Mat(binary.Cols, binary.Rows, MatType.CV_8UC1);


            var elem = Cv2.GetStructuringElement(StructuringElementShape.Cross,
                                                 new OpenCvSharp.CPlusPlus.Size(3, 3));

            bool done;

            do
            {
                Cv2.MorphologyEx(binary, temp, MorphologyOperation.Open, elem);
                Cv2.BitwiseNot(temp, temp);
                Cv2.BitwiseAnd(binary, temp, temp);
                Cv2.BitwiseOr(skel, temp, skel);
                Cv2.Erode(binary, binary, elem);

                double max;
                double min;
                Cv2.MinMaxLoc(binary, out min, out max);
                done = (max == 0);
            } while (!done);

            return(skel);
        }
Exemple #4
0
        public override bool run()
        {
            Mat element = Cv2.GetStructuringElement(MorphShapes.Cross, new Size(3, 3));
            Mat skel    = Mat.Zeros(src.Size(), MatType.CV_8UC1);
            Mat erode   = Mat.Zeros(src.Size(), MatType.CV_8UC1);
            Mat temp    = Mat.Zeros(src.Size(), MatType.CV_8UC1);

            int i  = 0;
            Mat im = src.Clone();
            int noneZero;

            do
            {
                noneZero = im.CountNonZero();
                erode    = im.Erode(element);
                temp     = erode.Dilate(element);
                Cv2.Subtract(im, temp, temp);
                Cv2.BitwiseOr(skel, temp, skel);
                erode.CopyTo(im);
                //                Cv2.ImShow("erode", erode); Cv2.WaitKey();
                i += 1;
            } while (im.CountNonZero() > 0 && im.CountNonZero() != noneZero);
            dst = skel;
            return(true);
        }
Exemple #5
0
 private void マスク合成(Mat[] src_color, ref Mat dst_color)
 {
     foreach (Mat src in src_color)
     {
         Cv2.BitwiseOr(src, dst_color, dst_color);
     }
 }
        static void Update()
        {
            //HSV画像とスライダーの値からマスクを生成
            var scalar_min = new Scalar(_h_min, _s_min, _v_min);
            var scalar_max = new Scalar(_h_max, _s_max, _v_max);

            _src.CopyTo(_mask);
            if (_h_min < 0)
            {
                var tempScalar1 = new Scalar(179, _s_max, _v_max);
                var tempScalar2 = new Scalar(0, _s_min, _s_min);
                scalar_min = new Scalar(_h_min + 180, _s_min, _v_min);

                var masks = new List <Mat>();
                masks.Add(CreateMaskImage(_src, scalar_min, tempScalar1));
                masks.Add(CreateMaskImage(_src, tempScalar2, scalar_max));

                Cv2.BitwiseOr(masks[0], masks[1], _mask);
            }
            else
            {
                Cv2.InRange(_hsv, scalar_min, scalar_max, _mask);
            }

            //画像前処理をする
            //PreProcessing();

            Cv2.ImShow(WINDOW_NAME, _mask);

            ////マスク画像を使って元画像にフィルタをかける
            //_dst = new Mat();
            ////src.CopyTo(src, mask);
            //Cv2.BitwiseAnd(_src, _src, _dst, _mask);

            //ウィンドウの画像を更新
            _src.CopyTo(_dst);
            int HueToDisplay(int hue)
            {
                return(hue + 180);
            }

            int SatValToDisplay(int aaa)
            {
                return((int)(aaa / 2.55));
            }

            Cv2.PutText(_dst, $"Hue: {HueToDisplay(_h_min)} ~ {HueToDisplay(_h_max)}", new Point(20, 20), HersheyFonts.HersheyTriplex, fontScale: 1.5, Scalar.Red, thickness: 2);
            Cv2.PutText(_dst, $"Sat: {SatValToDisplay(_s_min)} ~ {SatValToDisplay(_s_max)}", new Point(20, 70), HersheyFonts.HersheyTriplex, fontScale: 1.5, Scalar.Red, thickness: 2);
            Cv2.PutText(_dst, $"Val: {SatValToDisplay(_v_min)} ~ {SatValToDisplay(_v_max)}", new Point(20, 120), HersheyFonts.HersheyTriplex, fontScale: 1.5, Scalar.Red, thickness: 2);


            Cv2.ImShow("src", _dst);
        }
        public override void Update( )
        {
            Mat blueMask = Source.HsvImage.InRange(SpriteBlueLowerMask, SpriteBlueUpperMask);

            Mat greenMask = Source.HsvImage.InRange(SpriteGreenLowerMask, SpriteGreenUpperMask);

            Cv2.BitwiseOr(blueMask, greenMask, Mask);


            Mask = Mask.Dilate(null, iterations: 4);

            Mask = Mask.MorphologyEx(MorphTypes.Close, null, iterations: 3);
            Mask = Mask.Erode(null, iterations: 4);
        }
Exemple #8
0
        private void bn_LogicalSum_Click(object sender, RoutedEventArgs e)
        {
            if (listImage.Count > 0)
            {
                SubWindow.Win_LogicalSum win = new SubWindow.Win_LogicalSum(listImage);
                if (win.ShowDialog() == true)
                {
                    int nMode   = win.nMode;
                    int nIdx1   = win.nSrc1;
                    int nIdx2   = win.nSrc2;
                    Mat matSrc1 = listImage[nIdx1].fn_GetImage();
                    Mat matSrc2 = listImage[nIdx2].fn_GetImage();
                    Mat matDst  = new Mat();
                    timeStart = DateTime.Now;
                    switch (nMode)
                    {
                    case 0:
                        Cv2.Add(matSrc1, matSrc2, matDst);
                        break;

                    case 1:
                        Cv2.Subtract(matSrc1, matSrc2, matDst);
                        break;

                    case 2:
                        //Cv2.Average(matSrc1, matSrc2, matDst);
                        break;

                    case 3:
                        //Cv2.Differential()
                        Cv2.Absdiff(matSrc1, matSrc2, matDst);
                        break;

                    case 4:
                        Cv2.BitwiseAnd(matSrc1, matSrc2, matDst);
                        break;

                    case 5:
                        Cv2.BitwiseOr(matSrc1, matSrc2, matDst);
                        break;
                    }
                    fn_WriteLog($"[Logical Sum] {listImage[nIdx1].Title} + {listImage[nIdx2].Title} : {nMode} ({(DateTime.Now - timeStart).TotalMilliseconds} ms)");
                    fn_NewImage(matDst, $"Logical Sum {nMode}");
                }
            }
        }
        public override void Update()
        {
            Mat brownMask  = Source.InversedHsvImage.InRange(PcmacgBrownLowerMask, PcmacgBrownUpperMask);
            Mat orangeMask = Source.InversedHsvImage.InRange(PcmacgOrangeLowerMask, PcmacgOrangeUpperMask);
            Mat skinMask   = Source.InversedHsvImage.InRange(PcmacgSkinLowerMask, PcmacgSkinUpperMask);

            Cv2.BitwiseOr(brownMask, orangeMask, Mask);
            Cv2.BitwiseOr(Mask, skinMask, Mask);

            Vec3b a = Source.InversedHsvImage.At <Vec3b> (107, 368);

            Debug.WriteLine($"{a.Item0},{a.Item1},{a.Item2}");

            Mask = Mask.Dilate(null, iterations: 5);

            Mask = Mask.MorphologyEx(MorphTypes.Close, null, iterations: 3);
            Mask = Mask.Erode(null, iterations: 4);
        }
Exemple #10
0
            public void EdgeDetect(string fileName)
            {
                Mat srcMat = Cv2.ImRead(fileName);

                Mat srcBlue = srcMat.Split()[0];

                Mat cannyMat  = new Mat();
                Mat sobelMat  = new Mat();
                Mat LaplasMat = new Mat();

                Cv2.Canny(srcBlue, cannyMat, 50, 200, 3);

                //Cv2.ConvertScaleAbs()

                Cv2.Sobel(srcBlue, sobelMat, sobelMat.Type(), 1, 1, 1);

                Cv2.Laplacian(srcBlue, LaplasMat, 3);
                Cv2.ConvertScaleAbs(LaplasMat, LaplasMat, 1, 0);

                ImShow(srcBlue);
                ImShow(cannyMat);
                ImShow(sobelMat);
                ImShow(LaplasMat);

                Mat merge = new Mat(srcMat.Size(), MatType.CV_8U);

                foreach (Mat tm in srcMat.Split())
                {
                    Mat tmm = new Mat();
                    //Cv2.Canny(tm, tmm, 10, 250, 3);
                    Cv2.Laplacian(tm, tmm, 3);
                    Cv2.ConvertScaleAbs(tmm, tmm, 1, 0);
                    ImShow(tmm);
                    Cv2.Threshold(tmm, tmm, 0.5, 255, ThresholdTypes.Binary);

                    Cv2.BitwiseOr(merge, tmm, merge);
                }

                Cv2.MorphologyEx(merge, merge, MorphTypes.Erode, Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(3, 3), new OpenCvSharp.Point(1, 1)));

                ImShow(merge);

                Cv2.WaitKey();
            }
Exemple #11
0
        /// <summary>
        /// images内の画像の白部分をORで統合した画像を得る。
        /// useOrNotのimagesに対応するインデックスの要素をtrueにすると使用し、falseなら無視する。
        /// 例 : useOrNot = {true, true, true, false, false, true} => R, G, B, V を使用する。
        /// </summary>
        public static Bitmap UnionImages(Bitmap[] images, bool[] useOrNot)
        {
            // Matに変換
            var mat = new Mat[images.Length];

            for (int i = 0; i < images.Length; i++)
            {
                mat[i] = images[i].ToMat();
            }

            var unionMat = new Mat(mat[0].Height, mat[0].Width, mat[0].Type());

            for (int i = 0; i < mat.Length; i++)
            {
                if (useOrNot[i])
                {
                    Cv2.BitwiseOr(unionMat, mat[i], unionMat);
                }
            }
            return(unionMat.ToBitmap());
        }
Exemple #12
0
        private void timer1_Tick(object sender, EventArgs e)
        {
            src = cap.QueryFrame();
            pictureBoxIpl1.ImageIpl = src;

            if (src == null)
            {
                timer1.Stop();
            }
            else
            {
                // ? 결과에는 그레이 처리
                //using (Gray g = new Gray())
                //{
                //    pictureBoxIpl2.ImageIpl = g.GrayProcess(src);
                //}

                Mat img  = new Mat(src);
                Mat img2 = new Mat(src2);

                Mat converted = new Mat();
                Cv2.CvtColor(img, converted, ColorConversion.BgrToHsv);
                Mat green = converted.Clone();

                Cv2.InRange(converted, new Scalar(70 - 10, 30, 30), new Scalar(70 + 10, 255, 255), green); //잘되는거
                //Cv2.InRange(converted, new Scalar(70 - 10, 3, 3), new Scalar(70 + 10, 255, 255), green);

                Mat dst      = new Mat();
                Mat dst1     = new Mat();
                Mat inverted = new Mat();

                Cv2.BitwiseNot(green, inverted);
                Cv2.BitwiseAnd(img, img, dst, inverted);
                Cv2.BitwiseOr(dst, img2, dst1, green);
                Cv2.BitwiseOr(dst, dst1, dst1);

                //pictureBoxIpl2.ImageIpl = dst1.ToIplImage();
                pictureBoxIpl2.ImageIpl = dst1.ToIplImage();
            }
        }
Exemple #13
0
        /**
         * 去掉小数点等噪点
         */
        private static Mat DropSmallAreaNoise(Mat ImgBinary)
        {
            var Binary2 = new Mat();

            Cv2.BitwiseNot(ImgBinary, Binary2);
            Point[][] Contours = Cv2.FindContoursAsArray(Binary2, RetrievalModes.External, ContourApproximationModes.ApproxSimple);

            // 找出面积最大的区域
            int MaxArea = 0;

            foreach (Point[] Contour in Contours)
            {
                Rect Region = Cv2.BoundingRect(Contour);
                var  Area1  = Region.Width * Region.Height;
                if (Area1 > MaxArea)
                {
                    MaxArea = Area1;
                }
            }

            // 构造图像掩码
            Mat MaskMat = Mat.Zeros(Binary2.Rows, Binary2.Cols, MatType.CV_8UC1);

            foreach (Point[] Contour in Contours)
            {
                Rect Region = Cv2.BoundingRect(Contour);
                var  Area1  = Region.Width * Region.Height;
                if (Region.Height > Region.Width && (0.0 + Region.Height) / Region.Width < 3 && Area1 * 4 < MaxArea)
                {
                    // 设置感兴趣区域为纯白色(假定白色为背景色)
                    MaskMat[Region].SetTo(new Scalar(255));
                }
            }

            var Result = new Mat();

            Cv2.BitwiseOr(ImgBinary, MaskMat, Result);
            return(Result);
        }
Exemple #14
0
    Mat getBackgroundMask(Mat input)
    {
        Mat[] backMask    = new Mat[4];
        Mat   backMaskfin = new Mat();
        Mat   dilate      = new Mat();


        /*Cv2.InRange(
         * input,
         * new Scalar(bHueL[0], bSatL[0], bvalL[0]),
         * new Scalar(bHueH[0], bSatH[0], bvalH[0]),
         * backMask1);*/

        for (int i = 0; i < 4; ++i)
        {
            backMask[i] = new Mat();
            Cv2.InRange(
                input,
                new Scalar(bHueL[i], bSatL[i], bvalL[i]),
                new Scalar(bHueH[i], bSatH[i], bvalH[i]),
                backMask[i]);
        }

        Cv2.BitwiseOr(backMask[0], backMask[0], backMaskfin);
        Cv2.BitwiseOr(backMaskfin, backMask[1], backMaskfin);
        Cv2.BitwiseOr(backMaskfin, backMask[2], backMaskfin);
        Cv2.BitwiseOr(backMaskfin, backMask[3], backMaskfin);

        Mat stElement = Cv2.GetStructuringElement(MorphShapes.Ellipse, new Size(8, 8));

        Cv2.MorphologyEx(backMaskfin, backMaskfin, MorphTypes.Open, stElement);
        Cv2.MorphologyEx(backMaskfin, backMaskfin, MorphTypes.Close, stElement);
        Cv2.Dilate(backMaskfin, backMaskfin, stElement, new Point(-1, -1), 3);

        return(backMaskfin);
    }
Exemple #15
0
        public static FormExtractionResult ProcessImage(string filename, FormExtractionOptions options = null)
        {
            if (options == null)
            {
                // Assume recommanded parameters.
                options = new FormExtractionOptions();
            }

            var orig  = new Mat(filename);
            var image = new Mat(filename, ImreadModes.GrayScale);

            Cv2.AdaptiveThreshold(image, image, 255, AdaptiveThresholdTypes.MeanC, ThresholdTypes.Binary, 9, 4);

            // Resize image if too large.
            if (image.Width > options.ResizeWidth)
            {
                var height = options.ResizeWidth * image.Height / image.Width;
                Cv2.Resize(image, image, new Size(options.ResizeWidth, height));
            }

            Cv2.BitwiseNot(image, image);
            Cv2.Dilate(image, image, Cv2.GetStructuringElement(MorphShapes.Cross, new Size(2, 2)));

            MatOfByte         mat     = new MatOfByte(image);
            MatIndexer <byte> indexer = mat.GetIndexer();

            var row      = image.Height;
            var col      = image.Width;
            Mat newImage = new Mat(row, col, MatType.CV_8UC3);

            newImage.SetTo(Scalar.Black);

            // We must determine if it "may" be an interesting blob.
            Stopwatch watch = new Stopwatch();

            watch.Start();

            int[] imgData = new int[row * col];
            for (int y = 0; y < row; y++)
            {
                for (int x = 0; x < col; x++)
                {
                    imgData[y + x * row] = indexer[y, x];
                }
            }

            var result = HasBoxes(imgData, row, col, options);

            watch.Stop();
            result.Duration = watch.Elapsed;

            // Preview
            if (result.Boxes.Any() && image.Width != 0 && options.ShowDebugImage)
            {
                var img = CreateImage(result.DebugImg, hasColor: true);
                Cv2.BitwiseOr(newImage, img, newImage);

                Cv2.BitwiseNot(image, image);
                int width  = 400;
                var height = width * image.Height / image.Width;
                Cv2.Resize(orig, orig, new Size(width, height));
                Cv2.Resize(image, image, new Size(width, height));
                Cv2.Resize(newImage, newImage, new Size(width, height));

                using (new Window("orig", orig))
                    using (new Window("pre", image))
                        using (new Window("post", newImage))
                        {
                            Cv2.WaitKey();
                            Cv2.DestroyAllWindows();
                        }
            }

            // Dispose.
            orig.Dispose();
            image.Dispose();
            newImage.Dispose();
            mat.Dispose();

            return(result);
        }
Exemple #16
0
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");

            Mat foreground = Cv2.ImRead(@"D:\OneDrive\Pictures\butterflyGreenScreen.jpg");
            //Mat background = Cv2.ImRead(@"D:\OneDrive\Pictures\city.jpg");
            Mat foregroundHSV = foreground.CvtColor(ColorConversionCodes.BGR2HSV);

            Mat mask       = foregroundHSV.InRange(new Scalar(65, 180, 160), new Scalar(80, 255, 230));
            Mat invertMask = new Mat();

            Cv2.BitwiseNot(mask, invertMask);

            Mat finalForeground = new Mat();

            foreground.CopyTo(finalForeground, invertMask);

            //Mat finalBackground = new Mat();
            //background.CopyTo(finalBackground, mask);

            //Mat finalImage = new Mat();
            //Cv2.BitwiseOr(finalForeground, finalBackground, finalImage);

            Cv2.NamedWindow("Display", WindowMode.AutoSize);

            Cv2.SetMouseCallback("Display", (evnt, x, y, flags, _) =>
            {
                if (x < 0 || x >= foregroundHSV.Width || y < 0 || y >= foregroundHSV.Height)
                {
                    return;
                }

                Vec3b hsv = foregroundHSV.At <Vec3b>(y, x);

                Console.WriteLine($"H: {hsv.Item0}, S: {hsv.Item1}, V: {hsv.Item2}");
            });

            VideoCapture capture = new VideoCapture(0);

            capture.Set(CaptureProperty.FrameWidth, 640);
            capture.Set(CaptureProperty.FrameHeight, 360);
            Mat background      = new Mat();
            Mat finalBackground = new Mat();
            Mat finalImage      = new Mat();

            while (true)
            {
                if (!capture.Read(background))
                {
                    continue;
                }
                background.CopyTo(finalBackground, mask);
                Cv2.BitwiseOr(finalForeground, finalBackground, finalImage);
                Cv2.ImShow("Display", finalBackground);
                Cv2.WaitKey(1);
            }

            //Cv2.ImShow("Display", finalImage);

            //Cv2.WaitKey(0);
        }
Exemple #17
0
        public void FindContours(string sLeftPictureFile, string sRightPictureFile)
        {
            Mat tokuLeft  = new Mat();
            Mat tokuRight = new Mat();
            Mat output    = new Mat();

            AKAZE akaze = AKAZE.Create();

            KeyPoint[] keyPointsLeft;
            KeyPoint[] keyPointsRight;

            Mat descriptorLeft  = new Mat();
            Mat descriptorRight = new Mat();

            DescriptorMatcher matcher; //マッチング方法

            DMatch[] matches;          //特徴量ベクトル同士のマッチング結果を格納する配列

            //画像をグレースケールとして読み込み、平滑化する
            Mat Lsrc = new Mat(sLeftPictureFile, ImreadModes.Color);

            //画像をグレースケールとして読み込み、平滑化する
            Mat Rsrc = new Mat(sRightPictureFile, ImreadModes.Color);

            //特徴量の検出と特徴量ベクトルの計算
            akaze.DetectAndCompute(Lsrc, null, out keyPointsLeft, descriptorLeft);
            akaze.DetectAndCompute(Rsrc, null, out keyPointsRight, descriptorRight);


            //画像1の特徴点をoutput1に出力
            Cv2.DrawKeypoints(Lsrc, keyPointsLeft, tokuLeft);
            Image imageLeftToku = BitmapConverter.ToBitmap(tokuLeft);

            pictureBox3.SizeMode = PictureBoxSizeMode.Zoom;
            pictureBox3.Image    = imageLeftToku;
            tokuLeft.SaveImage("result/LeftToku.jpg");



            //画像2の特徴点をoutput1に出力
            Cv2.DrawKeypoints(Rsrc, keyPointsRight, tokuRight);
            Image imageRightToku = BitmapConverter.ToBitmap(tokuRight);

            pictureBox4.SizeMode = PictureBoxSizeMode.Zoom;
            pictureBox4.Image    = imageRightToku;
            tokuRight.SaveImage("result/RightToku.jpg");

            //総当たりマッチング
            matcher = DescriptorMatcher.Create("BruteForce");
            matches = matcher.Match(descriptorLeft, descriptorRight);

            Cv2.DrawMatches(Lsrc, keyPointsLeft, Rsrc, keyPointsRight, matches, output);
            output.SaveImage(@"result\output.jpg");

            int size         = matches.Count();
            var getPtsSrc    = new Vec2f[size];
            var getPtsTarget = new Vec2f[size];

            int count = 0;

            foreach (var item in matches)
            {
                var ptSrc    = keyPointsLeft[item.QueryIdx].Pt;
                var ptTarget = keyPointsRight[item.TrainIdx].Pt;
                getPtsSrc[count][0]    = ptSrc.X;
                getPtsSrc[count][1]    = ptSrc.Y;
                getPtsTarget[count][0] = ptTarget.X;
                getPtsTarget[count][1] = ptTarget.Y;
                count++;
            }

            // SrcをTargetにあわせこむ変換行列homを取得する。ロバスト推定法はRANZAC。
            var hom = Cv2.FindHomography(
                InputArray.Create(getPtsSrc),
                InputArray.Create(getPtsTarget),
                HomographyMethods.Ransac);

            // 行列homを用いてSrcに射影変換を適用する。
            Mat WarpedSrcMat = new Mat();

            Cv2.WarpPerspective(
                Lsrc, WarpedSrcMat, hom,
                new OpenCvSharp.Size(Rsrc.Width, Rsrc.Height));

            WarpedSrcMat.SaveImage(@"result\Warap.jpg");

            //画像1の特徴点をoutput1に出力
            Image imageLeftSyaei = BitmapConverter.ToBitmap(WarpedSrcMat);

            pictureBox5.SizeMode = PictureBoxSizeMode.Zoom;
            pictureBox5.Image    = imageLeftSyaei;


            //画像2の特徴点をoutput1に出力
            Image imageRightSyaei = BitmapConverter.ToBitmap(Rsrc);

            pictureBox6.SizeMode = PictureBoxSizeMode.Zoom;
            pictureBox6.Image    = imageRightSyaei;


            Mat LmatFloat = new Mat();

            WarpedSrcMat.ConvertTo(LmatFloat, MatType.CV_16SC3);
            Mat[] LmatPlanes = LmatFloat.Split();

            Mat RmatFloat = new Mat();

            Rsrc.ConvertTo(RmatFloat, MatType.CV_16SC3);
            Mat[] RmatPlanes = RmatFloat.Split();

            Mat diff0 = new Mat();
            Mat diff1 = new Mat();
            Mat diff2 = new Mat();


            Cv2.Absdiff(LmatPlanes[0], RmatPlanes[0], diff0);
            Cv2.Absdiff(LmatPlanes[1], RmatPlanes[1], diff1);
            Cv2.Absdiff(LmatPlanes[2], RmatPlanes[2], diff2);

            Cv2.MedianBlur(diff0, diff0, 5);
            Cv2.MedianBlur(diff1, diff1, 5);
            Cv2.MedianBlur(diff2, diff2, 5);

            diff0.SaveImage("result/diff0.jpg");
            diff1.SaveImage("result/diff1.jpg");
            diff2.SaveImage("result/diff2.jpg");

            Mat wiseMat = new Mat();

            Cv2.BitwiseOr(diff0, diff1, wiseMat);
            Cv2.BitwiseOr(wiseMat, diff2, wiseMat);

            wiseMat.SaveImage("result/wiseMat.jpg");

            Mat openingMat = new Mat();

            Cv2.MorphologyEx(wiseMat, openingMat, MorphTypes.Open, new Mat());

            Mat dilationMat = new Mat();

            Cv2.Dilate(openingMat, dilationMat, new Mat());
            Cv2.Threshold(dilationMat, dilationMat, 100, 255, ThresholdTypes.Binary);
            dilationMat.SaveImage(@"result\dilationMat.jpg");

            Mat LaddMat = new Mat();
            Mat RaddMat = new Mat();

            Console.WriteLine(dilationMat.GetType());
            Console.WriteLine(Rsrc.GetType());

            // dilationMatはグレースケールなので合成先のMatと同じ色空間に変換する
            Mat dilationScaleMat = new Mat();
            Mat dilationColorMat = new Mat();

            Cv2.ConvertScaleAbs(dilationMat, dilationScaleMat);
            Cv2.CvtColor(dilationScaleMat, dilationColorMat, ColorConversionCodes.GRAY2RGB);

            Cv2.AddWeighted(WarpedSrcMat, 0.3, dilationColorMat, 0.7, 0, LaddMat);
            Cv2.AddWeighted(Rsrc, 0.3, dilationColorMat, 0.7, 0, RaddMat);

            Image LaddImage = BitmapConverter.ToBitmap(LaddMat);

            pictureBox7.SizeMode = PictureBoxSizeMode.Zoom;
            pictureBox7.Image    = LaddImage;

            Image RaddImage = BitmapConverter.ToBitmap(RaddMat);

            pictureBox8.SizeMode = PictureBoxSizeMode.Zoom;
            pictureBox8.Image    = RaddImage;

            RaddMat.SaveImage(@"result\Result.jpg");

            MessageBox.Show("Done!");
        }
        public static unsafe void Accumulate(Mat edges, Mat dx, Mat dy, int minRadius, int maxRadius, float idp, List <Mat> accumVec, Mat <byte> nz)
        {
            Range boundaries = new Range(0, edges.Rows);

            int acols = (int)Math.Ceiling(edges.Cols * idp);
            int arows = (int)Math.Ceiling(edges.Rows * idp);
            int astep = acols + 2;

            Mat        accumLocal = new Mat(arows + 2, acols + 2, MatType.CV_32SC1, Scalar.All(0));
            int *      adataLocal = (int *)accumLocal.Ptr(0);
            Mat <byte> nzLocal    = new Mat <byte>(nz.Rows, nz.Cols);
            int        startRow   = boundaries.Start;
            int        endRow     = boundaries.End;
            int        numCols    = edges.Cols;

            if (edges.IsContinuous() && dx.IsContinuous() && dy.IsContinuous())
            {
                numCols *= (boundaries.End - boundaries.Start);
                endRow   = boundaries.Start + 1;
            }

            for (int y = startRow; y < endRow; ++y)
            {
                byte * edgeData = (byte *)edges.Ptr(y);
                short *dxData   = (short *)dx.Ptr(y);
                short *dyData   = (short *)dy.Ptr(y);
                int    x        = 0;

                for (; x < numCols; ++x)
                {
                    for (; x < numCols && edgeData[x] == 0; ++x)
                    {
                        ;
                    }

                    if (x == numCols)
                    {
                        continue;
                    }

                    float vx, vy;
                    int   sx, sy, x0, y0, x1, y1;

                    vx = dxData[x];
                    vy = dyData[x];

                    if (vx == 0 && vy == 0)
                    {
                        continue;
                    }

                    float mag = (float)Math.Sqrt(vx * vx + vy * vy);

                    if (mag < 1.0f)
                    {
                        continue;
                    }

                    Point pt = new Point(x % edges.Cols, y + x / edges.Cols);
                    nzLocal.Set(pt.Y, pt.X, 1); //

                    sx = (int)Math.Round((vx * idp) * 1024 / mag);
                    sy = (int)Math.Round((vy * idp) * 1024 / mag);

                    x0 = (int)Math.Round((pt.X * idp) * 1024);
                    y0 = (int)Math.Round((pt.Y * idp) * 1024);

                    // Step from min_radius to max_radius in both directions of the gradient
                    for (int k1 = 0; k1 < 2; k1++)
                    {
                        x1 = x0 + minRadius * sx;
                        y1 = y0 + minRadius * sy;

                        for (int r = minRadius; r <= maxRadius; x1 += sx, y1 += sy, r++)
                        {
                            int x2 = x1 >> 10, y2 = y1 >> 10;
                            if ((uint)x2 >= (uint)acols ||
                                (uint)y2 >= (uint)arows)
                            {
                                break;
                            }

                            adataLocal[y2 * astep + x2]++;
                        }

                        sx = -sx; sy = -sy;
                    }
                }
            }

            accumVec.Add(accumLocal);
            Cv2.BitwiseOr(nz, nzLocal, nz);
        }
Exemple #19
0
        public void GetDiffFrame(int width, int height, out double[] buf)
        {
            buf = new double[width * height];
            var frame = new Mat();
            var diff  = new Mat();

            if (capture.Read(frame))
            {
                frame = frame.Resize(new Size(width, height));
                Cv2.CvtColor(frame, frame, ColorConversionCodes.BGR2GRAY);
                if (PrevFrame != null)
                {
                    diff = frame.Clone();
                    Cv2.Absdiff(frame, PrevFrame, diff);
                    Cv2.Threshold(diff, diff, byte.MaxValue * 0.25, byte.MaxValue, ThresholdTypes.Binary);

                    Point[][]        contours;
                    HierarchyIndex[] hierarchyIndexes;
                    Cv2.FindContours(diff.Clone(), out contours, out hierarchyIndexes, RetrievalModes.List, ContourApproximationModes.ApproxTC89KCOS);
                    if (contours.Length > 0)
                    {
                        var points = new List <Point>();
                        for (int idx_cnt = 0; idx_cnt < contours.GetLength(0); ++idx_cnt)
                        {
                            if (hierarchyIndexes[idx_cnt].Parent != -1)
                            {
                                continue;
                            }
                            points.AddRange(contours[idx_cnt]);
                        }
                        Cv2.DrawContours(diff, new List <List <Point> >(new List <Point>[] { new List <Point>(Cv2.ConvexHull(points.ToArray())) }), 0, new Scalar(byte.MaxValue), -1);
                    }
                    var masked = diff.Clone();
                    frame.CopyTo(masked, diff);
                    Cv2.BitwiseOr(diff, PrevDiffFrame, diff);
                    Cv2.AddWeighted(masked, 0.5, diff, 0.5, 0, diff);

                    if (PrevFrame != null)
                    {
                        unsafe
                        {
                            byte *p  = (byte *)frame.Data;
                            byte *pv = (byte *)diff.Data;
                            for (int i = 0; i < width * height; i++)
                            {
                                buf[i] = (double)pv[i] / byte.MaxValue;
                            }
                        }
                    }
                }
                if (PrevFrame == null)
                {
                    PrevFrame     = frame.Clone();
                    PrevDiffFrame = new Mat(PrevFrame.Size(), PrevFrame.Type());
                }
                else
                {
                    double weight = 0.75;
                    Cv2.AddWeighted(PrevFrame, weight, frame, 1 - weight, 0, PrevFrame);
                    PrevDiffFrame = diff.Clone();
                }
            }
        }
        static void Main(string[] args)
        {
            if (!Directory.Exists(Settings.Images.Output))
            {
                Directory.CreateDirectory(Settings.Images.Output);
            }

            if (!Directory.Exists(Settings.Images.Dump))
            {
                Directory.CreateDirectory(Settings.Images.Dump);
            }

            var listOfImages = Directory.GetFiles(Settings.Images.Source, "*.jpg").ToList();

            //!Uncomment next line for select images by freq
            listOfImages = listOfImages.Where(x => x.Contains("940")).ToList();

            //! Comment from this to dump loading for dump load, lol
            //? get list of all filenames without .jpg and generate cntr PalmsList
            listOfImages.ForEach(x => {
                x         = x.Remove(0, x.LastIndexOf('\\') + 1).Replace(".jpg", "");
                var owner = x.Substring(0, x.Length - 3);

                PalmsList.Add(new PalmModel()
                {
                    Id        = x.Substring(x.Length - 2),
                    Owner     = owner,
                    FileName  = x,
                    Directory = $@"{Settings.Images.Output}{owner}"
                });
            });

            //? get names and create name collection
            //? create dirs for saving data
            var userNames = PalmsList.DistinctBy(x => x.Owner);

            userNames.ForEach(x => {
                UsersList.Add(new UserModel()
                {
                    Name      = x.Owner,
                    Patterns  = new List <Mat> (),
                    Directory = x.Directory
                });

                if (Directory.Exists(x.Directory) && Directory.GetFiles(x.Directory).Length > 0)
                {
                    Directory.Delete(x.Directory, true);  // recursive
                }

                Directory.CreateDirectory(x.Directory);
            });

            Console.WriteLine($"Total users: {UsersList.Count}");
            Console.WriteLine($"Total palm collection: {PalmsList.Count}");

            var totalROIExtractionTime = new Stopwatch();

            totalROIExtractionTime.Start();

            //! ROI extraction
            Console.WriteLine($"[{DateTime.Now}] ROI extraction");
            var ROITask = Task.Factory.StartNew(() => {
                PalmsList.ForEach(x => {
                    Task.Factory.StartNew(() => {
                        var path      = $@"{Settings.Images.Source}\{x.FileName}.jpg";
                        x.SourceImage = Cv2.ImRead(path, ImreadModes.Color);

                        x.Height = x.SourceImage.Size().Height;
                        x.Width  = x.SourceImage.Size().Width;

                        //! apply threshold
                        Cv2.CvtColor(x.SourceImage, x.SourceImage, ColorConversionCodes.BGR2GRAY);

                        //                                          0, 255
                        x.ThresholdImage = x.SourceImage.Threshold(5, 255, ThresholdTypes.Otsu);

                        // save for debug
#if SAVEALLRESULTS
                        Cv2.ImWrite($@"{x.Directory}\binary_{x.Id}.jpg", x.ThresholdImage);
#endif

                        //! ROI extraction

                        var i1 = x.Height - 50;
                        var i2 = x.Width - 50;

                        var radius = 50;
                        int pX     = 0;
                        int pY     = 0;

                        for (int i = 50; i != i1; i++)
                        {
                            for (int j = 50; j != i2; j++)
                            {
                                if (x.ThresholdImage.Get <byte> (i, j) == Settings.COLOR_WHITE)
                                {
                                    int a = 0;
                                    for (a = 1; a < 360; a++)
                                    {
                                        var y1 = Convert.ToInt16(j + radius * Math.Cos(a * Math.PI / 180));
                                        var x1 = Convert.ToInt16(i - radius * Math.Sin(a * Math.PI / 180));

                                        if (x1 < 1 || x1 > i1 || y1 < 1 || y1 > i2 || x.ThresholdImage.Get <byte> (x1, y1) == Settings.COLOR_BLACK)
                                        {
                                            break;
                                        }
                                    }

                                    if (a == 360)
                                    {
                                        radius += 10;
                                        pX      = i;
                                        pY      = j;
                                    }
                                }
                            }
                        }

                        radius -= 10;

                        var x0    = Convert.ToInt16(pY - Math.Sqrt(2) * radius / 2);
                        var y0    = Convert.ToInt16(pX - Math.Sqrt(2) * radius / 2);
                        var wsize = Convert.ToInt16(Math.Sqrt(2) * radius);

                        var rect = new Rect(x0, y0, wsize, wsize);

                        // for visual debug
                        Mat drawROIImage = new Mat();
                        x.SourceImage.CopyTo(drawROIImage);
                        drawROIImage.Rectangle(rect, Scalar.White);

                        x.ROI = new Mat(x.SourceImage, rect)
                                .Resize(new Size(216, 216));

                        Cv2.Rotate(x.ROI, x.ROI, RotateFlags.Rotate90Counterclockwise);

#if SAVEALLRESULTS
                        Cv2.ImWrite($@"{x.Directory}\ROIOnSource_{x.Id}.jpg", drawROIImage);
                        Cv2.ImWrite($@"{x.Directory}\ROI_{x.Id}.jpg", x.ROI);
#endif
                    }, TaskCreationOptions.AttachedToParent | TaskCreationOptions.RunContinuationsAsynchronously);
                });
            });

            ROITask.Wait();
            totalROIExtractionTime.Stop();
            Console.WriteLine($"[{DateTime.Now}] Total ROI extracton time: {totalROIExtractionTime.Elapsed}");

            //! Create dump
            Dump.ROI.Create(Settings.Images.Dump, PalmsList);

            //! Uncomment next block for loading images from dump and comment all lines before this
            // PalmsList = Dump.ROI.Load(Settings.Images.Dump, listOfImages);
            // var countFrom = 0;
            // var countTo = PalmsList.Count;
            // ------------------------------

            //! Apply filters

            Console.WriteLine($"[{DateTime.Now}] Apply filters to ROI image");
            totalROIExtractionTime.Reset();
            totalROIExtractionTime.Start();

            var filtersTask = Task.Factory.StartNew(() => {
                PalmsList.ForEach(x => {
                    Task.Factory.StartNew(() => {
                        //! Reduce noise
                        Cv2.MedianBlur(x.ROI, x.ROI, 5);

#if SAVEALLRESULTS
                        Cv2.ImWrite($@"{x.Directory}\ROI_Median_{x.Id}.jpg", x.ROI);
#endif

                        // Cv2.CvtColor(x.ROI, x.ROI, ColorConversionCodes.BGR2GRAY);
                        Cv2.FastNlMeansDenoising(x.ROI, x.ROI);
                        Cv2.CvtColor(x.ROI, x.ROI, ColorConversionCodes.GRAY2BGR);

#if SAVEALLRESULTS
                        Cv2.ImWrite($@"{x.Directory}\reduce_noise_{x.Id}.jpg", x.ROI);
#endif

                        //! Equalize hist
                        var element = Cv2.GetStructuringElement(MorphShapes.Cross, Settings.ElementSize);  // new Mat(7, 7, MatType.CV_8U);
                        Cv2.MorphologyEx(x.ROI, x.ROI, MorphTypes.Open, element);
                        Cv2.CvtColor(x.ROI, x.ROI, ColorConversionCodes.BGR2YUV);

                        // Cv2.EqualizeHist(x.ROI, x.ROI);
                        var RGB = Cv2.Split(x.ROI);

                        RGB[0] = RGB[0].EqualizeHist();
                        RGB[1] = RGB[1].EqualizeHist();
                        RGB[2] = RGB[2].EqualizeHist();

                        Cv2.Merge(RGB, x.ROI);
                        Cv2.CvtColor(x.ROI, x.ROI, ColorConversionCodes.YUV2BGR);

#if SAVEALLRESULTS
                        Cv2.ImWrite($@"{x.Directory}\equalized_hist_{x.Id}.jpg", x.ROI);
#endif

                        //! Invert image
                        Cv2.BitwiseNot(x.ROI, x.ROI);

#if SAVEALLRESULTS
                        Cv2.ImWrite($@"{x.Directory}\inverted_{x.Id}.jpg", x.ROI);
#endif

                        //! Erode image
                        Cv2.CvtColor(x.ROI, x.ROI, ColorConversionCodes.BGR2GRAY);
                        Cv2.Erode(x.ROI, x.ROI, element);

#if SAVEALLRESULTS
                        Cv2.ImWrite($@"{x.Directory}\eroded_{x.Id}.jpg", x.ROI);
#endif

                        //! Skeletonize
                        var skel   = new Mat(x.ROI.Size(), MatType.CV_8UC1, new Scalar(0));
                        var temp   = new Mat();
                        var eroded = new Mat();

                        do
                        {
                            Cv2.MorphologyEx(x.ROI, eroded, MorphTypes.Erode, element);
                            Cv2.MorphologyEx(eroded, temp, MorphTypes.Dilate, element);
                            Cv2.Subtract(x.ROI, temp, temp);
                            Cv2.BitwiseOr(skel, temp, skel);
                            eroded.CopyTo(x.ROI);
                        } while (Cv2.CountNonZero(x.ROI) != 0);

                        //! Threshold skeletonized image
                        var thr = skel.Threshold(0, 255, ThresholdTypes.Binary);

                        //! Remove contours
                        thr.Line(new Point(0, 0), new Point(0, thr.Height), Scalar.Black, 2);                  // rm left contour
                        thr.Line(new Point(0, 0), new Point(thr.Width, 0), Scalar.Black, 2);                   // rm top contour

                        thr.Line(new Point(thr.Width, thr.Height), new Point(thr.Width, 0), Scalar.Black, 2);  // rm right contour
                        thr.Line(new Point(thr.Width, thr.Height), new Point(0, thr.Height), Scalar.Black, 2); // rm bot contour

                        //! Normalize contours
                        element = Cv2.GetStructuringElement(MorphShapes.Ellipse, new Size(6, 6));

                        Cv2.Dilate(thr, thr, element);
                        Cv2.Erode(thr, thr, element);

                        Cv2.MorphologyEx(thr, thr, MorphTypes.Gradient, element);

                        Cv2.ImWrite($@"{x.Directory}\{x.Id}.jpg", thr);

                        var owner = UsersList.Find(u => u.Name == x.Owner);
                        owner.Patterns.Add(thr);  // add thresholded image to user patterns
                    }, TaskCreationOptions.AttachedToParent | TaskCreationOptions.RunContinuationsAsynchronously);
                });
            });

            filtersTask.Wait();
            totalROIExtractionTime.Stop();
            Console.WriteLine($"[{DateTime.Now}] Total apply filters time: {totalROIExtractionTime.Elapsed}");

            //! Create dump with users and they patterns
            Dump.Patterns.Create(Settings.Images.Dump, UsersList);

            //! Create CSV file
            Dump.CSV.Create(Settings.Images.CSV, PalmsList);
        }
Exemple #21
0
    public void proessHand(UnityEngine.Texture texture, ref Texture2D output)
    {
        Mat processingImage = OpenCvSharp.Unity.TextureToMat(texture as WebCamTexture);
        Mat frameCopy       = processingImage.Clone();

        Cv2.CvtColor(processingImage, processingImage, ColorConversionCodes.BGR2HSV);
        Mat maskedImage      = new Mat();
        Mat maskedSkin       = new Mat();
        Mat maskedBackground = new Mat();

        if (Input.GetKey(KeyCode.M))
        {
            useML = !useML;
        }
        if (Input.GetKey(KeyCode.R))
        {
            realTimeLearning = !realTimeLearning;
        }
        if (Input.GetKey(KeyCode.N))
        {
            deNoise = !deNoise;
        }

        if (deNoise)
        {
            Cv2.FastNlMeansDenoising(processingImage, processingImage, 1, 2, 5);
        }

        if (!useML)
        {
            drawColorSampler(processingImage);

            if (Input.GetKey(KeyCode.B))
            {
                calibrateBackground(frameCopy);
            }

            if (Input.GetKey(KeyCode.S))
            {
                calibrateSkin(frameCopy);
            }

            background = getBackgroundMask(frameCopy);
            skin       = getSkinMask(frameCopy);

            Cv2.BitwiseNot(background, background);
            Cv2.BitwiseOr(skin, background, foreground);

            Mat debug = getHandContour(skin, frameCopy);

            Cv2.BitwiseAnd(processingImage, processingImage, maskedSkin, skin);

            Cv2.BitwiseAnd(processingImage, processingImage, maskedBackground, background);

            Cv2.BitwiseAnd(frameCopy, frameCopy, maskedImage, foreground);

            Cv2.CvtColor(maskedImage, maskedImage, ColorConversionCodes.HSV2BGR);
            Cv2.CvtColor(maskedSkin, maskedSkin, ColorConversionCodes.HSV2BGR);
            Cv2.CvtColor(maskedBackground, maskedBackground, ColorConversionCodes.HSV2BGR);
            // Cv2.CvtColor(debug, debug, ColorConversionCodes.HSV2BGR);

            if (Input.GetKey(KeyCode.Q))
            {
                output = OpenCvSharp.Unity.MatToTexture(maskedSkin, output);
            }
            else if (Input.GetKey(KeyCode.W))
            {
                output = OpenCvSharp.Unity.MatToTexture(maskedBackground, output);
            }
            else
            {
                output = OpenCvSharp.Unity.MatToTexture(debug, output);
            }
        }
        else
        {
            background = getBackgroundMask(processingImage);
            if (realTimeLearning)
            {
                bsub.Apply(processingImage, background);
            }
            else
            {
                bsub.Apply(processingImage, background, 0);
            }

            Mat debug  = null;
            Mat kernel = Cv2.GetStructuringElement(MorphShapes.Ellipse, new Size(8, 8));
            Cv2.MorphologyEx(background, background, MorphTypes.Open, kernel);
            Cv2.MorphologyEx(background, background, MorphTypes.Open, kernel);
            Cv2.MorphologyEx(background, background, MorphTypes.Close, kernel);
            //Cv2.Dilate(background, background, kernel, new Point(-1, -1), 1);
            Cv2.BitwiseAnd(processingImage, processingImage, maskedBackground, background);

            debug = getHandContour(background, processingImage);
            // Cv2.CvtColor(maskedBackground, maskedBackground, ColorConversionCodes.HSV2BGR);
            //Cv2.CvtColor(processingImage, processingImage, ColorConversionCodes.HSV2BGR);
            Cv2.CvtColor(debug, debug, ColorConversionCodes.HSV2BGR);
            Cv2.CvtColor(background, background, ColorConversionCodes.GRAY2BGR);
            if (Input.GetKey(KeyCode.E))
            {
                output = OpenCvSharp.Unity.MatToTexture(background, output);
            }
            else
            {
                output = OpenCvSharp.Unity.MatToTexture(debug, output);
            }
        }
    }
Exemple #22
0
        static void Main(string[] args)
        {
            // Used to check memory leak
            //for (int i = 0; i < 1000; i++)
            using (var state = new ThreadLocal <FormExtractionHandle>(NativeFormExtraction.CreateFormExtraction))
            {
                GC.Collect();
                List <string> pathFiles = GetSamplesAndCleanUpResults();

                // For testing:
                pathFiles = pathFiles.Where(m => m.Contains("form9")).ToList();

                int numThread      = 1;            // Environment.ProcessorCount;
                var showDebugImage = true;         // If true, you may want to use: numThread = 1.

                Parallel.ForEach(pathFiles, new ParallelOptions {
                    MaxDegreeOfParallelism = numThread
                }, pathFile =>
                {
                    FormExtractionHandle handle = state.Value;

                    NativeFormExtraction.SetOptions(handle, 800, 25, 15, 5, 20000, 50000, showDebugImage);

                    var resizeWidth = 800;
                    var orig        = new Mat(pathFile);
                    var image       = new Mat(pathFile, ImreadModes.GrayScale);

                    Cv2.AdaptiveThreshold(image, image, 255, AdaptiveThresholdTypes.MeanC, ThresholdTypes.Binary, 9, 4);

                    // Resize image if too large.
                    if (image.Width > resizeWidth)
                    {
                        var height = resizeWidth * image.Height / image.Width;
                        Cv2.Resize(image, image, new Size(resizeWidth, height));
                    }

                    Cv2.BitwiseNot(image, image);
                    Cv2.Dilate(image, image, Cv2.GetStructuringElement(MorphShapes.Cross, new Size(2, 2)));

                    MatOfByte mat             = new MatOfByte(image);
                    MatIndexer <byte> indexer = mat.GetIndexer();

                    var row      = image.Height;
                    var col      = image.Width;
                    Mat newImage = new Mat(row, col, MatType.CV_8UC3);
                    newImage.SetTo(Scalar.Black);

                    // We must determine if it "may" be an interesting blob.
                    Stopwatch watch = new Stopwatch();
                    watch.Start();

                    int[] imgData = new int[row * col];
                    for (int y = 0; y < row; y++)
                    {
                        for (int x = 0; x < col; x++)
                        {
                            imgData[y + x * row] = indexer[y, x];
                        }
                    }

                    var result = NativeFormExtraction.RunFormExtraction(handle, imgData, row, col);
                    if (result != 0)
                    {
                        throw new Exception("Unknown error occured with the function: RunFormExtraction");
                    }
                    watch.Stop();
                    Console.WriteLine("Duration: " + watch.Elapsed);

                    if (showDebugImage)
                    {
                        var debugImg = NativeFormExtraction.GetDebugImage(handle, row * col);

                        var img = CreateImage(debugImg, row, col, hasColor: true);
                        Cv2.BitwiseOr(newImage, img, newImage);

                        Cv2.BitwiseNot(image, image);
                        int width  = 400;
                        var height = width * image.Height / image.Width;
                        Cv2.Resize(orig, orig, new Size(width, height));
                        Cv2.Resize(image, image, new Size(width, height));
                        Cv2.Resize(newImage, newImage, new Size(width, height));

                        using (new Window("orig", orig))
                            using (new Window("pre", image))
                                using (new Window("post", newImage))
                                {
                                    Cv2.WaitKey();
                                    Cv2.DestroyAllWindows();
                                }
                    }

                    // Dispose.
                    orig.Dispose();
                    image.Dispose();
                    newImage.Dispose();
                    mat.Dispose();
                });
            }

            Console.WriteLine("End");
            Console.ReadLine();
        }
Exemple #23
0
        static void Main(string[] args)
        {
            //! Create directories for output images
            if (!Directory.Exists(Settings.Images.Output))
            {
                Directory.CreateDirectory(Settings.Images.Output);
            }

            //! create list of images
            var listOfImages = Directory.GetFiles(Settings.Images.Source, "*.jpg")
                               .Where(x => x.Contains("940"))
                               .Where(x => x.Contains("_l_"))
                               // .Take (6) // take one palm to test
                               .ToList();

            //! variables for ROI
            double radius, a, xx, yy, predictX, predictY, angle;

            Point   centerOfPalm;
            Point2f centerOfImage;
            Rect    rect;

            //! variables for extracting file parameters
            PalmModel[] Palms = new PalmModel[listOfImages.Count];

            //! matherials
            Mat sourceHandle, thresholdHandle, roiHandle, skel, rotatedSource, eroded, thr, matrix = new Mat();
            Mat element = Cv2.GetStructuringElement(MorphShapes.Cross, Settings.ElementSize);

            Mat[] RGB;

            for (int i = 0; i != listOfImages.Count; i++)
            {
                Palms[i]           = new PalmModel();
                Palms[i].Filename  = listOfImages[i].Remove(0, listOfImages[i].LastIndexOf('/') + 1).Replace(".jpg", "");
                Palms[i].Owner     = Palms[i].Filename.Substring(0, Palms[i].Filename.IndexOf('_'));
                Palms[i].Id        = Palms[i].Filename.Substring(Palms[i].Filename.LastIndexOf('_') + 2);
                Palms[i].Type      = (Palms[i].Filename.IndexOf('r') == -1 ? 'l' : 'r');
                Palms[i].Directory = $"{Settings.Images.Output}{Palms[i].Type}/{Palms[i].Owner}";
                Palms[i].Path      = $"{Settings.Images.Source}/{Palms[i].Filename}.jpg";

                if (Directory.Exists(Palms[i].Directory) && Directory.GetFiles(Palms[i].Directory).Length > 0)
                {
                    Directory.Delete(Palms[i].Directory, true); // recursive
                }
                Directory.CreateDirectory(Palms[i].Directory);
            }

            Console.WriteLine($"[{DateTime.Now}] Transform started");

            var workerTime = new Stopwatch();

            workerTime.Start();

            for (int i = 0; i != listOfImages.Count; i++)
            {
                if (i % 10 == 0)
                {
                    Console.WriteLine($"{i}.{listOfImages.Count}");
                }

                // Read sample image
                sourceHandle = Cv2.ImRead(Palms[i].Path, ImreadModes.AnyColor);

                // Get center of image
                centerOfImage = new Point2f(sourceHandle.Width / 2, sourceHandle.Height / 2);

                // Start loop by rotations
                for (int j = 0; j != 180; j++)
                {
                    // change rotation angle
                    angle = j * 2;

                    rotatedSource = new Mat();
                    // get and apply image rotation matrix by angle
                    matrix = Cv2.GetRotationMatrix2D(centerOfImage, angle, 1.0);
                    Cv2.WarpAffine(sourceHandle, rotatedSource, matrix, new Size(sourceHandle.Width, sourceHandle.Height));

                    // apply threshold
                    thresholdHandle = rotatedSource.Threshold(0, 255, ThresholdTypes.Otsu);

                    /*// apply transform distance and convert to cv_8u
                     * thresholdHandle.DistanceTransform (DistanceTypes.L2, DistanceMaskSize.Precise);
                     * thresholdHandle.ConvertTo (thresholdHandle, MatType.CV_8U);
                     *
                     * // get center of palm
                     * centerOfPalm = GetHandCenter (thresholdHandle, out radius);*/
                    double radius1;
                    Cv2.DistanceTransform(thresholdHandle, matrix, DistanceTypes.L2, DistanceMaskSize.Mask5);
                    matrix.ImWrite($"{Palms[i].Directory}/002_distance-transform.jpg");

                    int[] maxIdx = new int[2];
                    int[] minIdx = new int[2];
                    Cv2.MinMaxIdx(matrix, out radius1, out radius, minIdx, maxIdx, thresholdHandle);
                    centerOfPalm = new OpenCvSharp.Point(maxIdx[1], maxIdx[0]);

                    // calculate ROI
                    a = (2 * radius) / Math.Sqrt(2);

                    xx = centerOfPalm.X - radius * Math.Cos(45 * Math.PI / 180);
                    yy = centerOfPalm.Y - radius * Math.Sin(45 * Math.PI / 180);

                    if (xx < 0)
                    {
                        a += xx; // 200 + -2 -> 200 - 2 = 198
                        xx = 0;
                    }

                    if (yy < 0)
                    {
                        a += yy; // 120 + -10 -> 120 - 10 = 110
                        yy = 0;
                    }

                    predictX = xx + a;
                    predictY = yy + a;

                    if (predictX > rotatedSource.Width)       // if more
                    {
                        xx -= predictX - rotatedSource.Width; // (590 - 580) = 10
                    }

                    if (predictY > rotatedSource.Height)
                    {
                        yy -= predictY - rotatedSource.Height; // 800 - 640 = 160
                    }

                    /*
                     *  rect = new Rect(new Point(xx + 20, yy + 20), new Size(a, a));
                     *  rect = new Rect(new Point(xx - 20, yy - 20), new Size(a, a));
                     *  rect = new Rect(new Point(xx - 20, yy + 20), new Size(a, a));
                     *  rect = new Rect(new Point(xx + 20, yy - 20), new Size(a, a));
                     */

                    rect = new Rect(new Point(xx, yy), new Size(a, a));

                    roiHandle = new Mat(rotatedSource, rect)
                                .Resize(Const.ResizeValue);

                    //! apply filters
                    Cv2.MedianBlur(roiHandle, roiHandle, 5);

                    // Cv2.CvtColor(roiHandle, roiHandle, ColorConversionCodes.BGR2GRAY);
                    Cv2.FastNlMeansDenoising(roiHandle, roiHandle);
                    Cv2.CvtColor(roiHandle, roiHandle, ColorConversionCodes.GRAY2BGR);

                    //! Equalize hist
                    Cv2.MorphologyEx(roiHandle, roiHandle, MorphTypes.Open, element);
                    Cv2.CvtColor(roiHandle, roiHandle, ColorConversionCodes.BGR2YUV);

                    RGB    = Cv2.Split(roiHandle);
                    RGB[0] = RGB[0].EqualizeHist();
                    RGB[1] = RGB[1].EqualizeHist();
                    RGB[2] = RGB[2].EqualizeHist();

                    Cv2.Merge(RGB, roiHandle);
                    Cv2.CvtColor(roiHandle, roiHandle, ColorConversionCodes.YUV2BGR);

                    //! Invert image
                    Cv2.BitwiseNot(roiHandle, roiHandle);

                    //! Erode image
                    Cv2.CvtColor(roiHandle, roiHandle, ColorConversionCodes.BGR2GRAY);
                    Cv2.Erode(roiHandle, roiHandle, element);

                    //! Skeletonize
                    skel          = new Mat(roiHandle.Size(), MatType.CV_8UC1, Const.ZeroScalar);
                    rotatedSource = new Mat();
                    eroded        = new Mat();
                    thr           = new Mat();

                    do
                    {
                        Cv2.MorphologyEx(roiHandle, eroded, MorphTypes.Erode, element);
                        Cv2.MorphologyEx(eroded, rotatedSource, MorphTypes.Dilate, element);
                        Cv2.Subtract(roiHandle, rotatedSource, rotatedSource);
                        Cv2.BitwiseOr(skel, rotatedSource, skel);
                        eroded.CopyTo(roiHandle);
                    } while (Cv2.CountNonZero(roiHandle) != 0);

                    //! Threshold skeletonized image
                    thr = skel.Threshold(0, 255, ThresholdTypes.Binary);

                    //! Remove contours
                    thr.Line(Const.Zero, new Point(0, thr.Height), Scalar.Black, 2);                       // rm left contour
                    thr.Line(Const.Zero, new Point(thr.Width, 0), Scalar.Black, 2);                        // rm top contour
                    thr.Line(new Point(thr.Width, thr.Height), new Point(thr.Width, 0), Scalar.Black, 2);  // rm right contour
                    thr.Line(new Point(thr.Width, thr.Height), new Point(0, thr.Height), Scalar.Black, 2); // rm bot contour

                    //! Partion lines
                    if (Const.MODE_TYPE)
                    {
                        Cv2.GaussianBlur(thr, thr, new Size(7, 7), sigmaX: 5);
                        Cv2.MorphologyEx(thr, thr, MorphTypes.Gradient, element);
                        Cv2.BitwiseNot(thr, thr);
                    }
                    thr.ImWrite($"{Palms[i].Directory}/{Palms[i].Id}-{angle}.jpg");
                }
            }
            workerTime.Stop();
            Console.WriteLine($"[{DateTime.Now}] Elapsed time: {workerTime.Elapsed}");
        }