Reputation: 1
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
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