大三下进实验室跟老师,老师做的是图形学方向的,扑哧扑哧的给了我们一些项目相关的资料,于是就啃起了《学习Opencv》这本书,主要是基于C的,不过在看的过程中有问题时搜索中发现了很多是基于C++的opencv2的解决方法,淘了一下发现《opencv2 cookbook》这本,准备啃完c的后来啃,总之加油吧
====================================================================================================================================
一开始看到这题的时候好像觉得挺简单,不过做的时候还是出了点小问题,回到正题吧,opencv里面提供了滑动条(TrackBar)的实现,通俗地讲其实就是大家看视频时下面的条,不过要拖动它时视频的内容跟着改变还需要自己去实现,根据书中中滑动条的创建函数为
int cvCreateTrackbar(
const char* trackbar_name,
const char* window_name,
int* value,
int count,
CvTrackbarCallback on_change);
第一个参数trackbar_name指的是这个滑动条的名字,第二个参数window_name指的是滑动条所在窗口的名字,第三个参数value是一个指向一个整型数的指针,当滑动条被拖动时会将滑动条所在的位置传递给该整形数,而一开始创建滑动条时其值便是滑动条的初始位置,第四个参数count则是滑动条所能表示的最大值,第五个参数on_change则是滑动条被拖动时所被调用的回调函数,这个参数可以被设置为NULL,这个时候滑动条就成了摆设,大家可以看视频的时候无聊在那里拖来拖去消磨时间(怎么感觉越玩越无聊=_=)
而这次我们要实现的是利用滑动条来控制视频的暂停与播放,因为opencv并没有提供按钮(Button)的实现,因此我们用只有两个位置的滑动条(即count设置为1,滑动条的位置除了0就是1)来实现类似开关的功能(0/1控制开关),在这里我们将初始值设置为0,当滑动条在1时暂停,在0时播放,因此我们的创建函数为:
int bar_postion = 0;
cvCreateTrackbar("Button","B",&bar_position,1,change);
接着我们来看一下回调函数的实现,课本上的定义为 void (*callback) (int position),滑动条被拖动后会将拖动后当前的位置传递给position,即函数里面我们可以用position来判断0/1,为了能在主体中实现播放暂停的功能,我们用一个全局布尔变量isStop来标志是否停止,而这个函数的作用主要是用来设置这个标志:
void change( int position)
{
if(position == 1)
{
istop = true;
}
else
if(position == 0)
{
istop = false;
}
}
视频的处理主要用的是CvCapture和cvQueryFrame结合来实现所以最后面整个代码的实现为:
#include "highgui.h"
#include "cv.h"
#include
using namespace std;
using namespace cv;
char g_wait;
bool istop = false;
int exit_sign = 0;
void change( int position)
{
if(position == 1)
{
istop = true;
}
else
if(position == 0)
{
istop = false;
}
}
int main()
{
CvCapture *b = cvCreateFileCapture("G:\\sing.AVI");
IplImage *c ;
cvNamedWindow("B");
cvCreateTrackbar("Button","B",0,1,NULL);
while(1)
{
while(!istop) //播放部分
{
c = cvQueryFrame(b);
if(!c)
{
exit_sign = 1;
break;
}
cvShowImage("B",c);
g_wait = cvWaitKey(100); //控制视频播放的速度
if(g_wait == 27)
{
exit_sign = 1;
break;
}
}
if(exit_sign == 1)
{
break;
}
while(istop) //暂停部分
{
cvShowImage("B",c);
g_wait =cvWaitKey(100); //控制视频播放的速度
if(g_wait == 27)
{
exit_sign = 1 ;
break;
}
}
}
cvReleaseCapture(&b);
cvDestroyWindow("B");
}
不过这个实现还有比较简单的方法,就是不用回调函数来设置,因为位置就只有0/1两个值,我们可以直接利用它来控制暂停和播放:
#include "highgui.h"
#include "cv.h"
#include
using namespace std;
using namespace cv;
char g_wait;
int istop = 0;
int exit_sign = 0;
int main()
{
CvCapture *b = cvCreateFileCapture("G:\\sing.AVI");
IplImage *c ;
cvNamedWindow("B");
cvCreateTrackbar("Button","B",&istop,1,NULL);
while(1)
{
while(!istop) //播放部分
{
c = cvQueryFrame(b);
if(!c)
{
exit_sign = 1;
break;
}
cvShowImage("B",c);
g_wait = cvWaitKey(100); //控制视频播放的速度
if(g_wait == 27)
{
exit_sign = 1;
break;
}
}
if(exit_sign == 1)
{
break;
}
while(istop) //暂停部分
{
cvShowImage("B",c);
g_wait =cvWaitKey(100); //控制视频播放的速度
if(g_wait == 27)
{
exit_sign = 1 ;
break;
}
}
}
cvReleaseCapture(&b);
cvDestroyWindow("B");
}
最后面的实现的效果如图:(佳慧唱的非常好~)
不过最后面还有一点残留问题,就是在暂停部分时,一开始是只有cvShowImage,一直循环显示当前帧没有cvWaitkey,然后按退出键就崩了..希望有大神能解答一下~