OpenCV: буферизация IplImage * для разделения между потоками - PullRequest
0 голосов
/ 19 марта 2012

Я пытался заставить кольцевой буфер работать в течение нескольких дней, и по какой-то причине он просто не играл в мяч.Я пишу программу на 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);

Я очень застрял, перепробовал все, что мог придумать.Без сомнения, это в конечном итоге станет чем-то очевидным (я ненавижу указатели).Любая помощь будет принята с благодарностью.

1 Ответ

0 голосов
/ 19 марта 2012

Я собираюсь сделать предположение здесь и предположить, что вы пытаетесь построить очередь 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 (). Единственным исключением из всего этого является frbuff.update_flag, который изменяется как от buf_get (), так и от buf_put (). Если buf_get () и buf_put () вызываются из разных потоков, вы можете быть уверены, что update_flag будет содержать неправильные данные.

...