public void Run_ConnectedComponents(Mat Source, OutputArray _Dst)
        {
            Mat Dst = _Dst.GetMat();

            using (Mat Src = new Mat())
            {
                Source.CopyTo(Src);

                int nLabels = Cv2.ConnectedComponentsWithStats(Src, _Label, _Stats, _Centroids, PixelConnectivity.Connectivity8, MatType.CV_32SC1);

                unsafe
                {
                    _MaxArea  = int.MinValue;
                    _MinArea  = int.MaxValue;
                    _ObjCount = _Stats.Rows - 1;

                    for (int H = 1, ObjArea = 0; H < _Stats.Rows; H++)
                    {
                        IntPtr ptr = _Stats.Ptr(H);
                        int *  p   = (int *)ptr.ToPointer();
                        ObjArea = p[4];
                        if (ObjArea > _MaxArea)
                        {
                            _MaxArea = ObjArea;
                        }
                        if (ObjArea < _MinArea)
                        {
                            _MinArea = ObjArea;
                        }
                    }
                }
            }
        }
Exemple #2
0
    void DetectLaser()
    {
        Mat[] bgrChannels = new Mat[3];
        Cv2.Split(videoSourceImage, out bgrChannels);

        Mat rt = new Mat();

        Cv2.Threshold(bgrChannels[2], rt, 240.0, 255.0, ThresholdTypes.Binary);

        Cv2.GaussianBlur(rt, rt, new Size(5, 5), 1);
        rt *= 255;

        Mat labels    = new Mat();
        Mat stats     = new Mat();
        Mat centroids = new Mat();

        Cv2.ConnectedComponentsWithStats(rt, labels, stats, centroids);

        if (centroids.Rows > 1)
        {
            Cv2.Circle(videoSourceImage, (int)centroids.At <double>(1, 0), (int)centroids.At <double>(1, 1), 20, new Scalar(255, 255, 255));
            Cv2.Circle(cannyImage, (int)centroids.At <double>(1, 0), (int)centroids.At <double>(1, 1), 20, new Scalar(255, 255, 255));
        }

        Cv2.Flip(videoSourceImage, videoSourceImage, FlipMode.XY);
        Cv2.Flip(cannyImage, cannyImage, FlipMode.XY);
        Cv2.ImShow("SuperLaserDetect", videoSourceImage);
        Cv2.ImShow("Processed WebCam", cannyImage);
    }
        //Find outer defect
        static void FindContour_and_outer_defect(Mat img, List <Point[]> contours_final, ref int nLabels, out int [,] stats, string mode)
        {
            // variable
            OpenCvSharp.Point[][] temp = new Point[1][];
            //0: 內圈 ; 1: 外圈
            OpenCvSharp.Point[] contour_now;
            if (mode == "inner")
            {
                contour_now = contours_final[0];
            }
            else
            {
                contour_now = contours_final[1];
            }
            // Convex hull


            var ellipsecontour = Cv2.FitEllipse(contour_now);

            Mat convex_mask_img = Mat.Zeros(img.Size(), MatType.CV_8UC1);

            Cv2.Ellipse(convex_mask_img, ellipsecontour, 255, -1);


            // Contour
            temp[0] = contour_now;
            Mat contour_mask_img = Mat.Zeros(img.Size(), MatType.CV_8UC1);

            Cv2.DrawContours(contour_mask_img, temp, -1, 255, -1);


            Mat diff_image = contour_mask_img ^ convex_mask_img;


            //Opening
            Mat kernel = Mat.Ones(4, 4, MatType.CV_8UC1);//改變凹角大小

            diff_image = diff_image.MorphologyEx(MorphTypes.Open, kernel);


            //=========================吃掉邊界=======================================
            //temp[0] = contour_now;
            //Cv2.DrawContours(diff_image, temp, -1, 0, 3);
            //================================================================
            convex_mask_img.SaveImage("./" + mode + "convex" + ".jpg");
            contour_mask_img.SaveImage("./" + mode + "contour" + ".jpg");
            diff_image.SaveImage("./" + mode + "mask" + ".jpg");
            //Connected Component
            var labelMat     = new MatOfInt();
            var statsMat     = new MatOfInt();// Row: number of labels Column: 5
            var centroidsMat = new MatOfDouble();

            nLabels = Cv2.ConnectedComponentsWithStats(diff_image, labelMat, statsMat, centroidsMat);

            var labels = labelMat.ToRectangularArray();

            stats = statsMat.ToRectangularArray();
            var centroids = centroidsMat.ToRectangularArray();
        }
