OpenCV - 让滑块在视频播放期间更新其位置

发布于 2024-10-17 21:23:05 字数 1305 浏览 1 评论 0原文

我选择了“学习 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("The Tom 'n Jerry Show", CV_WINDOW_AUTOSIZE);
    g_capture = cvCreateFileCapture(argv[1]);
    int frames = (int) cvGetCaptureProperty(
        g_capture, 
        CV_CAP_PROP_FRAME_COUNT
        );

    if (frames != 0)
    {
        cvCreateTrackbar(
            "Position",
            "The Tom 'n Jerry Show",
            &g_slider_position,
            frames,
            onTrackbarSlide
            );
    }

    IplImage* frame;

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

        cvSetTrackbarPos(
            "Position", 
            "The Tom 'n Jerry Show",
            ++g_slider_position
            );

        cvShowImage("The Tom 'n Jerry Show", frame);
        char c = cvWaitKey(33);
        if (c == 27)
            break;
    }

    cvReleaseCapture(&g_capture);
    cvDestroyWindow("The Tom 'n Jerry Show");

    return 0;
}

任何想法如何让滑块和视频按预期工作?

I've picked up 'Learning OpenCV' and have been trying some of the code examples/exercises. In this code snippet, I want to get the slider to update its position with each video frame change, but for some reason it won't work (the picture freezes 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("The Tom 'n Jerry Show", CV_WINDOW_AUTOSIZE);
    g_capture = cvCreateFileCapture(argv[1]);
    int frames = (int) cvGetCaptureProperty(
        g_capture, 
        CV_CAP_PROP_FRAME_COUNT
        );

    if (frames != 0)
    {
        cvCreateTrackbar(
            "Position",
            "The Tom 'n Jerry Show",
            &g_slider_position,
            frames,
            onTrackbarSlide
            );
    }

    IplImage* frame;

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

        cvSetTrackbarPos(
            "Position", 
            "The Tom 'n Jerry Show",
            ++g_slider_position
            );

        cvShowImage("The Tom 'n Jerry Show", frame);
        char c = cvWaitKey(33);
        if (c == 27)
            break;
    }

    cvReleaseCapture(&g_capture);
    cvDestroyWindow("The Tom 'n Jerry Show");

    return 0;
}

Any idea how to get the slider and video to work as intended?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

屋顶上的小猫咪 2024-10-24 21:23:05
This is the actual working code



// PROGRAM TO ADD A UPDATING TRACKBAR TO A VIDEO

#include <cv.h>
#include <highgui.h>


int g_slider_position = 0;
CvCapture* video_capture = NULL;

void onTrackbarSlide(int current_frame)
{
    current_frame = g_slider_position;
    cvSetCaptureProperty(video_capture,CV_CAP_PROP_POS_FRAMES,current_frame);
}

int main( int argc, char** argv )
{
    cvNamedWindow( "Video", CV_WINDOW_AUTOSIZE );
    video_capture = cvCreateFileCapture( "Crowdy.avi");
    int no_of_frames = (int) cvGetCaptureProperty(video_capture,CV_CAP_PROP_FRAME_COUNT);
    if( no_of_frames!= 0 ) 
    {
        cvCreateTrackbar("Slider","Video",&g_slider_position,no_of_frames,onTrackbarSlide);
    }

    IplImage* frame;

    while(1) 
    {
        frame = cvQueryFrame( video_capture );
        if( !frame ) break;
        cvShowImage( "Video", frame );
        cvSetTrackbarPos("Slider","Video",++g_slider_position);
        char c = cvWaitKey(33);
        if( c == 27 ) break;
    }
    cvReleaseCapture( &video_capture );
    cvDestroyWindow( "Video" );

    return(0);
}
This is the actual working code



// PROGRAM TO ADD A UPDATING TRACKBAR TO A VIDEO

#include <cv.h>
#include <highgui.h>


int g_slider_position = 0;
CvCapture* video_capture = NULL;

void onTrackbarSlide(int current_frame)
{
    current_frame = g_slider_position;
    cvSetCaptureProperty(video_capture,CV_CAP_PROP_POS_FRAMES,current_frame);
}

int main( int argc, char** argv )
{
    cvNamedWindow( "Video", CV_WINDOW_AUTOSIZE );
    video_capture = cvCreateFileCapture( "Crowdy.avi");
    int no_of_frames = (int) cvGetCaptureProperty(video_capture,CV_CAP_PROP_FRAME_COUNT);
    if( no_of_frames!= 0 ) 
    {
        cvCreateTrackbar("Slider","Video",&g_slider_position,no_of_frames,onTrackbarSlide);
    }

    IplImage* frame;

    while(1) 
    {
        frame = cvQueryFrame( video_capture );
        if( !frame ) break;
        cvShowImage( "Video", frame );
        cvSetTrackbarPos("Slider","Video",++g_slider_position);
        char c = cvWaitKey(33);
        if( c == 27 ) break;
    }
    cvReleaseCapture( &video_capture );
    cvDestroyWindow( "Video" );

    return(0);
}
镜花水月 2024-10-24 21:23:05

