我已经选择了“学习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;
}
知道如何让滑块和视频按预期工作吗?
答案 0 :(得分:6)
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);
}
答案 1 :(得分:5)
您在代码中递增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);
}
答案 2 :(得分:3)
这对我来说似乎有点复杂。我使用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_
变量是全局的。
答案 3 :(得分:1)
您可以尝试以下解决方案。
更改此
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
);
答案 4 :(得分:1)
您好我有类似的代码,我做了以下内容:
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;
}
所以你可以把滑杆拉到任何方向,我希望这可以帮助
答案 5 :(得分:1)
好的,我终于解决了更新滑块的问题 如果你想移动滑块,视频也会更新 现在没有图片冻结的问题
#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循环并将视频设置为新位置