Exemple #4
0
        private void bn_Blob_Click(object sender, RoutedEventArgs e)
        {
            if (listImage.Count > 0)
            {
                string strTitle = listImage[_nSelWin].Title;
                Mat    matSrc   = listImage[_nSelWin].fn_GetImage();
                if (matSrc.Channels() == 1)
                {
                    Mat matDst       = matSrc.Clone();
                    Mat matLabel     = new Mat();
                    Mat matStats     = new Mat();
                    Mat matCentroids = new Mat();
                    int width        = matSrc.Cols;
                    int height       = matSrc.Rows;
                    timeStart = DateTime.Now;

                    int NumofLabels = Cv2.ConnectedComponentsWithStats(matSrc, matLabel, matStats, matCentroids);

                    unsafe
                    {
                        byte *pDst       = matDst.DataPointer;
                        int * pLabel     = (int *)matLabel.DataPointer;
                        int * pStats     = (int *)matStats.DataPointer;
                        int * pCentroids = (int *)matCentroids.DataPointer;

                        //---------------------------------------------------------------------------
                        // Label 색칠하기.
                        //for (int stepY = 0; stepY < matLabel.Rows; stepY++)
                        //{
                        //    for (int stepX = 0; stepX < matLabel.Cols; stepX++)
                        //    {
                        //        if (pLabel[stepY * matLabel.Cols + stepX] > 0)
                        //        {
                        //            pDst[stepY * matLabel.Cols + stepX] = 128;
                        //        }
                        //    }
                        //}

                        for (int i = 0; i < NumofLabels; i++)
                        {
                            //pStats[i];
                            Cv2.Rectangle(matDst, new OpenCvSharp.Rect(pStats[i * 5], pStats[(i * 5) + 1], pStats[(i * 5) + 2], pStats[(i * 5) + 3]), new Scalar(128));
                        }
                    }

                    fn_WriteLog($"[Blob] {strTitle} ({(DateTime.Now - timeStart).TotalMilliseconds} ms)");
                    fn_NewImage(matDst, $"{strTitle}_Blob");
                }
                else
                {
                    fn_WriteLog($"[Blob] {strTitle} is Color.");
                }
            }
        }
Exemple #5
0
        public static void ExecLabeling()
        {
            string name   = $"C:\\Users\\yuuki\\Desktop\\Pre_Data01_t019_page_0011.tif";
            Mat    origin = Cv2.ImRead(name, ImreadModes.Color);
            Mat    tmp    = Cv2.ImRead(name, 0);
            Mat    bin    = new Mat();

            Cv2.Threshold(tmp, bin, 0, 255, ThresholdTypes.Otsu | ThresholdTypes.Binary);

            // ラベリング
            Mat status   = new Mat();
            Mat center   = new Mat();
            Mat labelTmp = new Mat();
            int nLabels  = Cv2.ConnectedComponentsWithStats(bin, labelTmp, status, center, PixelConnectivity.Connectivity8, MatType.CV_32SC1);

            var param = status.GetGenericIndexer <int>();

            for (int label = 0; label < nLabels; label++)
            {
                int    x         = param[label, 0];
                int    y         = param[label, 1];
                int    width     = param[label, 2];
                int    height    = param[label, 3];
                int    area      = param[label, 4];
                double occupancy = (double)area / (height * width);
                double aspect    = (double)height / width;
                if (CheckInRange(width, height, area, occupancy, aspect))
                {
                    origin.Rectangle(new Rect(x, y, width, height), new Scalar(0, 0, 255), 1);
                }
            }
            Cv2.NamedWindow("結果", WindowMode.AutoSize);
            Cv2.ImShow("結果", origin);
            Cv2.WaitKey(50);
            Cv2.WaitKey(0);
            Cv2.DestroyAllWindows();
            Cv2.ImWrite(@"C:\\Users\\yuuki\\Desktop\\2.tif", origin);
        }
