c语言 - OpenCV:缓冲 IplImage* 以在 pthreads 之间共享



几天来,我一直在努力让循环缓冲区工作,但由于某种原因,它无法发挥作用。我正在用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最终会包含错误的内容。

相关内容

  • 没有找到相关文章