Storing previous position of object?


#1

Hi all! I’m having some trouble with getting the coordinates from the previous frame of one of my shapes. What I have going on right now is a project that uses blob tracking to interact with ofxBox2d shapes/joints. I’m trying to get the previous position of the smoothedPoint variable I’m tracking in order to check when the point is moving (using the solution from this thread: https://forum.openframeworks.cc/t/storing-mouse-position/14303) and to use to check the object’s velocity (which I am unsure of if I’m doing that right).

I tried this method (here: https://forum.openframeworks.cc/t/get-previous-mouse-coordinate/16802) for getting the previous position, which is having an ofPoint and setting it equal to the current position of the point I’m tracking at the end of update, but that doesn’t seem to be working.

The previous movement is working with this project, so I feel like I’m not too far off: https://github.com/tespin/interactiveLine

Below is the code. The middle of it is dealing with Kinect/Box2d stuff. In the beginning of the update function I have a conditional statement to check if the mouse is moving, and at the end of it, I’m 1) checking to see if the mouse is moving, and if it is, setting it to false, and 2) setting the prev position to the current position. The formatted code is below:

void ofApp::update()
{	
	ofBackground(100, 100, 100);
    
    if (prevPosition != smoothedPoint)
    {
        mouseMoving = true;
        std::cout << "mouseMoving" << endl;
    }
    
    ofPoint ballDist = ofPoint(smoothedPoint - prevPosition);
    
    // Kinect----------------------------------------------------------------------------
    kinect.update();
    
    // there is a new frame and we are connected
    if(kinect.isFrameNew()) {
        
        // load grayscale depth image from the kinect source
        grayImage.setFromPixels(kinect.getDepthPixels());
        // we do two thresholds - one for the far plane and one for the near plane
        // we then do a cvAnd to get the pixels which are a union of the two thresholds
        grayThreshNear = grayImage;
        grayThreshFar = grayImage;
        grayThreshNear.threshold(nearThreshold, true);
        grayThreshFar.threshold(farThreshold);
        cvAnd(grayThreshNear.getCvImage(), grayThreshFar.getCvImage(), grayImage.getCvImage(), NULL);
        // update the cv images
        grayImage.flagImageChanged();
        
        // find contours which are between the size of 100 pixels and 1/2 the w*h pixels.
        // also, find holes is set to true so we will get interior contours as well....
        contourFinder.findContours(grayImage, 100, (kinect.width*kinect.height)/2, 1, false);
    }
    
    
    // Find the tip of the biggest blob.  We only search for one blob.
    for (int i = 0; i < contourFinder.nBlobs; i++){
        float maxY = std::numeric_limits<float>::lowest();
        std::size_t index = 0;
        std::vector<ofPoint>& points = contourFinder.blobs[i].pts;
        
        // go around contour to find the highest value of Y (i.e. the lowest in our setup).
        for (int p = 0; p < points.size(); ++p)
        {
            if (points[p].y > maxY)
            {
                maxY = points[p].y;
                index = p;
            }
        }
        
        // Smooth the position with a simple low pass filter.
        smoothedPoint = smoothedPoint * alpha + points[index] * (1.0 - alpha);
    }
    //far: 205, near: 255
    cout << "Far Threshold: " << farThreshold << "Near Threshold: " << nearThreshold << endl;
    // Kinect----------------------------------------------------------------------------
    
// Box2d-----------------------------------------------------------------------------
    box2d.update();
    
    friendlyTimer = ofGetElapsedTimef();
    
    deg += 0.3;
    
    pointDelta = smoothedPoint.distance(prevPosition);
    pointVelocity = pointDelta / velocityTimer;
    
    setFriendly();
    
    if (mouseMoving)
    {
        mouseMoving = false;
    }
    
    prevPosition = ofPoint(smoothedPoint);
    
//    std::cout << "Previous position: " << prevPosition << " Current Position: " << smoothedPoint << endl;
    std::cout << "ball dist" << ballDist << endl;
// Box2d-----------------------------------------------------------------------------
}

In case it’s necessary to look at the whole project, here is a link: https://github.com/tespin/Buddy/tree/master/Buddy/src

Thanks.


#2

Instead of comparing the points exactly (which is not recommended for various reasons), I’d subtract the current position from the last position, which will give you a “velocity” vector. Then take the magnitude of that vector … then check and see if that velocity magnitude is greater than some threshold.


#3

And if it is greater than that threshold, I can set mouseMoving to true?


#4

Yep. The velocity gives you a direction, but you don’t care about the direction. You just want the scalar magnitude so it doesn’t matter which direction it’s going in, just that it’s moving above a certain speed.


#5

Thanks Chris! I really appreciate your help. Also, I sent you an email about getting to talk to you. Let me know when would be a good time!