openCV blob info over OSC: Can OSC handle it?

Hello!
I’m using an openCV example to send blob information over OSC. At the moment this is being done inside the update() of my testApp.cpp, which means the application is trying to send OSC packets as fast as it can.
These are not big packets of information since they only carry centroid information for one blob at a time.
Can OSC handle this much information? It would almost look like a stream.

Also, can I send c++ vectors of blob information over OSC? or maybe static arrays?

Thank you all once again! =D

I’ve definitely sent several centroids over OSC before (from max/msp to Quartz composer). Depending on what the sender and receiver is it’s usually fine at 30fps, but definitely have a look at the OSC-spec to figure out what the best method might be. I think the time just changes based on how much data you’re sending.

I don’t think sending blob vectors over osc is as good an idea…thats a few orders of magnitude more data than just the x/y points of a centroid, so at best/worst it would probably be slow and drop a lot of packets of info…but that depends on how much latency you can handle in your project i suppose

This is very interesting. Thanks you very much laserpilot for the specs. =D

Since the amount of blobs changes over time depending on the scene I was thinking about sending the positions of the centroids as strings of characters and the parsing them on the other program. Does this seem like an acceptable approach? Would you recommend a better one? =D

This should not be a problem, kinect skeletons are routinely sent over osc these days.

–8

i would just put your sender in a for loop depending on the size of your blob vector and maybe format your messages like this (consider it pseudocode…):

  
for(int i=0; i< contourFinder.nBlobs() ; i++)  
m.setAddress("/" +ofToString(i)+"/x") ;  
//Other sending stuff here  
}  

so you get a different address for each blob that you can parse out on the other side or just set your maximum number of blobs and do it manually…probably just needs some data massaging on the other end to do exactly what you want

(oop…someone replied right before me…yes…totally forgot about osc is all the rage for kinect skeleton sending)

Cool! I was just not sure because this is the first time I use OSC, but this knowing that it can manage that is great!

@laserpilot
Thanks! I’ll try this. =D

The recieving end would have something like this right?

  
  
for (int count_blob = 0; count_blob < m.getNumArgs(); count_blob++){  
     if ( m.getAddress() == "/" +ofToString(count_blob)+"/" ){  
             // Code and stuff          
     }  
}  
  

Does “m.getNumArgs()” give me the ammount of values as I would expect here? It seems to work ok by the way!
Thanks you! :smiley:

i forget if getnumargs works like that…I’ve worked more with sending than receiving in oF. Maybe send a seperate OSC message that is just the number of blobs so you have that parsed out

Well that was much easier! xD Thanks!

Well it seems like I have an unforseen problem now!
The openCV OSC sending application is running and sending OSC packets at a rate of approx. 30 per second. The other application is running at approx. 60 fps or other. The examples “oscReceiveExample” and “oscSenderExample” have no mention of this type of problem so I’ll mention it.

I modified the oscReceiveExample code and it now looks like this:

  
  
if( receiver.hasWaitingMessages() == true) {  
      ofxOscMessage m;  
      receiver.getNextMessage( &m );  
      for (int cont_blob = 0; cont_blob < m.getNumArgs(); cont_blob++){  
         if ( m.getAddress() == "/" +ofToString(cont_blob)+"/" ){  
              int temp_mouseX = m.getArgAsInt32( 0 );  
              int temp_mouseY = m.getArgAsInt32( 1 );  
              ofPoint tmppos;  
              tmppos.set(temp_mouseX, temp_mouseY);  
              blob_position.push_back(tmppos);  
          }  
       }  
}  
  

The problem is that at some point I have to tell it to clear the vector because otherwise I’ll have a huge list of old states of each blob, but when I clear it un the update(), the draw() sometimes has no information to draw.
The problem being the rate of the recieved packets is much slower than the speed it is drawing. I’m thinking this problem might be solved by making another array that is almost permanent and only changes when there is information to be changed but I’m not sure.

Might you guys have any suggestions on how to approach this problem?
=D

Make your blob_position above a method variable and copy it into a class field iff it is not empty after your update in the above code.

–8

@eight:
I am doing this now. Thanks!

I’m getting weird behaviour. When I send over the INT that is supposed to be the Blob count I get strange integer numbers, like if 1 blob appears, is says there are 3, always rising with the amount of blobs I really don’t get this.
I checked everything before asking you guys. Any thoughts?

edit->
I figured out what it was, the value was actually the x coordenate of the first blob (the first arg). I was trying to use “addresses” but I guess it didn’t work:

if ( m.getAddress() == “/mouse/position” )
{}

edit 2->
Failed completely. Are there know issues with the ofxOsc addon?
I’ve had no luck trying to send over 1 integer that is the amount of blobs on the scene and each centroid whenever there is a blob on scene.

reedit-> I got what I wanted but I somehow think that the “address” parameters don’t really work, so I didn’t use them at all.

ofxOsc is a wrapper around OSCPack. The latter is the most popular and reliable implementation of OSC, although it has some issues when you try to send large amounts of data in one message, for example. For trivial cases like sending an Int, it should work. I think there might be a problem in your code.

–8

@eight
I believe you are right, I’ve still got a lot to learn about OSC.
Anyway, I managed to do what you told me before and now it works!

Thank you both! :smiley:

Hello,

If you’re still trying to send the contour info over OSC, poke around our project openTSPS (https://github.com/labatrockwell/openTSPS/). We’re using the really nice built-in OF contour simplification tools to send the full blob data over OSC.

(from https://github.com/labatrockwell/openTSPS/blob/master/addons/ofxTSPS/src/ofxTSPSPerson.cpp)

  
  
ofPolyline contour;  
ofPolyline simpleContour;  
  
void ofxTSPSPerson::update(ofxCvBlob blob, bool dampen){  
	contour		 = blob.pts;   
        simpleContour = contour;  
        simpleContour.simplify(2.0f);  
        float simplifyAmount = 2.5f;  
  
// simplify more if still too big  
    while (simpleContour.size() > 100){  
        simpleContour.simplify(simplifyAmount);  
        simplifyAmount += .5f;  
    }  
}  
  

which we are sending here (https://github.com/labatrockwell/openTSPS/blob/master/addons/ofxTSPS/src/communication/ofxTSPSOscSender.cpp)

  
  
   ofxOscMessage m;  
   m.setAddress( "blob" );  
  
   for (int i=0; i<p->simpleContour.size(); i++){  
      m.addFloatArg(p->simpleContour[i].x);  
      m.addFloatArg(p->simpleContour[i].y);  
   };  
  

Hope that helps! I think TSPS does a lot of the stuff you want to do, check it out!

1 Like

Sure it helps. I wanted to keep it simple this time but’ll read the source when I find the time!
Thank you =D