Rapidly trigger a single frame with an OpenNI device?

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Rapidly trigger a single frame with an OpenNI device?

james
Administrator
Hi,

I am currently working on a dynamic application, so rather than constantly streaming from the device, I would like to rapidly trigger a single frame.
Buffering, and doing something like getLatestCloud is not appropriate, as this means I have no control over the  moment of exposure (which I have trialed).

I have also trialed simply using the start and stop commands of the grabber, but this is slow, meaning it takes about 680ms to get the cloud after the trigger.

Furthermore, I have trialed by connecting and disconnecting the boost signals of the grabber, but this is still too slow, taking about 350ms to get the cloud after the trigger. Example code based on information from http://pointclouds.org/documentation/tutorials/openni_grabber.php#openni-grabber:
c = interface->registerCallback (f); // register callback and store connection to c
interface->start (); // start the grabber
c.disconnect (); // disconnect the connection without stopping whole grabber
c = interface->registerCallback (f); // re-register callback and store connection to c, to trigger a frame capture

Is there a way to rapidly get a single new frame, without any major custom coding?
Or if not, does anyone have any pointers how I should go about coding in such functionality?
Reply | Threaded
Open this post in threaded view
|

Re: Rapidly trigger a single frame with an OpenNI device?

kwaegel
Administrator
james wrote
Hi,

I am currently working on a dynamic application, so rather than constantly streaming from the device, I would like to rapidly trigger a single frame.
Buffering, and doing something like getLatestCloud is not appropriate, as this means I have no control over the  moment of exposure (which I have trialed).

...

Is there a way to rapidly get a single new frame, without any major custom coding?
Or if not, does anyone have any pointers how I should go about coding in such functionality?
Getting a specific exposure time will be tricky, no matter which way you go about it. Cheap devices like the Kinect and Xtion just don't have much support for external synchronization.

Just listening for the frames and discarding all but the one you want should get you within 33 ms, as long as you account for the transfer latency (~50 ms). Any better than that and I suspect you will need a (expensive) camera that supports a hardware sync signal.
Reply | Threaded
Open this post in threaded view
|

Re: Rapidly trigger a single frame with an OpenNI device?

james
Administrator
This post was updated on .
Hi,

I am just using a constant stream, and grabbing the latest frame whenever I have received a trigger. This, however, seems to insist on grabbing the frame prior to the trigger being received, not the frame after.

Here is the code for my grabber callback:

        void cloud_cb_ (const CloudConstPtr &cloud)
        {
                boost::mutex::scoped_lock lock (mtx_);
                if (TriggerReceived)
                {
                        cloud_  = cloud;
                        char IOserialWriteData = 's';
                        io_serial->write(&IOserialWriteData,1);
                        CloudGatheredAfterTrigger = true;
                        TriggerReceived = false;
                        FrameTime = StopWatch.getTime();
                        cout << "Time between Trigger and Frame: " << FrameTime - TriggerTime << " ms" << endl;
                }
        }


and here is where it is being viewed:

while (!viewer->wasStopped () )
                {
                        if (CloudGatheredAfterTrigger)
                        {
                                //lock while we set our cloud;
                                boost::mutex::scoped_lock lock (mtx_);
                                cout << "im here" << endl;
                                //the call to GetLatestCloud() sets the cloud_ to null;
                                //GetLatestCloud();
                                //viewer = Vis(GetLatestCloud());
                                viewer = Vis(cloud_);
                                viewer->spinOnce (1);
                                CloudGatheredAfterTrigger = false;
                        }
                }


This even happens for the first trigger, so it must be copying cloud to cloud_, before cloud has been filled again?
Can anyone see the problem?
I think it might be due to the way I am handling shared pointers?