您在代码中将 g_slider_position 递增两次,因此它将超出其限制(在 cvCreateTrackbar 中设置为 frames)。这可能会导致您的图片冻结。

要修复此问题,请将其更改

    g_slider_position++;
    cvSetTrackbarPos(
        "Position", 
        "The Tom 'n Jerry Show",
        ++g_slider_position
        );

    cvSetTrackbarPos(
        "Position", 
        "The Tom 'n Jerry Show",
        ++g_slider_position
        );

“会计”以编辑代码,我将检查 OpenCV 是否正确读取文件中的帧数。请参阅学习 OpenCV 的第 2 章示例 2.3,了解从 AVI 中检索帧数的一般方法(如果您正在使用该方法)。

在上面的代码中,如果帧数为 0,则不会创建轨迹栏,但代码仍会进入尝试更新轨迹栏位置的循环(如果找到帧)。我会用这个代替:

if (frames != 0)
{
    cvCreateTrackbar(
        "Position",
        "The Tom 'n Jerry Show",
        &g_slider_position,
        frames,
        onTrackbarSlide
        );
} 
else
{
    exit(1);
}

You are incrementing g_slider_position twice in the code, so it will increment beyond its limit (set in cvCreateTrackbar as frames). This is likely causing your picture to freeze.

To fix, change this

    g_slider_position++;
    cvSetTrackbarPos(
        "Position", 
        "The Tom 'n Jerry Show",
        ++g_slider_position
        );

to

    cvSetTrackbarPos(
        "Position", 
        "The Tom 'n Jerry Show",
        ++g_slider_position
        );

Accounting for the edited code, I would check that OpenCV is properly reading the number of frames from your file. Look at Learning OpenCV's Chapter 2, example 2.3 for a method of generically retrieving the number of frames from your AVI (if that is what you are using).

In your code above, if the number of frames is 0, the trackbar is not created but the code still enters a loop that attempts to update the trackbar position (if it finds a frame). I would use this instead:

if (frames != 0)
{
    cvCreateTrackbar(
        "Position",
        "The Tom 'n Jerry Show",
        &g_slider_position,
        frames,
        onTrackbarSlide
        );
} 
else
{
    exit(1);
}
往日 2024-10-24 21:23:05

这对我来说似乎有点复杂。我使用 cvGetCaptureProperty(g_capture, CV_CAP_PROP_POS_FRAMES) 调用来检索当前帧并使用它来更新滑块。

然后回调函数仅用于更改 g_capture 中的位置。

所以回调是:

//Call back for slider bar
void onTrackbarSlide(int pos) {
    cvSetCaptureProperty(g_capture, CV_CAP_PROP_POS_FRAMES, pos);
}

循环是:

IplImage* frame; //Frame grabbed from video
while(1) {
    frame = cvQueryFrame( g_capture );
    if (!frame ) break;
    cvShowImage( "Example2", frame );

    g_frame_count = (int) cvGetCaptureProperty(g_capture, CV_CAP_PROP_POS_FRAMES);

    cvSetTrackbarPos("Position","Example2", g_frame_count);

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

其中 g_ 变量是全局变量。

This seems a bit complicated to me. I used the cvGetCaptureProperty(g_capture, CV_CAP_PROP_POS_FRAMES) call to retrieve the current frame and used this to update the slider.

The callback function is then used just to change the position within g_capture.

So the call back is:

//Call back for slider bar
void onTrackbarSlide(int pos) {
    cvSetCaptureProperty(g_capture, CV_CAP_PROP_POS_FRAMES, pos);
}

And the loop is:

IplImage* frame; //Frame grabbed from video
while(1) {
    frame = cvQueryFrame( g_capture );
    if (!frame ) break;
    cvShowImage( "Example2", frame );

    g_frame_count = (int) cvGetCaptureProperty(g_capture, CV_CAP_PROP_POS_FRAMES);

    cvSetTrackbarPos("Position","Example2", g_frame_count);

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

Where the g_ variables are global.

凉薄对峙 2024-10-24 21:23:05

您可以尝试下面的解决方案。

将其更改

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

void onTrackbarSlide( int pos )
{
    if( pos > g_slider_position + 1 )
    cvSetCaptureProperty( 
        g_capture, 
        CV_CAP_PROP_POS_FRAMES, 
        pos);
}

并将其更改

cvSetTrackbarPos(
            "Position", 
            "The Tom 'n Jerry Show",
            ++g_slider_position
            );

cvSetTrackbarPos(
            "Position", 
            "The Tom 'n Jerry Show",
            g_slider_position + 1
            );

You can try the solution below.

change this

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

to

void onTrackbarSlide( int pos )
{
    if( pos > g_slider_position + 1 )
    cvSetCaptureProperty( 
        g_capture, 
        CV_CAP_PROP_POS_FRAMES, 
        pos);
}

and also change this

cvSetTrackbarPos(
            "Position", 
            "The Tom 'n Jerry Show",
            ++g_slider_position
            );

to

cvSetTrackbarPos(
            "Position", 
            "The Tom 'n Jerry Show",
            g_slider_position + 1
            );
遥远的绿洲 2024-10-24 21:23:05

您好,我有类似的代码,我执行了以下操作:

void onTrackbarSlide(int pos)
{
if(pos > g_lastPosition+1 || pos < g_lastPosition)
cvSetCaptureProperty(g_capture,CV_CAP_PROP_POS_FRAMES,pos);
g_lastPosition = pos;
}

......................

while(1)
{
frame = cvQueryFrame( g_capture );
if( !frame ) break;
cvShowImage( "Example3", frame );
cvSetTrackbarPos("Position", "Example3", g_slider_position+1);
char c = cvWaitKey(33);
if( c == 27 ) break;
}

所以您可以将滑动条抓取到任何方向,我希望这可以有所帮助

Hi I have simlar code and I did the following:

void onTrackbarSlide(int pos)
{
if(pos > g_lastPosition+1 || pos < g_lastPosition)
cvSetCaptureProperty(g_capture,CV_CAP_PROP_POS_FRAMES,pos);
g_lastPosition = pos;
}

.............

while(1)
{
frame = cvQueryFrame( g_capture );
if( !frame ) break;
cvShowImage( "Example3", frame );
cvSetTrackbarPos("Position", "Example3", g_slider_position+1);
char c = cvWaitKey(33);
if( c == 27 ) break;
}

So you can grab the slide bar to any direction , I hope this can help

怂人 2024-10-24 21:23:05

好吧我终于解决了更新滑块的问题
如果您想移动滑块,视频也会更新
现在不存在图片冻结的问题

#include "stdafx.h"

#include<cv.h>
#include<cxcore.h>
#include<highgui.h>

int g_slider_position = 0;
CvCapture* g_capture = NULL;
int count=0;              //initiate a global counter



void onTrackbarSlide( int pos )
{// if you are moving the slider for more than two frames then this loop will initiate      to
 // to update the video
    if(pos>count+2 || pos<count-2){
    cvSetCaptureProperty( 
        g_capture, 
        CV_CAP_PROP_POS_FRAMES, 
        pos);}
    count=pos;
}
int main(int argc, _TCHAR* argv[])
{
    //int count=0;
    cvNamedWindow("Example3",CV_WINDOW_AUTOSIZE);
    g_capture=cvCreateFileCapture("video.avi");
    int frames = (int) cvGetCaptureProperty(
        g_capture,
        CV_CAP_PROP_FRAME_COUNT
        );
    if(frames!= 0) {
        cvCreateTrackbar(
            "Position",
            "Example3",
            &g_slider_position,
            frames,
            onTrackbarSlide
            );
    }
    IplImage* frame;
    while (1)
    {
        count++;  // the counter will move along with the frame
        frame = cvQueryFrame( g_capture );
        if (!frame) break;
        cvShowImage ("Example3", frame);
        cvSetTrackbarPos("Position", "Example3", g_slider_position+1);
        char c = cvWaitKey(33);
        if(c==27) break;
    }

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

了,现在我所做的是创建了一个全局计数器,

当我们使用鼠标滑块到不同位置时,它将与帧一起更新,然后在 onTrackbarSlider 例程中使用 if 循环将启动并将视频设置到新位置

OK I finally solved this problem of updating the slider
and also if you want to move the slider the video will update
there is no problem of picture freezing now

#include "stdafx.h"

#include<cv.h>
#include<cxcore.h>
#include<highgui.h>

int g_slider_position = 0;
CvCapture* g_capture = NULL;
int count=0;              //initiate a global counter



void onTrackbarSlide( int pos )
{// if you are moving the slider for more than two frames then this loop will initiate      to
 // to update the video
    if(pos>count+2 || pos<count-2){
    cvSetCaptureProperty( 
        g_capture, 
        CV_CAP_PROP_POS_FRAMES, 
        pos);}
    count=pos;
}
int main(int argc, _TCHAR* argv[])
{
    //int count=0;
    cvNamedWindow("Example3",CV_WINDOW_AUTOSIZE);
    g_capture=cvCreateFileCapture("video.avi");
    int frames = (int) cvGetCaptureProperty(
        g_capture,
        CV_CAP_PROP_FRAME_COUNT
        );
    if(frames!= 0) {
        cvCreateTrackbar(
            "Position",
            "Example3",
            &g_slider_position,
            frames,
            onTrackbarSlide
            );
    }
    IplImage* frame;
    while (1)
    {
        count++;  // the counter will move along with the frame
        frame = cvQueryFrame( g_capture );
        if (!frame) break;
        cvShowImage ("Example3", frame);
        cvSetTrackbarPos("Position", "Example3", g_slider_position+1);
        char c = cvWaitKey(33);
        if(c==27) break;
    }

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

ok now what i have done is that i have created a global counter which will be updated alongside with the frames

now when we use the slider with the mouse to a different position then in onTrackbarSlider routine the if loop will be initiated and it will set the video to the new position

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文