Example #1
0
        /// <summary>
        /// 箱の頂点を見つける
        /// </summary>
        /// <param name="box">箱</param>
        /// <param name="pt">頂点の配列</param>
#else
        /// <summary>
        /// Finds box vertices
        /// </summary>
        /// <param name="box">Box</param>
        /// <param name="pt">Array of vertices</param>
#endif
        public static void BoxPoints(CvBox2D box, out CvPoint2D32f[] pt)
        {
            pt = new CvPoint2D32f[4];
            NativeMethods.cvBoxPoints(box, pt);

            // cvgeometry.cpp  line 89~103

            /*
             * double angle = box.Angle * CvConst.CV_PI / 180.0;
             * float a = (float)Math.Cos(angle)*0.5f;
             * float b = (float)Math.Sin(angle)*0.5f;
             *
             * pt[0].X = box.Center.X - a * box.Size.Height - b * box.Size.Width;
             * pt[0].Y = box.Center.Y + b * box.Size.Height - a * box.Size.Width;
             * pt[1].X = box.Center.X + a * box.Size.Height - b * box.Size.Width;
             * pt[1].Y = box.Center.Y - b * box.Size.Height - a * box.Size.Width;
             * pt[2].X = 2 * box.Center.X - pt[0].X;
             * pt[2].Y = 2 * box.Center.Y - pt[0].Y;
             * pt[3].X = 2 * box.Center.X - pt[1].X;
             * pt[3].Y = 2 * box.Center.Y - pt[1].Y;
             * //*/
        }
Example #2
0
    // Converts the ROI (screen coordinates) into world coordinates and
    // positions world gameobject to that position and rotation
    void ROIScreenToGameObject(CvBox2D boxToTrack, GameObject obj1)
    {
        Vector2 origin;
        origin.x = objectScreenPosition.position.x + scaleObjectWidth(boxToTrack.Center.X);
        origin.y = objectScreenPosition.position.y + scaleObjectHeight(boxToTrack.Center.Y);

        obj1.transform.position = Camera.main.ScreenToWorldPoint(new Vector3(origin.x, Screen.height - origin.y,
                                                         Mathf.Abs(transform.position.z - Camera.main.transform.position.z)));

        obj1.transform.eulerAngles = new Vector3(0, 0, 90 - boxToTrack.Angle);
        obj1.transform.localScale = new Vector3(scaleObjectHeight(boxToTrack.Size.Height) / 100,
                                           scaleObjectWidth(boxToTrack.Size.Width) / 100, 1);
    }
