2016-08-16 17 views
1

現在、Kinectと一緒にEmguCVライブラリを使用してWPFを使用して簡単なヒットテストを作成しています。私はチェス盤のコーナーを見つけて四角形の四隅として四角形のリストに格納することができます。次に、LeftMouseButtonUpイベントを使用してマウスの位置を取得し、長方形。マウスクリックのイベント座標が、見つかったチェス盤のコーナー座標と一致していないか、または一致していません - EmguCV/WPF

問題は、EmguCVがチェス盤のコーナーとして返す座標とマウスクリックイベントが並べられていないので、ヒット(つまり、四角形内のマウスクリック)を検出できないと思われるということです。どのようにこれらの2つの座標を整列させるには?何か不足していますか?

XAML:

<Window x:Class="EmguMotionTest.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="350" Width="525" KeyDown="Window_KeyDown" > 
    <Grid> 
     <Image Name="rgbImage" Stretch="Fill" MouseLeftButtonUp="rgbImage_MouseLeftButtonUp"/> 
     <Line Name="line" Stroke="Red" StrokeThickness="1" Visibility="Visible" /> 
    </Grid> 
</Window> 

C番号:

public partial class MainWindow : Window 
{ 
    /*Kinect Initialization*/ 
    KinectSensor _kinectSensor; 

    /*Getting the Chessboard corners*/ 
    PointF[] corners = new PointF[] { }; 
    PointF[] points = new PointF[4]; 
    List<PointF> cornerPts = new List<PointF>(); 
    List<List<PointF>> rectangle = new List<List<PointF>>(); 
    /*Defining the Chessboard parameters */ 
    const int width = 4; 
    const int height = 4; 
    Drawing.Size boardSize = new Drawing.Size(width, height); 

    public MainWindow() 
    { 
     InitializeComponent(); 

     this.Unloaded += delegate 
     { 
      _kinectSensor.ColorStream.Disable(); 
     }; 

     this.Loaded += delegate 
     { 
      _kinectSensor = KinectSensor.KinectSensors[0]; 

      _kinectSensor.ColorStream.Enable(); 
      _kinectSensor.Start(); 

      BackgroundWorker bw = new BackgroundWorker(); 
      bw.DoWork += (a, b) => Pulse(); 
      bw.RunWorkerCompleted += (c, d) => bw.RunWorkerAsync(); 
      bw.RunWorkerAsync(); 
     }; 
    } 

    /*Polling event to retrieve Data from Kinect*/ 
    private void Pulse() 
    { 
     using (ColorImageFrame imageFrame = _kinectSensor.ColorStream.OpenNextFrame(200)) 
     { 
      if (imageFrame == null) 
       return; 

      //Converting a Kinect Color Frame to EmguCV Image 
      Image<Bgr, Byte> imageCap = imageFrame.ToOpenCVImage<Bgr, Byte>(); 

      Image<Gray, Byte> gray = imageCap.Convert<Gray, Byte>(); 

      corners = CameraCalibration.FindChessboardCorners(gray, boardSize, Emgu.CV.CvEnum.CALIB_CB_TYPE.ADAPTIVE_THRESH | Emgu.CV.CvEnum.CALIB_CB_TYPE.FILTER_QUADS); 

      if (corners != null) 
      { 
       CvInvoke.cvFindCornerSubPix(gray, corners, corners.Length, new Drawing.Size(11, 11), new Drawing.Size(-1, -1), new MCvTermCriteria(30, 0.1)); 
       CameraCalibration.DrawChessboardCorners(gray, boardSize, corners); 

       //Displaying the result in WPF 
       this.Dispatcher.Invoke(
         new Action(() => rgbImage.Source = gray.ToBitmapSource()) 
         ); 
      } 
      else 
      { 
       //Displaying the result in WPF 
       this.Dispatcher.Invoke(
         new Action(() => rgbImage.Source = gray.ToBitmapSource()) 
         ); 
      } 

     } 
    } 

