I'm trying to detect the moving objects with my webcam, where I want to detect the position on my two fingers moving, so I can scale an image according to the move of my fingers, like if it was a touch screen, but I want to achieve that with camera and detecting moving fingers, so if I move my two fingers to each other the image get smaller, and if I move them away from each other the image get biger.
Here is my code:
MotionDetector detector;
BlobCountingObjectsProcessing motionProcessing;
motionProcessing = new BlobCountingObjectsProcessing();
detector = new MotionDetector(new TwoFramesDifferenceDetector(), motionProcessing);
What I get is many rectangles around each finger. How can I recognize each finger separately?
Thanks alot.
Use RANSAC to fit two lines through the centroids of the rectangles, one for each finger. The difference in slopes between the two lines will give you an indication of how far apart they are. So the gradient of slope differences will tell you how to scale the image and by how much.
Related
I am trying to implement some kind of snapping functionality in WPF for a circle (which represents my mouse) and it should snap to another object (normally this would be a line or a rectangle).
Is there a way to do this kind of functionality with WPF without doing all the calculations on my own and if not is there an easy way (library?) to get this kind of information?
Edit: I want to snap the border of the circle to the border of the rectangle/line.
As a first step, you should find the point on the rectangle that is the closest to the cursor, and the distance between the two: extending the edges of the rectangle, you partition the plane into 9 regions. Depending on the region where the cursor lies, the searched distance will be the distance to a corner (Euclidean distance formula) or the distance to an edge (difference of abscissas or ordinates).
Subtract the circle radius from this distance. This will tell you if you are close enough for a snap.
When a snap is possible, move the cursor along the line from the current cursor position to the closest point until you hit the corner or edge. You will need to use the parametric equation of the line segment.
The complete discussion requires some care but only involves simple math.
A similar approach is possible to snap to a line segment. Here is a trick: if you rotate the line segment to make it horizontal, you can consider the line segment as a degenerate rectangle and use the same snapping algorithm. Rotate the line segment and the cursor, apply the snapping logics and then counter-rotate the updated cursor.
That kind of functionality only takes a few lines of code to replicate... I doubt that you'll find a 'library' of code to do it for you. The method is as follows:
Keep a collection that contains the 4 Points that form each shape's bounding box. You then need to handle to MouseMove event on the Canvas, or shape container. In this event, you simply need to ascertain whether the current mouse position is within a certain distance from any of the shape edges... you'll have a little bit more work to do with non-rectangular shapes to calculate their edges, but the principal is the same.
If you detect the presence of a nearby shape, then you simply need to change the value of the nearest dimension to that of the nearby shape... the snap. That's it... much easier than you think.
I have an unknown amount of polygons, all facing the camera (-z) with different positions. I want to rotate each polygon around its center by different angles. Would it be faster to use glRotate and glTranslate, or to calculate the rotation myself, or to do something else?
I have a map, containing many objects in an area sized 5000*5000.
my screen size is 800*600.
how can i scroll my map, i don't want to move all my objects left and right, i want the "camera" to move, But unfortunately i didn't found any way to move it.
Thanks
I think you are looking for the transformMatrix parameter to SpriteBatch.Begin (this overload).
You say you don't want the objects to move, but you want the camera to move. But, at the lowest level, in both 2D and 3D rendering, there is no concept of a "camera". Rendering always happens in the same region - and you must use transformations to place your vertices/sprites into that region.
If you want the effect of a camera, you have to implement it by moving the entire world in the opposite direction.
Of course, you don't actually store the moved data. You just apply an offset when you render the data. Emartel's answer has you do that for each sprite. However using a matrix is cleaner, because you don't have to duplicate the code for every single Draw - you just let the GPU do it.
To finish with an example: Say you want your camera placed at (100, 200). To achieve this, pass Matrix.CreateTranslation(-100, -200, 0) to SpriteBatch.Begin.
(Performing a frustum cull yourself, as per emartel's answer, is probably a waste of time, unless your world is really huge. See this answer for an explanation of the performance considerations.)
Viewport
You start by creating your camera viewport. In the case of a 2D game it can be as easy as defining the bottom left position where you want to start rendering and expand it using your screen resolution, in your case 800x600.
Rectangle viewportRect = new Rectangle(viewportX, viewportY, screenWidth, screenHeight);
Here's an example of what your camera would look like if it was offset off 300,700 (the drawing is very approximate, it's just to give you a better idea)
Visibility Check
Now, you want to find every sprite that intersects the red square, which can be understood as your Viewport. This could be done with something similar to (this is untested code, just a sample of what it could look like)
List<GameObject> objectsToBeRendered = new List<GameObject>();
foreach(GameObject obj in allGameObjects)
{
Rectangle objectBounds = new Rectangle(obj.X, obj.Y, obj.Width, obj.Height);
if(viewportRect.IntersectsWith(objectBounds))
{
objectsToBeRendered.Add(obj);
}
}
Here's what it would look like graphically, the green sprites are the ones added to objectsToBeRendered. Adding the objects to a separate list makes it easy if you want to sort them from Back to Front before rendering them!
Rendering
Now that we found which objects were intersecting we need to figure out where on the screen the will end up.
spriteBatch.Begin();
foreach(GameObject obj in objectsToBeRendered)
{
Vector2 pos = new Vector2(obj.X - viewportX, obj.Y - viewportY);
spriteBatch.Draw(obj.GetTexture(), pos, Color.White);
}
spriteBatch.End();
As you can see, we deduce the X and Y position of the viewport to bring the world position of the object into Screen Coordinates within the viewport. This means that the small square that could be at 400, 800 in World Coordinates would be rendered at 100, 100 on the screen given the viewport we have here.
Edit:
While I agree with the change of "correct answer", keep in mind that what I posted here is still very useful when deciding which animations to process, which AIs to update, etc... letting the camera and the GPU make the work alone prevents you from knowing which objects were actually on screen!
For those of you who don't remember exactly what the old windows Starfield screensaver looked like, here's a YouTube video: http://www.youtube.com/watch?v=r5AoFiVs2ME
Right now, I can generate random particles ("stars") inside in a certain radius. What I've having trouble doing is figuring out the best way the achieve the affected seen in the afore-linked video.
Question: Given that I have the coordinates (vectors) for my randomly generated particles. What is the best way and/or equation to give them a direction (vector) so that they move across the screen in a way which closely resembles that which is seen in the old screensaver?
Thanks!
They seem to move away from the center. You could try to calculate the vector from the center point of the screen to the generated particle position? Then use the same direction to move the particle and accelerate the particle until it is outside the screen.
A basic algorithm for you to work with:
Generate stars at random location, with a 3-D gaussian distribution (middle of screen most likely, less likely as you go farther from the screen). Note that the motion vector of the star is determined by this starting point... the motion will effectively travel along the line formed by the origin point and the starting location, outward.
Assign each newly generated star a distance. Note that distance is irrespective of starting location.
Move the star in a straight line at an exponentially increasing speed while simultaneously decreasing it's distance. You'll have to tweak these parameters yourself.
The star should disappear when it passes the boundary of the screen, regardless of speed.
I am doing some sort of drawing software in WPF, and I have certain visual elements in a Canvas like for example Rectangles and Lines. I have implemented dragging of those elements around the Canvas to move them. The motion must be aligned to pixels, I read WPF uses points and not pixels so it has become a concern of mine to know whether my lines or rectangles are aligned to pixels. I tried using SnapsToPixels, but I'm not sure it will do the trick, or if it will do it when I'm moving the visuals around.
Finally, I must implement moving visuals with the keyboard, a single cursor stroke means move the visual exactly one pixel, how can I do this from the code behind? I assume doing something like:
Canvas.SetLeft(visual) = Canvas.GetLeft(visual) + 1;
Will only add one point to its position, and not one pixel, how can I move exactly one pixel in the Canvas?
Thank you very much.
It might help to use SnapToDevicePixels for your canvas.
Is this what you are looking for?
Matrix m =
PresentationSource.FromVisual(Application.Current.MainWindow)
.CompositionTarget.TransformToDevice;
double pixelSizeX = m.M11;
double pixelSizeY = m.M22;