Example #3
0
    //  Use the CamShift algorithm to track to base histogram throughout the
    // succeeding frames
    void CalculateCamShift(CvMat _image)
    {
        CvMat _backProject = CalculateBackProjection(_image, _histogramToTrack);

        // Create convolution kernel for erosion and dilation
        IplConvKernel elementErode = Cv.CreateStructuringElementEx(10, 10, 5, 5, ElementShape.Rect, null);
        IplConvKernel elementDilate = Cv.CreateStructuringElementEx(4, 4, 2, 2, ElementShape.Rect, null);

        // Try eroding and then dilating the back projection
        // Hopefully this will get rid of the noise in favor of the blob objects.
        Cv.Erode(_backProject, _backProject, elementErode, 1);
        Cv.Dilate(_backProject, _backProject, elementDilate, 1);

        if (backprojWindowFlag)
        {
            Cv.ShowImage("Back Projection", _backProject);
        }

        // Parameters returned by Camshift algorithm
        CvBox2D _outBox;
        CvConnectedComp _connectComp;

        // Set the criteria for the CamShift algorithm
        // Maximum 10 iterations and at least 1 pixel change in centroid
        CvTermCriteria term_criteria = Cv.TermCriteria(CriteriaType.Iteration | CriteriaType.Epsilon, 10, 1);

        // Draw object center based on Kalman filter prediction
        CvMat _kalmanPrediction = _kalman.Predict();

        int predictX = Mathf.FloorToInt((float)_kalmanPrediction.GetReal2D(0, 0));
        int predictY = Mathf.FloorToInt((float)_kalmanPrediction.GetReal2D(1, 0));

        // Run the CamShift algorithm
        if (Cv.CamShift(_backProject, _rectToTrack, term_criteria, out _connectComp, out _outBox) > 0)
        {

            // Use the CamShift estimate of the object center to update the Kalman model
            CvMat _kalmanMeasurement = Cv.CreateMat(2, 1, MatrixType.F32C1);
            // Update Kalman model with raw data from Camshift estimate
            _kalmanMeasurement.Set2D(0, 0, _outBox.Center.X); // Raw X position
            _kalmanMeasurement.Set2D(1, 0, _outBox.Center.Y); // Raw Y position
            //_kalmanMeasurement.Set2D (2, 0, _outBox.Center.X - lastPosition.X);
            //_kalmanMeasurement.Set2D (3, 0, _outBox.Center.Y - lastPosition.Y);

            lastPosition.X = Mathf.FloorToInt(_outBox.Center.X);
            lastPosition.Y = Mathf.FloorToInt(_outBox.Center.Y);

            _kalman.Correct(_kalmanMeasurement); // Correct Kalman model with raw data

            // CamShift function returns two values: _connectComp and _outBox.

            //	_connectComp contains is the newly estimated position and size
            //  of the region of interest. This is passed into the subsequent
            // call to CamShift
            // Update the ROI rectangle with CamShift's new estimate of the ROI
            _rectToTrack = CheckROIBounds(_connectComp.Rect);

            // Draw a rectangle over the tracked ROI
            // This method will draw the rectangle but won't rotate it.
            _image.DrawRect(_rectToTrack, CvColor.Aqua);
            _image.DrawMarker(predictX, predictY, CvColor.Aqua);

            // _outBox contains a rotated rectangle esimating the position, size, and orientation
            // of the object we want to track (specified by the initial region of interest).
            // We then take this estimation and draw a rotated bounding box.
            // This method will draw the rotated rectangle
            rotatedBoxToTrack = _outBox;

            // Draw a rotated rectangle representing Camshift's estimate of the
            // object's position, size, and orientation.
            _image.DrawPolyLine(rectangleBoxPoint(_outBox.BoxPoints()), true, CvColor.Red);

        }
        else
        {

            //Debug.Log ("Object lost by Camshift tracker");

            _image.DrawMarker(predictX, predictY, CvColor.Purple, MarkerStyle.CircleLine);

            _rectToTrack = CheckROIBounds(new CvRect(predictX - Mathf.FloorToInt(_rectToTrack.Width / 2),
                                           predictY - Mathf.FloorToInt(_rectToTrack.Height / 2),
                                        _rectToTrack.Width, _rectToTrack.Height));
            _image.DrawRect(_rectToTrack, CvColor.Purple);

        }

        if (trackWindowFlag)
            Cv.ShowImage("Image", _image);
    }
Example #4
0
        /// <summary>
        /// 枠だけの楕円,もしくは塗りつぶされた楕円を描画する
        /// </summary>
        /// <param name="img">楕円が描かれる画像.</param>
        /// <param name="box">描画したい楕円を囲む矩形領域.</param>
        /// <param name="color">楕円の色.</param>
        /// <param name="thickness">楕円境界線の幅.</param>
        /// <param name="line_type">楕円境界線の種類.</param>
        /// <param name="shift">矩形領域の頂点座標の小数点以下の桁を表すビット数.</param>
#else
        /// <summary>
        /// Draws simple or thick elliptic arc or fills ellipse sector
        /// </summary>
        /// <param name="img">Image. </param>
        /// <param name="box">The enclosing box of the ellipse drawn </param>
        /// <param name="color">Ellipse color. </param>
        /// <param name="thickness">Thickness of the ellipse boundary. </param>
        /// <param name="line_type">Type of the ellipse boundary</param>
        /// <param name="shift">Number of fractional bits in the box vertex coordinates. </param>
