opencvsharp 模板追踪

本次试验用的WINFORM ,要先绘制窗体 ,自己测试的时候注意对象名就可以了。

 public Form1()
        {
            InitializeComponent();
        }
        static Mat mat1 = new Mat(@"timg.jpg", ImreadModes.AnyColor);
        static Mat result = new Mat();
        static OpenCvSharp.Point minLocation, maxLocation;
        static Mat src = new Mat();
        static Mat grayImage = new Mat();
        static Mat ThresholdImage = new Mat();
        static Bitmap bitmap, bitmap2, bitmap3;
        static VideoCapture capture = new VideoCapture();
        int a, b;

        //运行摄像头
        private void runVideo()
        { 
            FrameSource frame = Cv2.CreateFrameSource_Camera(0);  
            while (true)
            {              
                // capture.Read(mat1); 
                // VideoBox.Dispose(); 
                frame.NextFrame(src);               
                grayImage = src.CvtColor(ColorConversionCodes.BGR2GRAY);              
                bitmap2 = BitmapConverter.ToBitmap(grayImage);
                Cv2.Threshold(grayImage, ThresholdImage,a,b,ThresholdTypes.Binary);
                bitmap3 = BitmapConverter.ToBitmap(ThresholdImage);
                Action<Bitmap, Bitmap,Bitmap> action = showVideoBox;    //委托
                action(bitmap, bitmap2, bitmap3);   
            }
            //while (true)
            //{
            //    capture.Read(mat1);
            //    Cv2.ImShow("mat1", src);
            //    Cv2.WaitKey(100);
            //}
        }
        //窗口异步传值的委托 
        private void showVideoBox( Image image, Image image2, Image image3)
        {
            Action<Image> action = deleVideoBox;
            Action<Image> action2 = deleGrayBox;
            Action<Image> action3 = deleThresholdBox;
            VideoBox.BeginInvoke(action, image);
            grayBox.BeginInvoke(action2, image2);
            ThresholdBox.BeginInvoke(action3,image3);
        }
        //原视图
        private void deleVideoBox( Image image)
        {
            Invalidate();
            result.Create(src.Cols - mat1.Cols + 1, src.Rows - mat1.Cols + 1, MatType.CV_32FC1);
            //进行匹配(1母图,2模版子图,3返回的result,4匹配模式_这里的算法比opencv少,具体可以看opencv的相关资料说明)
            Cv2.MatchTemplate(src, mat1, result, TemplateMatchModes.SqDiff);
            //对结果进行归一化(这里我测试的时候没有发现有什么用,但在opencv的书里有这个操作,应该有什么神秘加成,这里也加上)
            Cv2.Normalize(result, result, 1, 0, NormTypes.MinMax, -1);
            /// 通过函数 minMaxLoc 定位最匹配的位置
            /// (这个方法在opencv里有5个参数,这里我写的时候发现在有3个重载,看了下可以直接写成拿到起始坐标就不取最大值和最小值了)
            /// minLocation和maxLocation根据匹配调用的模式取不同的点
            Cv2.MinMaxLoc(result, out minLocation, out maxLocation);
            Cv2.Rectangle(src, minLocation, new OpenCvSharp.Point(minLocation.X + mat1.Cols, minLocation.Y + mat1.Rows), Scalar.Red, 2); 
            bitmap = BitmapConverter.ToBitmap(src);
            VideoBox.Image = image;
            VideoBox.Invalidate();
        }
        //灰度视图 (这里没用,不是主要的)
        private void deleGrayBox(Image image)
        {
            Invalidate();
            grayBox.Image = image;
            grayBox.Invalidate();
        }
        //二值化视图(这里没用,不是主要的)
        private void deleThresholdBox(Image image)
        {
            Invalidate();
            ThresholdBox.Image = image;
            ThresholdBox.Invalidate();
        }
        private void button1_Click(object sender, EventArgs e)
        {
            capture.Open(0);
            Action action = runVideo;
            action.BeginInvoke(null, null);
        }
        
        private void hScrollBar2_Scroll(object sender, ScrollEventArgs e)
        {
            a = hScrollBar2.Value;
            label1.Text= hScrollBar2.Value.ToString();
        }

        private void hScrollBar1_Scroll(object sender, ScrollEventArgs e)
        {
            b = hScrollBar1.Value; 
            label2.Text = hScrollBar1.Value.ToString();
        }
    }


下面是绘制的窗 体:

opencvsharp 模板追踪_第1张图片

下面是结果:不知道怎么发视频,实际上移动烟盒,只要在摄像头范围内,就能一直抓取到这个烟盒。
opencvsharp 模板追踪_第2张图片

你可能感兴趣的:(opencvsharp)