我几天来一直在努力尝试让循环缓冲区正常工作,但由于某种原因它无法正常工作。我正在用 C 编写程序,而不是 C++。
我正在尝试在一个线程中缓冲来自相机的图像,以便可以在另一个线程中读取和处理它(我知道如何使用 pthread_mutex_* 进行资源锁定)。到目前为止,我已将缓冲区图像管理到缓冲区中,但在检索它们时遇到问题。这是我的循环缓冲区实现:
#define BUFFER_SIZE 100
typedef struct
{
IplImage** queue[BUFFER_SIZE];
IplImage** in;
IplImage** out;
int num_frames;
int in_ctr;
int out_ctr;
int update_flag;
} frame_buffer;
static frame_buffer frbuff;
void buff_init()
{
frbuff.in = &frbuff.queue[0];
frbuff.out = &frbuff.queue[0];
frbuff.num_frames = 0;
frbuff.in_ctr = 0;
frbuff.out_ctr = 0;
frbuff.update_flag = 0;
}
int buff_size()
{
return frbuff.num_frames;
}
int buff_flag_check()
{
return frbuff.update_flag;
}
void buff_flag_set()
{
frbuff.update_flag = 1;
}
void buff_flag_clr()
{
frbuff.update_flag = 0;
}
IplImage** buff_get()
{
IplImage** nextfr;
if(frbuff.num_frames == 0)
{
return NULL;
}
nextfr = frbuff.out++;
if(++frbuff.out_ctr == BUFFER_SIZE)
{
frbuff.out = &frbuff.queue[0];
frbuff.out_ctr = 0;
}
--frbuff.num_frames;
buff_flag_clr();
return nextfr;
}
int buff_put(IplImage* nextfr)
{
if(++frbuff.num_frames > BUFFER_SIZE)
{
return 0;
}
frbuff.in++;
frbuff.in = nextfr;
if(++frbuff.in_ctr == BUFFER_SIZE)
{
frbuff.in = &frbuff.queue[0];
frbuff.in_ctr = 0;
}
buff_flag_set();
return 1;
}
我可以使用 buff_put() 很好,这似乎有效,因为我看到计数器增加了。当我 buff_get() 时,我也得到一些不为空的东西。当我尝试用它做任何事情时,问题就出现了:
IplImage **some_image;
some_image = buff_get();
cvShowImage("some_window_somewhere",some_image);
显然它对此不满意......
OpenCV Error: Bad flag (parameter or structure field) (Unrecognized or unsupported array type) in cvGetMat, file /home/fagg/src/OpenCV-2.3.1/modules/core/src/array.cpp, line 2482
terminate called after throwing an instance of 'cv::Exception'
what(): /home/fagg/src/OpenCV-2.3.1/modules/core/src/array.cpp:2482: error: (-206) Unrecognized or unsupported array type in function cvGetMat
我也尝试过这个(这会导致段错误):
cvShowImage("some_window_somewhere",*some_image);
我很困惑,已经尝试了我能想到的一切。毫无疑问,它最终会变得显而易见(我讨厌指针)。任何帮助将不胜感激。
最佳答案
我将在这里做出一个假设,假设您正在尝试构建一个 ImpImage* 队列。如果是这种情况,这一行:
IplImage** queue[BUFFER_SIZE];
应阅读:
IplImage* queue[BUFFER_SIZE];
这些行:
IplImage** buff_get()
{
IplImage** nextfr;
if(frbuff.num_frames == 0)
{
return NULL;
}
nextfr = frbuff.out++;
应阅读:
IplImage* buff_get()
{
IplImage* nextfr;
if(frbuff.num_frames == 0)
{
return NULL;
}
nextfr = *frbuff.out++;
这些行:
IplImage **some_image;
some_image = buff_get();
cvShowImage("some_window_somewhere",some_image);
应阅读:
IplImage *some_image;
some_image = buff_get();
cvShowImage("some_window_somewhere",some_image);
接下来我们有一个简单的错误。这一行:
frbuff.in = nextfr;
应阅读:
*frbuff.in = nextfr;
令我惊讶的是现代 C 编译器没有完全拒绝该代码。至少它必须发出警告。如果您使用 gcc,我建议您至少传递 -Wall -Wextra 作为您编写的所有新代码的最低限度。将代码转换为编译器在不发出警告的情况下接受的形式可能会很痛苦,但从长远来看,当您发现不这样做时会更加痛苦。
其次,你说你正在使用pthreads。如果 buf_get() 始终从同一线程调用,那么大多数代码都可以正常工作,buf_put() 也同样如此。如果从多个线程调用 buf_get() ,那么至少您的队列将被损坏, buf_put() 也是如此。所有这一切的一个异常(exception)是 frbuff.update_flag,它是从 buf_get() 和 buf_put() 更改而来的。如果从不同的线程调用 buf_get() 和 buf_put() ,您可以放心 update_flag 最终将包含错误的内容。
关于c - OpenCV:缓冲 IplImage* 以在 pthreads 之间共享,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9765536/