views:

71

answers:

2

hello , I have recently started working on OpenCV using c++.I am having a problem with the following code.

#include "cv.h"
#include "highgui.h"
int g_slider_position = 0;
CvCapture* g_capture = NULL;

void onTrackbarSlide(int pos) {
  cvSetCaptureProperty(
    g_capture,
    CV_CAP_PROP_POS_FRAMES,
    pos
  );
}

int main( int argc, char** argv ) {
  cvNamedWindow( "Example3", CV_WINDOW_AUTOSIZE );
  g_capture = cvCreateFileCapture( "Aawaarapan.avi" );
  int frames = (int) cvGetCaptureProperty(
    g_capture,
    CV_CAP_PROP_FRAME_COUNT
  );
  if( frames!= 0 ) {
    cvCreateTrackbar(
      "Position",
      "Example3",
      &g_slider_position,
      frames,
      onTrackbarSlide //need to be call as onTrackbarSlide(g_slider_position) but gives error:invalid use of void expression 
    );
  }

  IplImage* frame;
  while(1) {
    frame = cvQueryFrame( g_capture );
    if( !frame ) break;

    cvShowImage( "Example3", frame );
    cvCreateTrackbar(
      "Position",
      "Example3",
      &g_slider_position,
      frames,
      onTrackbarSlide
    );

    char c = cvWaitKey(33);
    if( c == 27 ) break;

    ++g_slider_position;
  }

  cvReleaseCapture( &g_capture );
  cvDestroyWindow( "Example3" );
  return(0);
}

here the call to the function cvCreateTrackbar takes as argument, the function

void onTrackbarSlide(int pos)

but when i call the function like this cvCreateTrackbar( "Position", "Example3", &g_slider_position, frames, onTrackbarSlide(g_slider_position) );`

it is reporting an error error: invalid use of void expression

Actually i need to pass the g_slider_position to the function so that the slider's position is known.

A friend of mine told me to call the function as

cvCreateTrackbar(
  "Position",
  "Example3",
  &g_slider_position,
  frames,
  onTrackbarSlide
);

this doesn't report any error but it doesn't do what it is supposed to.the slider's position is necessary.

So, my question is how do i call the cvCreateTracker with argument onTrackerSlide(with its integer argument).hope i was not confusing . Thank you !!!!

+3  A: 

g_slider_position is accessible to your function -- you can't pass it. You should use the code you have (from your friend), but the int passed is the id of the trackbar.

Should be this:

void onTrackbarSlide(int id) {
  cvSetCaptureProperty(
    g_capture,
    CV_CAP_PROP_POS_FRAMES,
    g_slider_position
  );
}
Lou Franco
@lou what is id there???
CadetNumber1
how could that be? In the code you show, it's declared right above the function. If you moved it to another cpp, then you need to extern declare it with `extern int g_slider_position;`
Lou Franco
id is the id of the slider -- this is so you can share the same callback in multiple sliders.
Lou Franco
@lou yes you are right.actually misspelled it.
CadetNumber1
A: 

This is an issue of C function pointer usage, which I'm assuming you've never used.

At the point of creating the trackbar, you should indeed use:

cvCreateTrackbar(
  "Position",
  "Example3",
  &g_slider_position,
  frames,
  onTrackbarSlide
);

When you make that call, you are telling OpenCV two pieces of information:

  1. the address of g_slider_position
  2. the address of onTrackbarSlide

Now, when that trackbar is moved, OpenCV will:

  1. modify g_slider_position directly (so you don't actually even need to receive it as a function parameter, but anyway)
  2. call onTrackbarSlide(g_slider_position), which it can do because it knows both pieces of information

If you write the code the way you were trying to:

cvCreateTrackbar(
  "Position",
  "Example3",
  &g_slider_position,
  frames,
  onTrackbarSlide(g_slider_position)
);

Where you wrote onTrackbarSlide(g_slider_position), that turned into a function invocation of onTrackbarSlide. In other words, while trying to figure out what values you wanted to pass to cvCreateTrackbar, it called onTrackbarSlide and passed it the current value of g_slider_position, and hoped that onTrackbarSlide would return a function pointer, because that's what it needed. OK, it never got that far, because it could tell at compile time that onTrackbarSlide returned void, and that void was not void(*aCallbackFunction)(int) (which is how you specify the type "a function that takes an int and returns nothing"), but I'm using narrative style...

As for the id vs position argument, I can't speak from experience. The docs I just read from willowgarage state that your callback receives the position, not the id, which means you have no way to use a single callback to differentiate between sliders. I personally wouldn't want to do that anyway, 'coz it means I'd have one function with a switch instead of multiple functions. Multiple functions will be (microscopically) more efficient, and definitely more readable.

On the other hand, cvCreateTrackbar does return an int, which might be the id of that trackbar. Not sure what you're supposed to do with it, though. The actual meaning of the return value was not defined on the doc page I just read. Given that this is a C API and lacks a bool type, that int might just be a true/false return...

DigitalMonk