1

私は、ロボットのエアホッケー選手である私のプロジェクトに取り組んでいます。

プロジェクトでは、マイクロソフトのライフカムを使用して「ボール」の場所を特定しています。それは働いています。

問題は、メイン フォームでプロジェクトを実行しているときです。ゲームに入る前に、ボタン内のコードであるカメラ (1 つの写真) をチェックしている場合:

 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;
        }

私はグーグルで検索しようとしましたが、ここで答えを探しましたが、何も見つかりませんでした。カメラチェックに入っていない場合は、問題なく動作します。

4

1 に答える 1

0

システムがアイドル状態のときに画像をキャプチャすることになっていることがわかった場合にのみ、画像をキャプチャしますが、それは頻繁すぎるか、十分ではない可能性があります。

DispatcherTimer を追加して、レンダリングの優先順位と 1000/60 (1 秒あたり 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;
    }
于 2013-03-29T12:54:44.197 に答える