Pass new variable to ofxCv example-contours-following

i am working of the ofxCv example-contours-following which creates an object for each tracked contour. the example calls them class Glow : public ofxCv::RectFollower

i am not able to work out how to pass additional variables in to these objects.

a simple thing i would like to do is adjust the dyingTime variable.
but even if i make dyingTime a public variable loop through all found followers it does not work

        followers.clear();
        followers = tracker.getFollowers();
        for(auto v:followers){
            ofLog()<<"auto dyingTime "<<dyingTime;
            v.setDyingTime(dyingTime);
        }

i guess i need a lesson about object orientated programming.

1 Like

I don’t see a reason why this should work. Did you properly declare you variable in the header file? Can you show us more of your code?

here a quick example.

dying time is a public variable set to 1 at creation.

during draw i set followers[i].dyingTime = 0.33
then in 2 different spots in the other object i print out dyingTime. one time in update and one in draw. both give me different reading.

your issue is that you declare vector<Glow> followers; in your header file and then you later assign followers = tracker.getFollowers(); in your ofApp::draw(). By doing so you copy the vector including it’s contents, if you then assign a new value to dyingTime it won’t affect the Object it’s intend for (but a copy of it). … using more high-level languages on my day to day work I’m also always suffering from this when coming back to such a low level language like C++ where you have to deal explicitly with “pass by reference” and “pass by value”.

Try this:

void ofApp::draw() {
    ofSetColor(255);
    movie.draw(0, 0);
    contourFinder.draw();
    vector<Glow> & followers = tracker.getFollowers();
    for(int i = 0; i < followers.size(); i++) {
        followers[i].dyingTime = 10;
        followers[i].draw();
        int temp_label = followers[i].getLabel();
    }
}

note here we’re using & which results in a reference instead of a copy of the vector that comes out of tracker.getFollowers().

thanks.

the reason why i declare vector followers in the .h file is because i need to reference followers also in update(), so it needs to be global.

i tried vector & followers in the header file, but get this error:
/Applications/of_v0.9.3_osx_release/addons/ofxCv/example-contours-following/src/main.cpp:5:15: Call to implicitly-deleted default constructor of ‘ofApp’

just call tracker.getFollowers(); also in your ofApp::update function.

thanks for continuing advice.

sure i will add followers = tracker.getFollowers(); to my update function.

BUT at this point if i try to follow your advice and try to add & to vector<Glow> & followers; in my header file then i get the above mentioned compile error.

you won’t need to add vector<Glow> & followers; in your header file, just use vector<Glow> & followers = tracker.getFollowers(); in you update and your draw functions. It won’t cost you anything as getFollowers() gives you a reference anyway.

https://en.wikipedia.org/wiki/Reference_c++

ok i see.

yes that now works. somehow.
as you know i am trying to modify dyingTime. this variable is being used in update, draw and kill.
seems like even thought the variables print out ok and the age indicating circles decrease faster or slower according to the set dyingTime, dying still happens on the original value set in the header.

here some of the print out and the new code.

[notice ] dyingTime in kill 10
[notice ] dyingTime in kill 10
[notice ] dyingTime in update 10
[notice ] dyingTime in kill 5.11
[notice ] dyingTime in kill 5.11
[notice ] dyingTime in kill 5.11
[notice ] dyingTime in draw 5.11
[notice ] 0 : 1
[notice ] dyingTime in draw 5.11
[notice ] 1 : 1
[notice ] dyingTime in draw 5.11
[notice ] 2 : 29
[notice ] dyingTime in kill 10
[notice ] dyingTime in kill 10
[notice ] dyingTime in update 10
[notice ] dyingTime in kill 5.11
[notice ] dyingTime in kill 5.11
[notice ] dyingTime in kill 5.11
[notice ] dyingTime in draw 5.11

Haven’t had a detailed look at your code yet … but this works for me: https://gist.github.com/m9dfukc/88b0a124d6a58dcc6e167067342efcac

thanks.

the reason why i am testing this is, because i am hoping to pass in other info about each blob and have this info stay in there.
I am planning to use this tracking method with a face finder like DLib (which does not provide ID lables). The face finder provides not just bounding rect but position of eyes etc, and the “follower” code would give me continues ID labels.

but it seems i would have to pass this info in to the followers every frame, just like we now have to pass dyingTime.

i am familiar if object orientated programming to a certain extend but this whole deal with followers = tracker.getFollowers(); confuses me.

you mean something like this https://github.com/m9dfukc/ofxDLib/commits/master … very ruff example of how it could work.

nice.
i will give that a try soon.
thanks :slight_smile:

yes works well.
i found that the displayed rect and label was flickering a lot.
might have something to do with for (unsigned int i = 0; i < dets.size(); ++i){ and gets.size() not being updated.
might also have to do with me running things in a different threads.

but when i draw it while looping through the shapes it looks stable.

 ofSetColor(ofColor::red);
    for (unsigned int n = 0; n < shapes.size(); ++n) {
        for (int i = 0; i < shapes[n].num_parts(); i++) {
            ofDrawCircle(toOf(shapes[n].part(i)),1);
        }
        ofDrawBitmapString(ofToString(tracker.getCurrentLabels()[n]), leftEyes[n]);
        
    }

herzlichen Dank

i guess now we are back to how this post started.

the question is how can i now add the eye positions to the “follower” object, have the “follower” accumulate those and average them over time.

the current follower-example accumulates the rect position because the ofxCv::tracker somehow auto calls void Glow::update(const cv::Rect& track). this is not called from ofApp::
that’s why i was experimenting with the dyingTime; i.e. adjusting/adding custom info.
still feel i still haven’t really solved this problem.

Ahm, yes. I had left out the Follower classes when I did the port of the ofxCv Tracker. Just added them in my last commit. Give me a bit and I’ll look into it … I assume you wanna have something like a RectTrackerFollower<face>?!

yes you are right.
and by bigger question is how to make these tracking objects that can contain all sorts of data: eye position, other feature position, maybe in the future person’s IDs/names and so on.

it seems silly to make a new object that could contain all this info. we already have the follower object, but i don’t know yet how to extend it to contain the above mentioned other info.
also hoping that the follower object could not just hold other data but also process it to a certain extend, like smoothing multiple reading.

thx

Ok,

added some more functionality to the FaceTracker class https://github.com/m9dfukc/ofxDLib/commits/master … not sure if this is the right approach. In general I think it would make sense to mirror the API of ofxFaceTracker.

Let me know if this makes any sense to you.

Shamelessly stealing from Kyle :wink:

just tested your additions to ofxDLib and it works great. :slightly_smiling:

will now try to use your TrackerFollower addition inside tracker.h since i am hoping to add accumulative data to each face, such as previous position of rect and eyes. so i can use them for smoothing.