一、前言
对视频进行处理时,为了达到实时处理的效果,可以不必处理每一帧,以下为间隔几帧处理视频,并使用Linux的pthread多线程机制将获取下一帧与处理当前帧异步进行的一个例子
二、代码
//main.c
#include <opencv2/highgui/highgui_c.h>
#include <opencv2/core/core_c.h>
#include <opencv2/imgproc/imgproc_c.h>
#include <stdio.h>
#include <pthread.h>
static IplImage *in;
static IplImage *det;
static IplImage *disp;
static CvCapture *cap;
IplImage* get_frame_from_video(CvCapture *cap , int frame_skip);
void *fetch_in_thread(void *ptr);
void *process_in_thread(void *ptr);
int main()
{
cap = cvCaptureFromFile("../../video2.mp4");
if(!cap) error("Couldn't connect to video.\n");
pthread_t fetch_thread;
pthread_t process_thread;
fetch_in_thread(0);
det = in;
cvNamedWindow("Demo" , 1);
while(1){
if(pthread_create(&fetch_thread, 0, fetch_in_thread, 0)) error("Thread creation failed"); //创建线程获取下一帧图像
if(pthread_create(&process_thread, 0, process_in_thread, 0)) error("Thread creation failed"); //创建线程处理当前帧
pthread_join(fetch_thread, 0);
pthread_join(process_thread, 0);
cvWaitKey(1);
cvShowImage("Demo" , disp );
cvReleaseImage(&disp);
det = in;
}
cvreleasecapture(&cap);
return 0;
}
IplImage* get_frame_from_video(CvCapture *cap, int frame_skip) //间隔frame_hop-1 帧从视频结构读取视频帧
{
IplImage* _src;
static unsigned int counter = 0;
while (counter++ %(frame_skip+1) != 1){
_src = cvQueryFrame(cap);
if (!_src){
return NULL;
}
}
_src = cvQueryFrame(cap);
if (!_src){
return NULL;
}
IplImage *out = cvCloneImage(_src);
return out;
}
void *fetch_in_thread(void *ptr) //获取帧
{
in = get_frame_from_video(cap , 2); //
if(in == NULL){
error("no frame readed!");
}
}
void *process_in_thread(void *ptr) //处理帧
{
IplImage *dst_gray = cvCreateImage(cvGetSize(det),det->depth,1);
cvCvtColor(det,dst_gray,CV_BGR2GRAY); //得到灰度图
cvReleaseImage(&det);
disp = dst_gray;
}
三、运行在当前目录下使用gcc -o main main.c `pkg-config --cflags --libs opencv` -lpthread 编译链接生成可执行文件