#endif
        public static void EllipseBox(CvArr img, CvBox2D box, CvScalar color, int thickness, LineType line_type, int shift)
        {
            if (img == null)
            {
                throw new ArgumentNullException("img");
            }

            CvSize axes = new CvSize
            {
                Width = (int)Math.Round(box.Size.Height * 0.5),
                Height = (int)Math.Round(box.Size.Width * 0.5)
            };
            Ellipse(img, box.Center, axes, box.Angle, 0, 360, color, thickness, line_type, shift);
        }
Example #5
0
        /// <summary>
        /// 枠だけの楕円,もしくは塗りつぶされた楕円を描画する
        /// </summary>
        /// <param name="img">楕円が描かれる画像.</param>
        /// <param name="box">描画したい楕円を囲む矩形領域.</param>
        /// <param name="color">楕円の色.</param>
        /// <param name="thickness">楕円境界線の幅.</param>
        /// <param name="line_type">楕円境界線の種類.</param>
#else
        /// <summary>
        /// Draws simple or thick elliptic arc or fills ellipse sector
        /// </summary>
        /// <param name="img">Image. </param>
        /// <param name="box">The enclosing box of the ellipse drawn </param>
        /// <param name="color">Ellipse color. </param>
        /// <param name="thickness">Thickness of the ellipse boundary. </param>
        /// <param name="line_type">Type of the ellipse boundary</param>
#endif
        public static void EllipseBox(CvArr img, CvBox2D box, CvScalar color, int thickness, LineType line_type)
        {
            EllipseBox(img, box, color, thickness, line_type, 0);
        }
Example #6
0
        /// <summary>
        /// 枠だけの楕円,もしくは塗りつぶされた楕円を描画する
        /// </summary>
        /// <param name="img">楕円が描かれる画像.</param>
        /// <param name="box">描画したい楕円を囲む矩形領域.</param>
        /// <param name="color">楕円の色.</param>
#else
        /// <summary>
        /// Draws simple or thick elliptic arc or fills ellipse sector
        /// </summary>
        /// <param name="img">Image. </param>
        /// <param name="box">The enclosing box of the ellipse drawn </param>
        /// <param name="color">Ellipse color. </param>
#endif
        public static void EllipseBox(CvArr img, CvBox2D box, CvScalar color)
        {
            EllipseBox(img, box, color, 1, LineType.Link8, 0);
        }
Example #7
0
        /// <summary>
        /// 箱の頂点を見つける
        /// </summary>
        /// <param name="box">箱</param>
        /// <param name="pt">頂点の配列</param>
#else
        /// <summary>
        /// Finds box vertices
        /// </summary>
        /// <param name="box">Box</param>
        /// <param name="pt">Array of vertices</param>
#endif
        public static void BoxPoints(CvBox2D box, out CvPoint2D32f[] pt)
        {
            pt = new CvPoint2D32f[4];
            CvInvoke.cvBoxPoints(box, pt);

            // cvgeometry.cpp  line 89~103
            /*
            double angle = box.Angle * CvConst.CV_PI / 180.0;
            float a = (float)Math.Cos(angle)*0.5f;
            float b = (float)Math.Sin(angle)*0.5f;

            pt[0].X = box.Center.X - a * box.Size.Height - b * box.Size.Width;
            pt[0].Y = box.Center.Y + b * box.Size.Height - a * box.Size.Width;
            pt[1].X = box.Center.X + a * box.Size.Height - b * box.Size.Width;
            pt[1].Y = box.Center.Y - b * box.Size.Height - a * box.Size.Width;
            pt[2].X = 2 * box.Center.X - pt[0].X;
            pt[2].Y = 2 * box.Center.Y - pt[0].Y;
            pt[3].X = 2 * box.Center.X - pt[1].X;
            pt[3].Y = 2 * box.Center.Y - pt[1].Y;
            //*/
        }
Example #8
0
 public static extern void cvBoxPoints(CvBox2D box, [Out] CvPoint2D32f[] pt);
Example #9
0
 public static extern int cvCamShift(IntPtr prob_image, CvRect window, CvTermCriteria criteria, IntPtr comp, ref CvBox2D box);