Exemple #6
0
        public void Detect(Mat bin, ref List <CellState> countList_1, int t, int z)
        {
            List <CellState> countList = new List <CellState>();

            // ラベリング
            Mat           status   = new Mat();
            Mat           center   = new Mat();
            Mat           labelTmp = new Mat();
            int           nLabels  = Cv2.ConnectedComponentsWithStats(bin, labelTmp, status, center, PixelConnectivity.Connectivity8, MatType.CV_32SC1);
            List <Scalar> colors   = new List <Scalar>();

            var param = status.GetGenericIndexer <int>();

            for (int label = 0; label < nLabels; label++)
            {
                int    x         = param[label, 0];
                int    y         = param[label, 1];
                int    width     = param[label, 2];
                int    height    = param[label, 3];
                int    area      = param[label, 4];
                double occupancy = (double)area / (height * width);
                double aspect    = (double)height / width;

                //ラべリング情報による閾値設定(閾値以内なら分裂候補、以外ならノイズ)
                if (CheckInRange(width, height, area, occupancy, aspect))
                {
                    //現在フレームにおける分裂候補の情報を保存
                    countList.Add(new CellState(x, y, z, width, height, t));
                    //分裂候補なので白で描画
                    colors.Add(Scalar.White);
                }
                else
                {
                    //分裂候補でないので黒で描画(ノイズ)
                    colors.Add(Scalar.Black);
                }
            }

            int count   = countList.Count;
            int count_1 = countList_1.Count;
            List <CellState> CandidatesTmp = new List <CellState>();

            for (int c = 0; c < count - 1; c++)
            {
                for (int v = 0; v < count_1; v++)
                {
                    //候補座標同士の差が絶対値10px以下ならば分裂候補として再確定
                    if (Math.Abs(countList[c].x - countList_1[v].x) <= 20 && Math.Abs(countList[c].y - countList_1[v].y) <= 20 && countList[c].y != 0)
                    {
                        if (Math.Abs((countList[c].x + countList[c].w) - countList[c + 1].x) <= 10 && Math.Abs((countList[c].y + countList[c].h) - countList[c + 1].y) <= 10)
                        {
                            Console.WriteLine("時間:{0}、Z軸:{1}、(x,y)=({2},{3})", countList[count - 1].t, countList[count - 1].z, countList[c].x, countList[c].y);
                            //分裂候補の情報を保存する
                            CandidatesTmp.Add(new CellState(countList[c].x, countList[c].y, countList[c].z, countList[c].w, countList[c].h, countList[c].t));
                            Result[z][t].Rectangle(new Rect(countList[c].x, countList[c].y, countList[c].w, countList[c].h), new Scalar(0, 0, 255), 1);
                            Result[z][t].Rectangle(new Rect(countList[c + 1].x, countList[c + 1].y, countList[c + 1].w, countList[c + 1].h), new Scalar(0, 0, 255), 1);
                        }
                    }
                }
            }

            //1フレームごとに適用させるために配列の初期化を行う
            //過去候補配列を初期化
            countList_1.Clear();

            //過去候補配列に現在フレームの分裂候補結果を保存
            countList_1 = countList;

            Candidates.Add(CandidatesTmp);
        }
Exemple #7
0
        private void ImgList_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            int pos;

            if (ImgList != null && ImgList.SelectedItem != null)
            {
                if (DetectList != null)
                {
                    DetectList.Clear();
                }

                // var OriImageMat = new Mat(ImgList.SelectedItem.ToString());
                var ThrImageMat = new Mat();
                pos = ImgList.SelectedIndex;
                //CurrentFN = ImgList.SelectedItem.ToString();
                CurrentFN = fileEntries[pos];
                Mat OriImageMat = new Mat(CurrentFN);
                Mat GrayImage   = OriImageMat.CvtColor(ColorConversionCodes.BGR2GRAY);

                //int slideVal;
                //int.TryParse(SliderValue, out slideVal);

                Cv2.Threshold(GrayImage, ThrImageMat, int.Parse(SliderValue), 255, ThresholdTypes.Binary);

                int[] mask = { 1, 1, 1,
                               1, 1, 1,
                               1, 1, 1 };

                Mat kernel = new Mat(3, 3, MatType.CV_32F, mask);

                Cv2.MorphologyEx(ThrImageMat, ThrImageMat, MorphTypes.Open, kernel);
                Cv2.MorphologyEx(ThrImageMat, ThrImageMat, MorphTypes.Close, kernel);
                Cv2.BitwiseNot(ThrImageMat, ThrImageMat);

                var label     = new MatOfInt();
                var stats     = new MatOfInt();
                var centroids = new MatOfDouble();

                var nLabels = Cv2.ConnectedComponentsWithStats(ThrImageMat, label, stats, centroids, PixelConnectivity.Connectivity8, MatType.CV_32S);


                var statsIndexer = stats.GetGenericIndexer <int>();
                for (int i = 0; i < nLabels; i++)
                {
                    //Threshold줄때 일정크기 이하의 객체는 노이즈로 간주하고 패스
                    if (statsIndexer[i, 4] < 90)
                    {
                        continue;
                    }

                    var rect = new OpenCvSharp.Rect
                    {
                        X      = statsIndexer[i, 0],
                        Y      = statsIndexer[i, 1],
                        Width  = statsIndexer[i, 2],
                        Height = statsIndexer[i, 3]
                    };

                    Cv2.Rectangle(OriImageMat, rect, new Scalar(33, 113, 243), 3);

                    obj temp = new obj();

                    //중심좌표 x,y (0 ~ 1)
                    temp.X = ((rect.X + rect.Width) / 2.0) / OriImageMat.Width;
                    temp.Y = ((rect.Y + rect.Height) / 2.0) / OriImageMat.Height;
                    temp.W = (double)rect.Width / (double)OriImageMat.Width;
                    temp.H = (double)rect.Height / (double)OriImageMat.Height;

                    DetectList.Add(temp);
                }



                OriginalImg.Source  = OriImageMat.ToWriteableBitmap();
                ThresholdImg.Source = ThrImageMat.ToWriteableBitmap();
            }
        }
