I recently bought a GigE camera tha came bundles with its SDK. One of the examples explains how to grab frames from the camera through a callback function. It works in the following way:
void OnImageGrabbed(Image* pImage, const void* pCallbackData)
{
printf( "Grabbed image %d\n", imageCnt++ );
return;
}
//...
int main(int argc, char** argv)
{
camera.StartCapture(OnImageGrabbed);
}
the above is based on a simple cpp program (no objects involved).
Now I am trying to incorporate the functionality in my object oriented application (written in openFrameworks ). I am really fuzzy as to how to do that and I haven't been able to find close enough example to follow on the internet.
basically what I do in my header
file:
class ofApp : public ofBaseApp{
public:
void setup();
void update();
void draw();
friend void OnImageGrabbed(Image* pImage, const void* pCallbackData);
bool bNewFrameArrived;
};
then in my implementation
(.cpp) file
void ofApp::setup()
{
bNewFrame = false ;
cam.StartCapture(OnImageGrabbed);
}
void OnImageGrabbed(Image* pImage, const void* pCallbackData)
{
bNewFrame = false ;
cout<< "Grabbed image" << endl;
bNewFrame = true ;
}
void ofApp::update(){
//somehow grab the pImage. but how???
if ( bNewFrame )
//do stuff
}
having this as a friend class is fine, but how can I access the instantiation of the ofApp
class (namely the bNewFrame variable)? Also how can I access pImage
afterwards from my update()
member function?
Thank you for your help!
There are couple of ways, depending on can you use member functions or even lambdas as a callback. If it is a C-style function pointer, then options are slightly limited.
Firstly, you could add a static std::deque
or std::vector
to file scope, where callback pushes the image pointers. After that, process whatever Image
pointers the queue/vector holds. See the following.
static std::vector<Image*> s_imageQueue;
....
void onImageGrabbed(Image* image, const void* callbackData)
{
s_imageQueue.push_back(image);
}
...
void ofApp::update()
{
...
for (auto image : s_imageQueue)
{
// process image
}
s_imageQueue.clear();
...
}
If camera.StartCapture()
accepts std::function<void(Image*,const void*)>
, you could just do something like the following.
void ofApp::setup()
{
camera.StartCamera( [] (Image* image, const void* data) {
// process image here
});
}