math112311
math112311

Reputation: 1

C# WPF , Find coordinates according to Virtual Screen resolution

I"m working on a wpf project using kinect SDK and OpenCV , what I need to do is to create a box that follow the blob that showing in the kinect camera and check if the blob is inside a rectangle that been added by choosing 4 dots (corners of the recangle)

MCvBox2D box = contours.GetMinAreaRect();
openCVImg.Draw(box, new Bgr(System.Drawing.Color.Red), 2);

POINT p = new POINT { x = (int)box.center.X, y = (int)box.center.Y };

double minX = Math.Min(Canvas.GetLeft(dot1), Math.Min(Canvas.GetLeft(dot2), Math.Min(Canvas.GetLeft(dot3), Canvas.GetLeft(dot4))));
double minY = Math.Min(Canvas.GetTop(dot1), Math.Min(Canvas.GetTop(dot2), Math.Min(Canvas.GetTop(dot3), Canvas.GetTop(dot4))));
double maxX = Math.Max(Canvas.GetLeft(dot1), Math.Max(Canvas.GetLeft(dot2), Math.Max(Canvas.GetLeft(dot3), Canvas.GetLeft(dot4))));
double maxY = Math.Max(Canvas.GetTop(dot1), Math.Max(Canvas.GetTop(dot2), Math.Max(Canvas.GetTop(dot3), Canvas.GetTop(dot4))));
if (p.x >= minX && p.x <= maxX && p.y >= minY && p.y <= maxY)
{
...
}

the box is what created around the blob , and the dot1,..,dot4 is the corners of the rectangle and the POINT p is the center of the box . the if statement checking if the box found inside the rectangle

the problem is when I checked the coordinates of the Dots , they showed different coordinates from the point p . for example when box.X was over minX , it show the the coordinate of box.X = 125 and the coordinate of maxX=634.

I"ll more than happy to have any ideas what I did wrong here and how to fix it.

thanks

Upvotes: 0

Views: 109

Answers (1)

BionicCode
BionicCode

Reputation: 28948

You can use Visual.PointFromScreen to convert a point expressed in screen coordinates to the coordinate system of a Visual (in your case the hosting Canvas element).

You should also avoid mixing System.Drawing and System.Windows namespaces (and even Win32 types like POINT).
Because this is a WPF application you should immediately convert all System.Drawing types returned from the OpenCV API to System.Windows (WPF) types.

You can further improve your code by using Rect.Contains to test if a Point is contained within the rectangle defined by a Rect. Handling a Rect instead of "loose" coordinate points at least improves the readability of the code.

private void HandleTrackingBox(Contour<PointF> contour)
{
  MCvBox2D box = contour.GetMinAreaRect();
  openCVImg.Draw(box, new Bgr(System.Drawing.Color.Red), 2);
  var testPointFromScreen = new System.Windows.Point(box.center.X, box.center.Y);

  System.Windows.Rect referenceBounds = CreateReferenceBounds();
  bool isTestPointValid = IsScreenTestPointWithinBounds(referenceBounds, testPointFromScreen);
  if (isTestPointValid)
  {
    // TODO::Handle test point is within the bounds
  }
}

private System.Windows.Rect CreateReferenceBounds()
{
  double minX = Math.Min(Canvas.GetLeft(dot1), Math.Min(Canvas.GetLeft(dot2), Math.Min(Canvas.GetLeft(dot3), Canvas.GetLeft(dot4))));
  double minY = Math.Min(Canvas.GetTop(dot1), Math.Min(Canvas.GetTop(dot2), Math.Min(Canvas.GetTop(dot3), Canvas.GetTop(dot4))));
  double maxX = Math.Max(Canvas.GetLeft(dot1), Math.Max(Canvas.GetLeft(dot2), Math.Max(Canvas.GetLeft(dot3), Canvas.GetLeft(dot4))));
  double maxY = Math.Max(Canvas.GetTop(dot1), Math.Max(Canvas.GetTop(dot2), Math.Max(Canvas.GetTop(dot3), Canvas.GetTop(dot4))));

  double boundsWidth = maxX - minX;
  double boundsHeight = maxY - minY;
  var boundsSize = new System.Windows.Size(boundsWidth, boundsHeight);
  var boundsLocation = new System.Windows.Point(minX, minY);
  var referenceBounds = new System.Windows.Rect(boundsLocation, boundsSize);

  return referenceBounds;
}

private bool IsScreenTestPointWithinBounds(Rect referenceBounds, System.Windows.Point screenTestPoint)
{
  // Use the hosting Canvas to transform the screen point 
  // to a point relative to the Canvas element
  var relativeTestPoint = this.HostingCanvas.PointFromScreen(testPointFromScreen);
  return referenceBounds.Contains(relativeTestPoint);
}

Upvotes: 0

Related Questions