2016-05-17 11 views
0

私はカメラのマウスや他のフェイスコントロールマウスのようなシステムを開発しています。私はすべての機能を実装しています。マウスポインタも動きやすいですが、ポインタをマウスでコントロールするように滑らかな動きを作りたいと思います。私が使用していたコードは次のとおりです。emguCV C#を使用して頭の動きでマウスポインタを制御する方法?

 if (startButton == true) 
     { 
      try 
      { 
       cap = new Capture(); 
       pictureBox1.Image = cap.QueryFrame().ToImage<Bgr, Byte>().Bitmap; 
      } 
      catch (Exception exp) 
      { 
       MessageBox.Show("Error:" + exp); 
      } 
      _cascadeClassifier = new CascadeClassifier(Application.StartupPath + "/haarcascade_frontalface_default.xml"); 
      eye_cascadeClassifier = new CascadeClassifier(Application.StartupPath + "/haarcascade_eye.xml"); 

      timer1.Start(); 
     } 

    private void timer1_Tick(object sender, EventArgs e) 
    { 
     using (var imageFrame = cap.QueryFrame().ToImage<Bgr, Byte>().Flip(FlipType.Horizontal)) 
     { 
      if (imageFrame != null) 
      { 
       var grayframe = imageFrame.Convert<Gray, byte>(); 

       var faces = _cascadeClassifier.DetectMultiScale(grayframe, 1.1, 10, Size.Empty); //the actual face detection happens here 

       foreach (var face in faces) 
       { 
        if(Configure.FaceBoxCheck==true) 
        imageFrame.Draw(face, new Bgr(Color.LightGreen), 2); //the detected face(s) is highlighted here using a box that is drawn around it/them 
        Int32 yCoordStartSearchEyes = face.Top + (face.Height * 3/11); 
        Point startingPointSearchEyes = new Point(face.X, yCoordStartSearchEyes); 
        Size searchEyesAreaSize = new Size(face.Width, (face.Height * 3/11)); 
        Rectangle possibleROI_eyes = new Rectangle(startingPointSearchEyes, searchEyesAreaSize); 

        int widthNav = (imageFrame.Width/11 * 3); 
        int heightNav = (imageFrame.Height/11 * 3); 
        Rectangle nav = new Rectangle(new Point(imageFrame.Width/2 - widthNav/2, imageFrame.Height/2 - heightNav/2), new Size(widthNav, heightNav)); 
        imageFrame.Draw(nav, new Bgr(Color.Lavender), 3); 
        Point cursor = new Point(face.X + searchEyesAreaSize.Width/2, yCoordStartSearchEyes + searchEyesAreaSize.Height/2); 
        grayframe.ROI = possibleROI_eyes; 
        var eyes = eye_cascadeClassifier.DetectMultiScale(grayframe, 2.15, 3, Size.Empty); 

        foreach (var eye in eyes) 
        { 
         //imageFrame.Draw(eye, new Bgr(Color.Red), 2); 
         if(Configure.EyeBoxCheck==true) 
         imageFrame.Draw(possibleROI_eyes, new Bgr(Color.DarkGreen), 2); 
         if (nav.Left < cursor.X && cursor.X < (nav.Left + nav.Width) && nav.Top < cursor.Y && cursor.Y < nav.Top + nav.Height) 
         { 
          LineSegment2D CursorDraw = new LineSegment2D(cursor, new Point(cursor.X, cursor.Y + 1)); 

          imageFrame.Draw(CursorDraw, new Bgr(Color.White), 3); 
          //we compute new cursor coordinate using a simple scale based on frame width and height 
          int xCoord = (imageFrame.Width * (cursor.X - nav.Left))/nav.Width; 
          int yCoord = (imageFrame.Height * (cursor.Y - nav.Top))/nav.Height; 
          //We set our new cursor position 
          Cursor.Position = new Point(xCoord * 2, yCoord *2); 
        } 
       } 
      } 
+0

に基づいていますemgucv、しかし、問題は、位置遷移がスムーズでないように思われる。私はあなたが現在のマウス位置と次の計算位置の間の "パス"を計算すべきだと思います。次に、そのパスに沿ってマウスを「手動で」移動させる必要があります。私はこれが意味を成しているかどうかわからない。 – Pikoh

答えて

0

[OK]を、私は他のより良い方法がたくさんあると確信しているが、これは点Aから「スムーズ」のようにカーソル位置を移動するの迅速&汚い方法ですbを指す。もちろん、この実装は、UIスレッドをブロックしないようにApplication.DoEvents()を使用する代わりに、別のスレッドを使用して最適化する必要があります。これがトラックに表示されることを願っています。まず、どのように使用すべきか。代わりに:

Cursor.Position = new Point(xCoord * 2, yCoord *2); 

あなたがこれを行う必要があります。今

MoveCursorSmooth(Cursor.Position, new Point(xCoord * 2, yCoord *2)); 

を、MoveCursorSmoothの実装:

private void MoveCursorSmooth(Point a, Point b) 
    { 
     var step = 5; 
     var left = Math.Min(a.X, b.X); 
     var right = Math.Max(a.X, b.X); 
     int width = right - left; 

     var top = a.Y; 
     var bottom = b.Y; 
     int height = bottom - top; 

     if (width > height) 
     { 
      double slope = (double)height/(double)width; 
      if (a.X <= b.X) 
       for (int x = 1; x < width; ++x) 
       { 
        Cursor.Position = new Point((left + x), (a.Y + ((int)(slope * x + 0.5)))); 
        System.Threading.Thread.Sleep(step); 
        Application.DoEvents(); 
       } 
      else 
       for (int x = 1; x < width; ++x) // xOffset 
       { 
        Cursor.Position = new Point((right - x), (a.Y + ((int)(slope * x + 0.5)))); 
        System.Threading.Thread.Sleep(step); 
        Application.DoEvents(); 
       } 
     } 
     else 
     { 

      double slope = (double)width/(double)height; 
      if (a.X <= b.X) 
      { 
       for (int y = 1; y < height; ++y) 
       { 
        Cursor.Position = new Point((a.X + ((int)(slope * y + 0.5))), (top + y)); 
        System.Threading.Thread.Sleep(step); 
        Application.DoEvents(); 
       } 
      } 
      else 
      { 
       for (int y = 1; y < height; ++y) 
       { 
        Cursor.Position = new Point((b.X + ((int)(slope * y + 0.5))), (bottom - y)); 
        System.Threading.Thread.Sleep(step); 
        Application.DoEvents(); 
       } 
      } 
     } 
    } 

この方法は、私が試したことのないthis answer

+0

このコードは滑らかな動きをするが、imageboxは動かないビデオがぶら下がっている、私はスレッドにエラーがあると思うし、フォームアプリケーションを実行してマウスポインタも動くplace、 PSの動きも自動で頭の動きに追従しません。 –

+0

私はあなたに言ったように、これはトラック上にあなたを得るためだけです。このコードは別のスレッドにあるはずですが、私はビデオがハングアップしても驚きません。頭の動きに追従しない動きについては、マウスの目的地を示すものですが、このメソッドを目的地で呼び出すと、何らかの「取り消し」信号を実装する必要があります。それが目的地に達するまで動いてください。これはあなたを軌道に乗せるためですが、もちろんそれを多く改善する必要があります。 – Pikoh

関連する問題