Exemple #8
0
        static bool RunOn(string file, OpenCvSharp.Rect boundingBox)
        {
            int areas = 0;

            int[] quadrants = new int[4];
            using (OpenCvSharp.Mat m = new OpenCvSharp.Mat(file, OpenCvSharp.ImreadModes.Grayscale))
            {
                //blur the image a little
                using (var blurred = m.GaussianBlur(new Size(3, 3), 0))
                {
                    //make the image binary black or white and make black the background color
                    using (var g = blurred.Threshold(200, 255, ThresholdTypes.BinaryInv | ThresholdTypes.Otsu))
                    {
                        var element = Cv2.GetStructuringElement(
                            MorphShapes.Rect,
                            new Size(50, 1));
                        //remove lines from dark background image by creating a mask
                        using (var mask = g.MorphologyEx(MorphTypes.Open, element, iterations: 2))
                        {
                            using (Mat newMask = new Mat())
                            {
                                //mask bits should be 0 to skip copying items
                                Cv2.BitwiseNot(mask, newMask);



                                using (Mat newImage = new Mat())
                                {
                                    //make new image and apply mask so as to not copy the lines
                                    g.CopyTo(newImage, newMask);

                                    //create the box image
                                    using (OpenCvSharp.Mat box = new OpenCvSharp.Mat(new Size(boundingBox.Width, boundingBox.Height), MatType.CV_8U))
                                    {
                                        //copy to the box
                                        newImage[boundingBox].CopyTo(box);



                                        using (Mat labels = new Mat())
                                        {
                                            using (var centroids = new Mat())
                                            {
                                                using (Mat stats = new Mat())
                                                {
                                                    //find the white blobs
                                                    //populate the quadrants blobs appear in
                                                    //create total area of white stuff

                                                    int cnt = Cv2.ConnectedComponentsWithStats(box, labels, stats, centroids, PixelConnectivity.Connectivity8);
#if usequadrants
                                                    int qh = box.Size().Height / 2;
                                                    int qw = box.Size().Width / 2;

                                                    var tl = new Rect(0, 0, qw, qh);
                                                    var vl = new Rect(0, qh, qw, qh);
                                                    var tr = new Rect(qw, 0, qw, qh);
                                                    var br = new Rect(qw, qh, qw, qh);
#endif
                                                    for (var x = 1; x < stats.Size().Height; x++)
                                                    {
                                                        #if usequadrants
                                                        var left   = stats.Get <int>(x, (int)ConnectedComponentsTypes.Left);
                                                        var top    = stats.Get <int>(x, (int)ConnectedComponentsTypes.Top);
                                                        var width  = stats.Get <int>(x, (int)ConnectedComponentsTypes.Width);
                                                        var height = stats.Get <int>(x, (int)ConnectedComponentsTypes.Height);

                                                        var re = new Rect(left, top, width, height);
                                                        if (re.IntersectsWith(tl))
                                                        {
                                                            quadrants[0] = 1;
                                                        }
                                                        if (re.IntersectsWith(vl))
                                                        {
                                                            quadrants[1] = 1;
                                                        }
                                                        if (re.IntersectsWith(tr))
                                                        {
                                                            quadrants[2] = 1;
                                                        }
                                                        if (re.IntersectsWith(br))
                                                        {
                                                            quadrants[3] = 1;
                                                        }
#endif
                                                        areas += stats.Get <int>(x, (int)ConnectedComponentsTypes.Area);
                                                    }
                                                }
                                            }
                                        }

                                        var boxarea = box.Size().Width *box.Size().Height;



                                        double[] areasTest = new double[] { areas };
                                        double[] boxAreas  = new double[] { boxarea };


                                        //use infer.net to determine if the mean is good or not
                                        VariableArray <bool> ytest = Variable.Array <bool>(new Range(areasTest.Length));
                                        BayesPointMachine(areasTest, boxAreas, Variable.Random(wPosterior), ytest);
                                        var res  = (DistributionStructArray <Bernoulli, bool>)engine.Infer(ytest);
                                        var mean = res[0].GetMean();


                                        Console.WriteLine(boxarea + " " + areas + " " + mean + " "
                                            #if usequadrants
                                                          + quadrants.Sum());