예제 #1
0
        public override IObservable <Contours> Process(IObservable <IplImage> source)
        {
            return(Observable.Defer(() =>
            {
                IplImage temp = null;
                return source.Select(input =>
                {
                    Seq currentContour;
                    temp = IplImageHelper.EnsureImageFormat(temp, input.Size, IplDepth.U8, 1);
                    CV.Copy(input, temp);

                    var storage = new MemStorage();
                    var scanner = CV.StartFindContours(temp, storage, Contour.HeaderSize, Mode, Method, Offset);
                    while ((currentContour = scanner.FindNextContour()) != null)
                    {
                        if (MinArea.HasValue || MaxArea.HasValue)
                        {
                            var contourArea = CV.ContourArea(currentContour, SeqSlice.WholeSeq);
                            if (contourArea < MinArea || contourArea > MaxArea)
                            {
                                scanner.SubstituteContour(null);
                            }
                        }
                    }

                    return new Contours(scanner.EndFindContours(), input.Size);
                });
            }));
        }
        //tracking routine
        public float[] GetParams(IplImage input)
        {
            //subtract mask from frame
            CV.Sub(Mask, input, output);

            //threshold to remove any small background noise
            CV.Threshold(output, output, thr, 255, ThresholdTypes.Binary);

            //find countours of the rest of the pixels
            Seq currentContour;

            using (var storage = new MemStorage())
                using (var scanner = CV.StartFindContours(output, storage, Contour.HeaderSize, ContourRetrieval.External, ContourApproximation.ChainApproxNone, new Point(0, 0)))
                {
                    bfArea = 0;
                    while ((currentContour = scanner.FindNextContour()) != null)
                    {
                        //calculate the number of pixels inside the contour
                        contourArea = CV.ContourArea(currentContour, SeqSlice.WholeSeq);

                        //if number of pixels fit the expected for the fly, calculate the distribution moments
                        if (contourArea > bfArea && (contourArea > MinArea && contourArea < MaxArea))
                        {
                            scanner.SubstituteContour(null);
                            //calculate the pixel distribution moments
                            moments = new Moments(currentContour);
                            if (moments.M00 > 0)
                            {
                                //transform moments into X,Y and orentation
                                param[0] = Convert.ToSingle(moments.M10 / moments.M00);
                                param[1] = Convert.ToSingle(moments.M01 / moments.M00);
                                param[2] = 180f * Convert.ToSingle(0.5 * Math.Atan2(2 * (moments.M11 / moments.M00 - param[0] * param[1]), (moments.M20 / moments.M00 - param[0] * param[0]) - (moments.M02 / moments.M00 - param[1] * param[1]))) / Convert.ToSingle(Math.PI);
                            }
                        }
                        bfArea = contourArea;
                    }
                }
            //return position and orientation
            return(param);
        }