4

我最近开始使用c++在OpenCV上工作。我对以下代码有问题。

#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);
}

这里对函数的调用cvCreateTrackbar作为参数,函数

void onTrackbarSlide(int pos)

但是当我调用这样的函数时 cvCreateTrackbar("Position", "Example3", &g_slider_position, frames, onTrackbarSlide(g_slider_position));`

它正在报告错误 error: invalid use of void expression

实际上我需要将 g_slider_position 传递给函数,以便知道滑块的位置。

我的一个朋友告诉我把这个函数称为

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

这不会报告任何错误,但它没有做它应该做的事情。滑块的位置是必要的。

所以,我的问题是如何使用参数 onTrackerSlide(及其整数参数)调用 cvCreateTracker。我希望我没有混淆。

谢谢!

4

2 回答 2

3

g_slider_position您的功能可以访问 - 您无法通过它。您应该使用您拥有的代码(来自您的朋友),但传递的 int 是跟踪栏的 id。

应该是这样的:

void onTrackbarSlide(int id) {
  cvSetCaptureProperty(
    g_capture,
    CV_CAP_PROP_POS_FRAMES,
    g_slider_position
  );
}
于 2010-10-12T19:09:44.397 回答
1

这是 C 函数指针使用的问题,我假设您从未使用过。

在创建轨迹栏时,您确实应该使用:

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

当你打电话时,你告诉 OpenCV 两条信息:

  1. 的地址g_slider_position
  2. 的地址onTrackbarSlide

现在,当移动该轨迹栏时,OpenCV 将:

  1. 直接修改g_slider_position(因此您实际上甚至不需要将其作为函数参数接收,但无论如何)
  2. call onTrackbarSlide(g_slider_position),它可以这样做,因为它知道这两条信息

如果您按照您尝试的方式编写代码:

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

在你写的地方onTrackbarSlide(g_slider_position),这变成了一个函数调用onTrackbarSlide. 换句话说,在试图找出你想要传递给 的值时cvCreateTrackbar,它调用onTrackbarSlide并将 的当前值传递给它g_slider_position,并希望它onTrackbarSlide会返回一个函数指针,因为这正是它所需要的。好的,它从来没有走那么远,因为它可以在编译时告诉onTrackbarSlide返回void,而事实void并非如此void(*aCallbackFunction)(int)(这就是你如何指定类型“一个接受 int 并且什么都不返回的函数”),但我使用的是叙述风格...

至于idvsposition论点,我不能凭经验说话。我刚刚从 willowgarage 中读到的文档表明您的回调接收的是位置,而不是 id,这意味着您无法使用单个回调来区分滑块。无论如何,我个人都不想这样做,因为这意味着我将拥有一个带开关的功能而不是多个功能。多个功能将(微观上)更有效,并且绝对更具可读性。

另一方面,cvCreateTrackbar确实返回一个 int,它可能是该 trackbar 的 id。不过,不确定你应该用它做什么。我刚刚阅读的文档页面上没有定义返回值的实际含义。鉴于这是一个 C API 并且缺少bool类型,这int可能只是一个真/假返回......

于 2010-10-29T02:16:49.873 回答