几天来,我一直在努力让循环缓冲区工作,但由于某种原因,它无法发挥作用。我正在用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()时,我也会得到一些不为null的东西。当我试图用它做任何事情时,问题就来了:
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);
接下来我们有一个简单的bug。此行:
frbuff.in = nextfr;
应为:
*frbuff.in = nextfr;
我很惊讶现代C编译器没有直接拒绝代码。至少它必须发出警告。如果您使用的是gcc,我建议将-Wall-Wextra作为您编写的所有新代码的最低要求。将代码转换成编译器在没有警告的情况下接受的形式可能会很痛苦,但从长远来看,因为你发现不这样做会更痛苦。
其次,您说您正在使用pthreads。如果总是从同一个线程调用buf_get(),那么大多数代码都是可以的,buf_put()也是如此。如果从多个线程调用buf_get(),那么至少您的队列会被破坏,buf_put()也是如此。这一切的一个例外是frbuff.update_flag,它由buf_get()和buf_put()更改而来。如果从不同的线程调用buf_get()和buf_put(),您可以确信update_flag最终会包含错误的内容。