OpenCV - заставляет ползунок обновлять свою позицию во время воспроизведения видео - PullRequest
11 голосов
/ 19 февраля 2011

Я выбрал «Обучение OpenCV» и пробовал некоторые примеры кода / упражнения.В этом фрагменте кода я хочу, чтобы ползунок обновлял свою позицию при каждом изменении видеокадра, но по какой-то причине он не будет работать (изображение зависает со следующим кодом):идея, как заставить слайдер и видео работать как задумано?

Ответы [ 6 ]

6 голосов
/ 02 марта 2012
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);
}
5 голосов
/ 21 февраля 2011

Вы увеличиваете 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 считывает количество кадров из вашего файла. Посмотрите в главе 2 «Изучения» OpenCV, пример 2.3, метод для общего получения количества кадров из вашего AVI (если это то, что вы используете).

В приведенном выше коде, если количество кадров равно 0, трекбар не создается, но код все еще входит в цикл, который пытается обновить позицию трекбара (если он находит кадр). Я бы использовал это вместо:

if (frames != 0)
{
    cvCreateTrackbar(
        "Position",
        "The Tom 'n Jerry Show",
        &g_slider_position,
        frames,
        onTrackbarSlide
        );
} 
else
{
    exit(1);
}
3 голосов
/ 05 декабря 2012

Это кажется мне немного сложным.Я использовал вызов 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_ являются глобальными.

1 голос
/ 06 февраля 2012

ОК. Я, наконец, решил эту проблему обновления ползунка, а также, если вы хотите переместить ползунок, видео будет обновлено, теперь нет проблем с зависанием изображения

#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, и он установит видеона новую должность

1 голос
/ 31 декабря 2011

Привет, у меня есть код Симлара, и я сделал следующее:

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

Так что вы можете захватить ползунок в любом направлении, я надеюсь, что это может помочь

1 голос
/ 11 сентября 2011

Вы можете попробовать решение ниже.

изменить это

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
            );
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...