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 に次の 2 つの情報が伝えられます。

  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 を取り、何も返さない関数」という型を指定する方法です)、しかし、私はナラティブ スタイルを使用しています。 ...

idvsの議論についてはposition、経験から言えません。willowgarage から読んだばかりのドキュメントでは、コールバックは ID ではなく位置を受け取ると記載されています。つまり、単一のコールバックを使用してスライダーを区別する方法はありません。とにかく、私は個人的にそれをしたくありません.'cozは、複数の機能ではなく、スイッチを備えた1つの機能を持つことを意味します. 複数の関数は (微視的に) より効率的で、間違いなく読みやすくなります。

一方、cvCreateTrackbarそのトラックバーの ID である可能性がある int を返します。しかし、あなたがそれをどうするべきかはわかりません。戻り値の実際の意味は、私が読んだドキュメント ページでは定義されていませんでした。これが C API であり、bool型がないことを考えると、それintは単に true/false の戻り値になる可能性があります...

于 2010-10-29T02:16:49.873 に答える