2016-05-17 7 views
0

Ich entwickle ein System genau wie Kamera Maus oder andere Face Control Maus, ich habe alle Funktionen implementiert, der Mauszeiger bewegt sich auch gut, aber ich möchte die Bewegung glatt wie die Maus den Zeiger zu steuern. der Code ich verwende ist:Wie steuert man den Mauszeiger mit Kopfbewegung mit 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

basiert habe ich nicht versucht, emgucv, aber das Problem scheint zu sein, dass der Positionsübergang nicht glatt ist. Ich denke, Sie sollten einen "Pfad" zwischen der aktuellen Mausposition und der nächsten berechneten Position berechnen. Dann müssen Sie die Maus "manuell" auf diesem Pfad bewegen. Ich weiß nicht, ob das Sinn macht – Pikoh

Antwort

0

Ok, ich bin sicher, dass es viele andere bessere Möglichkeiten gibt, aber das ist eine schnelle & schmutzige Art und Weise Cursorposition von Punkt a in einem „Smooth“ Art der Fortbewegung zu Punkt b. Natürlich kann und sollte diese Implementierung mit einem anderen Thread optimiert werden, anstatt Application.DoEvents() zu verwenden, um das Blockieren des UI-Threads zu vermeiden, aber ich hoffe, das bringt Sie auf die richtige Spur. Erstens, wie Sie es verwenden sollten. Statt:

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

sollten Sie dies tun:

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

nun die Umsetzung der 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(); 
       } 
      } 
     } 
    } 

Diese Methode auf this answer

+0

dieser Code macht glatte Bewegung, aber die Imagebox funktioniert nicht das Video hängt, ich denke, es gibt Fehler im Thread und als ich schließe das Formular Anwendung läuft und Mauszeiger auch Bewegungen an bestimmten Platz, PS Bewegung ist auch automatisch folgt nicht Kopfbewegung. –

+0

Wie ich Ihnen sagte, ist dies nur etwas, um Sie auf die Spur zu bringen. Dieser Code sollte in einem anderen Thread sein, ich bin nicht überrascht, das Video hängt. Über die Bewegung, die nicht der Kopfbewegung folgt, sind Sie diejenige, die den Zielpunkt der Maus angibt, aber Sie sollten wahrscheinlich ein "Cancel" -Signal implementieren, da, sobald Sie diese Methode mit einem Ziel aufrufen, die Maus würde fahre fort, bis es das Ziel erreicht. Dies ist nur, um Sie auf die Spur zu bringen, aber natürlich müssen Sie es sehr verbessern. – Pikoh

Verwandte Themen