用emguCv库提取视频中物体坐标

视频中的一帧

用emguCv库提取视频中物体坐标_第1张图片 

提取后在黑色物体边生成红色矩形框,并在图片左上角输出矩形框中心坐标。

代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Emgu.CV;
using Emgu.CV.CvEnum;
using Emgu.CV.Structure;
using Emgu.Util;
using Emgu.CV.Util;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Text;
using System.Windows.Forms;

namespace ClassLibrary1
{
     public class Class1
    {
      
        public Class1()
        { }
        static public Rectangle Findcoordinate(Mat frame, int bigarea, int smallarea)
        {
            Mat grayimg = new Mat(), thresholdimg = new Mat(), canny = new Mat();
            VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();
            double gnthresh = 40;
            int idx, idy = 0;
            String text1 = null, text2 = null, text3 = null;
            Rectangle box = new Rectangle();
            CvInvoke.CvtColor(frame, grayimg, ColorConversion.Bgr2Gray);
            CvInvoke.Blur(grayimg, grayimg, new Size(3, 3), new Point(-1, -1));
            CvInvoke.Threshold(grayimg, thresholdimg, gnthresh, 255, ThresholdType.Binary);
            //CvInvoke.Dilate(thresholdimg, thresholdimg, null, new Point(-1, -1), 1, BorderType.Constant, CvInvoke.MorphologyDefaultBorderValue);//膨胀扩张
            CvInvoke.Erode(thresholdimg, thresholdimg, null, new Point(-1, -1), 1, BorderType.Constant, CvInvoke.MorphologyDefaultBorderValue);//腐蚀,先膨胀后腐蚀是闭运算,消除小黑洞
            CvInvoke.Canny(thresholdimg, canny, 100, 50);//最大幅值100,最小幅值50,大于100,则保留;小于50,排除;两者之间且连着大于100的点才保留
            //Mat mask1 = new Mat(thresholdimg.Size.Height,thresholdimg.Size.Width,DepthType.Cv8U,1);
            //mask1.SetTo(new MCvScalar(255));
            //canny.CopyTo(mask1);
            int[,] hierachy = CvInvoke.FindContourTree(canny, contours, ChainApproxMethod.ChainApproxSimple);//最后一个参数表示一个矩形只要4个点的参数   
            if (contours.Size == 0) return box;
            for (; idy >= 0 && text1 == null; idy = hierachy[idy, 0])
                for (idx = idy; idx >= 0; idx = hierachy[idx, 2])//hierachy[idx, 0]表示后一个轮廓索引编号    [idx,2]表示内部轮廓
                {
                    using (VectorOfPoint c = contours[idx])
                    using (VectorOfPoint approx = new VectorOfPoint())
                    {
                        CvInvoke.ApproxPolyDP(c, approx, CvInvoke.ArcLength(c, true) * 0.001, true);//逼近多边形,ApproxPolyDP(,,精度为周长的0.02倍,要封闭的)
                        double area = CvInvoke.ContourArea(approx);
                        /*Point[] pts = approx.ToArray();
                                for (int j = 0; j < pts.Length; j++)
                                {
                                    Point p1 = new Point(pts[j].X, pts[j].Y);
                                    Point p2;
                                    if (j == pts.Length - 1)
                                        p2 = new Point(pts[0].X, pts[0].Y);
                                    else
                                        p2 = new Point(pts[j + 1].X, pts[j + 1].Y);
                                    CvInvoke.Line(frame, p1, p2, new MCvScalar(255, 255, 0), 3);
                                }*/
                        if (bigarea > area && area > smallarea)
                        {
                            box = CvInvoke.BoundingRectangle(c);//返回外部矩形边界                                 
                            Mat candidate = new Mat();
                            using (Mat tmp = new Mat(frame, box))  //roi
                            {
                                CvInvoke.CvtColor(tmp, candidate, ColorConversion.Bgr2Gray);
                            }
                            using (Mat mask = new Mat(candidate.Size.Height, candidate.Width, DepthType.Cv8U, 1))  //set the value of pixels not in the contour region to zero  设置像素值不在轮廓区域为零
                            {
                                mask.SetTo(new MCvScalar(255));//白色图像
                                //CvInvoke.DrawContours(mask, contours, idx, new MCvScalar(0), -1, LineType.EightConnected, null, int.MaxValue, new Point(-box.X, -box.Y));//黑色轮廓
                                //CvInvoke.Imshow("x", mask);
                                CvInvoke.Rectangle(frame, box, new MCvScalar(0, 0, 255), 2);
                                text1 = Convert.ToString((2 * box.X + box.Width) / 2);//横向坐标
                                text2 = Convert.ToString(box.Y);//纵向坐标 
                                text3 = Convert.ToString(area);
                            }

                            break;
                        }
                    }

                }
            if (text1 != null && text2 != null)
            {
                CvInvoke.PutText(frame, text1, new Point(0, 40), FontFace.HersheyTriplex, 1, new MCvScalar(255, 255, 255), 2);
                CvInvoke.PutText(frame, text2, new Point(160, 40), FontFace.HersheyTriplex, 1, new MCvScalar(255, 255, 255), 2);
                CvInvoke.PutText(frame, text3, new Point(320, 40), FontFace.HersheyTriplex, 1, new MCvScalar(255, 255, 255), 2);
            }
            return box;
        }
    }
}

 

你可能感兴趣的:(用emguCv库提取视频中物体坐标)