【问题标题】:image capturing is failing after one capture一次拍摄后图像拍摄失败
【发布时间】:2013-03-20 02:28:30
【问题描述】:

我的项目是机器人空气曲棍球运动员;

在项目中,我使用 Microsoft lifecam 来识别“球”位置。 这行得通。

问题是当我以主窗体运行项目时 - 如果在进入游戏之前我正在检查相机(一张图片) 那就是按钮里面的代码:

 Capture capture = new Capture(0);
 Image<Emgu.CV.Structure.Bgr,byte>  temp = capture.QueryFrame();
 picture pic = new picture(temp);
 pic.ShowDialog();

检查完我就开始玩了 游戏停止给我这个错误:

An unhandled exception of type 'System.AccessViolationException' 
occurred in Emgu.CV.dll
Additional information: Attempted to read or write protected memory. 
This is often an indication that other memory is corrupt.

图像处理代码为:

 class C_Camera
    {
        public Capture capWebCam = null;
        public bool binCapturingInProgress = false;
        public Image<Bgr, byte> imgOriginal;
        public Image<Gray, byte> imgProcessed;
        public ImageBox imageBox1 = new ImageBox();
        public TextBox textBox1;
        public List<PointF> centerList;
        CircleF[] circles;

        public void newCapture(bool b, List<PointF> centers)
        {
            centerList = centers;
            binCapturingInProgress = b;

            try
            {
                capWebCam = new Capture();
            }
            catch (NullReferenceException except)
            {
                MessageBox.Show(except.Message);
                return;
            }

            Application.Idle += processFrameAndUpdateGUI;//add process image function to the applicationlist in tasks
            binCapturingInProgress = true;
        }


        public void processFrameAndUpdateGUI(object sender, EventArgs arg)
        {
            imgOriginal = capWebCam.QueryFrame();
            if (imgOriginal == null) 
            {
                return;
            }
            imgProcessed = imgOriginal.InRange(new Bgr(0, 0, 150)/*min filter*/, new Bgr(80, 80, 256));
         //   imgProcessed = imgOriginal.InRange(new Bgr(0, 0, 175)/*min filter*/, new Bgr(100, 100, 256));

            imgProcessed = imgProcessed.SmoothGaussian(9);//9
            circles = imgProcessed.HoughCircles(new Gray(100), //canny threshhold
                                                          new Gray(50), //accumolator threshold
                                                          2,//size of image 
                                                          imgProcessed.Height / 4, //min size in pixels between centers of detected circles
                                                          15, //min radios
                                                          43)[0];//max radios and get circles from first channel
            foreach (CircleF circle in circles)
            {


                centerList.Add(circle.Center);
                //     circlesOfBalls.Add(circle);

                if (textBox1.Text != "") textBox1.AppendText(Environment.NewLine);
                textBox1.AppendText("ball position = x" + centerList[centerList.Count - 1].X +
                                    ", y = " + centerList[centerList.Count - 1].Y.ToString().PadLeft(4)
                                    + "centerList.Count= " + centerList.Count);

                // + ", radios = " + centerList[centerList.Count - 1].Radius.ToString("###,000").PadLeft(7))

                textBox1.ScrollToCaret();// scrolls the textBox to last line

                // draw a small green circle in the center
                CvInvoke.cvCircle(imgOriginal, // draw on the original image
                                  new Point((int)circle.Center.X, (int)circle.Center.Y),//center point of circle
                                  3, // radios of circle,
                                  new MCvScalar (0, 255, 0), // draw in green color
                                  -1, //indicates to fill the circle
                                  LINE_TYPE.CV_AA, //smoothes the pixels
                                  0);// no shift 

                //draw a red circle around the detected object
              //  if (imgOriginal.Data != null) 
                    imgOriginal.Draw(circle,    //current circle
                                new Bgr(Color.Red), // draw pure red
                                3);
            } // end of for each

           // if(imgOriginal.Data != null)
                imageBox1.Image = imgOriginal;
        }

我试图在谷歌和这里搜索答案,但找不到任何答案。 如果我没有进入相机,请检查它是否正常工作。

【问题讨论】:

    标签: c# opencv image-processing emgucv


    【解决方案1】:

    从外观上看,您只有在我发现您应该在系统空闲时捕获图像时才捕获图像,但这可能过于频繁或不够频繁。

    尝试添加 DispatcherTimer 并为其提供渲染优先级和 1000/60(每秒 60 帧)的频率。

        DispatcherTimer UpdateTimer; 
        public Capture capWebCam = null;
        public bool binCapturingInProgress = false;
        public Image<Bgr, byte> imgOriginal;
        public Image<Gray, byte> imgProcessed;
        public ImageBox imageBox1 = new ImageBox();
        public TextBox textBox1;
        public List<PointF> centerList;
        CircleF[] circles;
    
        public void newCapture(bool b, List<PointF> centers)
        {
            centerList = centers;
            binCapturingInProgress = b;
    
            try
            {
                capWebCam = new Capture();
            }
            catch (NullReferenceException except)
            {
                MessageBox.Show(except.Message);
                return;
            }
    
            binCapturingInProgress = true;
    
    
            //Start the timer after the device is ready to be captured (this looks like a good place to do it)
            UpdateTimer = new DispatcherTimer(DispatcherPriority.Render);
            UpdateTimer.Interval = TimeSpan.FromMilliseconds(1000 / 60);
            UpdateTimer.Tick += processFrameAndUpdateGUI;
            UpdateTimer.Start();
        }
    
        private void processFrameAndUpdateGUI(object o, EventArgs e)
        {
           //Capture new image, render it and display it.
    
            imgOriginal = capWebCam.QueryFrame();
            if (imgOriginal == null) 
            {
                return;
            }
            imgProcessed = imgOriginal.InRange(new Bgr(0, 0, 150)/*min filter*/, new Bgr(80, 80, 256));
         //   imgProcessed = imgOriginal.InRange(new Bgr(0, 0, 175)/*min filter*/, new Bgr(100, 100, 256));
    
            imgProcessed = imgProcessed.SmoothGaussian(9);//9
            circles = imgProcessed.HoughCircles(new Gray(100), //canny threshhold
                                                          new Gray(50), //accumolator threshold
                                                          2,//size of image 
                                                          imgProcessed.Height / 4, //min size in pixels between centers of detected circles
                                                          15, //min radios
                                                          43)[0];//max radios and get circles from first channel
            foreach (CircleF circle in circles)
            {
    
    
                centerList.Add(circle.Center);
                //     circlesOfBalls.Add(circle);
    
                if (textBox1.Text != "") textBox1.AppendText(Environment.NewLine);
                textBox1.AppendText("ball position = x" + centerList[centerList.Count - 1].X +
                                    ", y = " + centerList[centerList.Count - 1].Y.ToString().PadLeft(4)
                                    + "centerList.Count= " + centerList.Count);
    
                // + ", radios = " + centerList[centerList.Count - 1].Radius.ToString("###,000").PadLeft(7))
    
                textBox1.ScrollToCaret();// scrolls the textBox to last line
    
                // draw a small green circle in the center
                CvInvoke.cvCircle(imgOriginal, // draw on the original image
                                  new Point((int)circle.Center.X, (int)circle.Center.Y),//center point of circle
                                  3, // radios of circle,
                                  new MCvScalar (0, 255, 0), // draw in green color
                                  -1, //indicates to fill the circle
                                  LINE_TYPE.CV_AA, //smoothes the pixels
                                  0);// no shift 
    
                //draw a red circle around the detected object
              //  if (imgOriginal.Data != null) 
                    imgOriginal.Draw(circle,    //current circle
                                new Bgr(Color.Red), // draw pure red
                                3);
            } // end of for each
    
           // if(imgOriginal.Data != null)
                imageBox1.Image = imgOriginal;
        }
    

    【讨论】:

    • 嗨托马斯,谢谢你的帮助。我试着按照你告诉我的去做,但不幸的是 DispatcherTimer 仅在 wpf 中可用。我找不到如何设置计时器优先级。所以这就是我所做的: timer = new Timer(); //time timer.Interval = Convert.ToInt32(TimeSpan.FromMilliseconds(1000 / 60).TotalMilliseconds); timer.Tick += processFrameAndUpdateGUI; timer.Start();
    • 是的,几乎是一样的,我猜我的想法是关于问题在哪里以及如何解决是正确的。如果您在表单中执行此操作,您可能需要使用计时器(可以在工具箱中找到)
    • 修复它:) 我需要做的就是 capture.dispose();在主要形式 tnks
    猜你喜欢
    • 2015-01-03
    • 1970-01-01
    • 2016-09-06
    • 2020-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多