    private void Window_KeyDown(object sender, KeyEventArgs e) 
    { 
     if (e.Key == Key.Space) 
     { 
      //Clear out the List of points 
      if (cornerPts != null) 
      { 
       cornerPts.Clear(); 
      } 

      //Enter all the found corners into an array stored as polygons 
      for (int i = 0; i < boardSize.Height - 1; i++) 
      { 
       for (int j = 0; j < boardSize.Width - 1; j++) 
       { 
        //Getting the corners of the squares (Square 1, 2, 3).. 
        int p1 = (i * boardSize.Width) + j; 
        int p2 = (i * boardSize.Width) + j + 1; 
        int p3 = ((i + 1) * boardSize.Width) + j; 
        int p4 = ((i + 1) * boardSize.Width) + j + 1; 

        //Add range method 

        points[0] = corners[p1]; 
        points[1] = corners[p2]; 
        points[2] = corners[p3]; 
        points[3] = corners[p4]; 

        cornerPts.AddRange(points); 
        rectangle.Add(new List<PointF>() { points[0], points[1], points[2], points[3] }); 
       } 
      } 
     } 

     /*To test the corners points are being added correctly */ 
     if (e.Key == Key.D) 
     { 
      Console.WriteLine("D button press registered"); 

      ///*Test Square */ 
      for (int c = 0; c < rectangle.Count; c++) 
      { 
       for (int n = 0; n < 4; n++) 
       { 
        Console.WriteLine("Triangle no: " + c + "," + n + rectangle[c][n]); 
       } 
      } 
     } 
    } 

    private void rgbImage_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) 
    { 
     System.Windows.Point p = Mouse.GetPosition(rgbImage); 
     Console.WriteLine("MouseX: " + p.X + "," + "MouseY: " + p.Y); 

     Console.WriteLine("-------------Hit Test---------------"); 
     /*Test Square */ 
     for (int c = 0; c < rectangle.Count; c++) 
     { 
      for (int n = 0; n < 4; n++) 
      { 
       //Console.WriteLine("Triangle no: " + c + "," + n + rectangle[c][n]); 

       if ((p.X > rectangle[c][0].X && p.X < rectangle[c][1].X) && (p.Y > rectangle[c][0].Y && p.Y < rectangle[c][2].Y)) 
       { 
        Console.WriteLine("Triangle HIT is triangle no: " + c); 
       } 

      } 
     } 
    } 
} 

答えて

2

マウスの位置が画像に応じてスケーリングしなければなりませんでした。正しい画素値を

を取得するようにパルス()メソッドは、ビットマップのPixelWidthとPixelHeightを抽出し、画像制御

/*Polling event to retrieve Data from Kinect*/ 
    private void Pulse() 
    { 

     using (ColorImageFrame imageFrame = _kinectSensor.ColorStream.OpenNextFrame(200)) 
     { 
      if (imageFrame == null) 
       return; 

      //Converting a Kinect Color Frame to EmguCV Image 
      Image<Bgr, Byte> imageCap = imageFrame.ToOpenCVImage<Bgr, Byte>(); 

      Image<Gray, Byte> gray = imageCap.Convert<Gray, Byte>(); 

      corners = CameraCalibration.FindChessboardCorners(gray, boardSize, Emgu.CV.CvEnum.CALIB_CB_TYPE.ADAPTIVE_THRESH | Emgu.CV.CvEnum.CALIB_CB_TYPE.FILTER_QUADS); 

      if (corners != null) 
      { 
       CvInvoke.cvFindCornerSubPix(gray, corners, corners.Length, new Drawing.Size(11, 11), new Drawing.Size(-1, -1), new MCvTermCriteria(30, 0.1)); 
       CameraCalibration.DrawChessboardCorners(gray, boardSize, corners); 

       pixelWidth = gray.ToBitmapSource().PixelWidth; 
       pixelHeight = gray.ToBitmapSource().PixelHeight; 

       //Displaying the result in WPF 
       this.Dispatcher.Invoke(
         new Action(() => rgbImage.Source = gray.ToBitmapSource()) 
         ); 
      } 
      else 
      { 
       //Displaying the result in WPF 
       this.Dispatcher.Invoke(
         new Action(() => rgbImage.Source = gray.ToBitmapSource()) 
         ); 

      } 
     } 
    } 

    private void rgbImage_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) 
    { 
     System.Windows.Point p = Mouse.GetPosition(rgbImage); 

     var pixelMousePosX = e.GetPosition(rgbImage).X * pixelWidth/rgbImage.ActualWidth; 
     var pixelMousePosY = e.GetPosition(rgbImage).Y * pixelHeight/rgbImage.ActualHeight; 

     Console.WriteLine("MousePixelX: " + pixelMousePosX + "," + "MousePixelY: " + pixelMousePosY); 

     /*Test Square */ 
     for (int c = 0; c < rectangle.Count; c++) 
     { 
      for (int n = 0; n < 4; n++) 
      { 
       if ((pixelMousePosX > rectangle[c][0].X && pixelMousePosX < rectangle[c][1].X) && (pixelMousePosY > rectangle[c][0].Y && pixelMousePosY < rectangle[c][2].Y)) 
       { 
        Console.WriteLine("Triangle HIT is triangle no: " + c); 
       } 

      } 
     } 
    } 
に応じてマウスの位置をスケール
関連する問題