我正在尝试提高我正在使用OpenCV在嵌入式Linux计算机上运行的实时计算机视觉程序的捕获性能。我想使用多个线程和共享内存缓冲区来分离(1)捕获视频帧和(2)处理它们的任务(我相信“生产者/消费者问题”)。我已经阅读了pthreads,互斥变量和条件变量,但不明白它们如何与select()
函数一起使用。
现在,使用Video4Linux2 Video Capture Example改编的代码捕获视频帧,该代码使用select()
。据我了解,select()
阻止程序,直到网络摄像头可以获得数据,这可能很慢并且浪费时间。如果可能的话,我想使用那些浪费的CPU周期来处理图像处理。 (当然这意味着处理总是必须在一帧“陈旧”的图像上完成,但是以30 fps的速度实际上它将是实时的。)
我发现有些example code使用pthread_mutex_lock()
和pthread_mutex_control()
来保护共享数据,但是似乎这些仍会阻止“处理”线程在等待时运行通过select()
获取图片数据。更具体地说,这里有一些伪代码来说明我的担忧。 (注意:我意识到这些线程需要包含循环和其他检查,如上面链接的示例才能真正正常工作。)
void* capture()
{
pthread_mutex_lock(&mutex); // protect shared data
pthread_cond_wait(&space_avail,&mutex); // make sure the buffer has room
/// capture code... ///
select(fd+1, &fds, NULL, NULL, &tv); // waiting for data...
// Want to be processing frames
// during select, but won't the
// processing thread be blocked
// by the mutex lock?
// store image to the frame buffer
/// more capture code... ///
pthread_cond_signal(&data_avail);
pthread_mutex_unlock(&mutex);
}
void* process()
pthread_mutex_lock(&mutex);
pthread_cond_wait(&data_avail);
// access the most recently stored frame from the buffer
/// Do image processing ///
pthread_mutex_signal(&space_avail);
pthread_mutex_unlock(&mutex);
}
答案 0 :(得分:0)
如果我已正确理解您的问题,您希望避免在程序等待选择时浪费的繁忙等待周期,并将其用于图像处理。如果我错了,请纠正我。
根据我的经验,执行此操作的一种简单方法是为select API指定一个小超时。 Select API将等待此时间。如果在此持续时间内它从网络摄像头接收到任何数据,则select的返回值将不为零。如果在该持续时间内没有看到任何有趣的内容,则返回值将为0.
所以您的伪代码可以修改为以下内容:
void* capture(){
while(true){//iterate how many times you feel it is valid to
if (select(fd+1, &fds, NULL, NULL, &tv)!=0){
//We have found something here.take data from the webcam.
//break from the loop.
break;
}else{
//timeout occurred. process the image.
}
}
//process the data from the webcam
}
如果这可以解决您的问题,请告诉我。有关Select API的更多信息,请访问: http://linux.die.net/man/2/select