Создание мата OpenCv из Gstreamer создает серое изображение, но я хочу цвет - PullRequest
0 голосов
/ 13 июня 2019

Я использую gstreamer для доступа к изображениям с веб-камеры. Я использую appsrc, чтобы получить доступ к этим изображениям, и затем я хочу иметь возможность обрабатывать их с openCv. Итак, сначала мне нужно загрузить их в объект Mat. Однако я могу сделать это только в оттенках серого. Если я пытаюсь прочитать несколько каналов, я получаю исключение «нарушение прав чтения».

Код, который я использую для создания мата, выглядит следующим образом:

GstSample* sample;
    GstBuffer* buffer;
    GstMapInfo map;

    g_signal_emit_by_name(sink, "pull-sample", &sample);
    g_print("Check frame");
    if (sample != NULL) {

        buffer = gst_sample_get_buffer(sample);
        if (gst_buffer_map(buffer, &map, GST_MAP_READ))
        {


            Mat frame(Size(width, height), CV_8UC3, map.data, cv::Mat::AUTO_STEP);
            imwrite("elephant.jpg", frame);


        }
        g_print("Found frame");
        return GST_FLOW_OK;
    }
    return GST_FLOW_ERROR;

Когда я раньше использовал файл-приемник для записи в файл, изображения были цветными.

Я использую следующие фильтры в моем коде:

filtercaps = gst_caps_new_simple("image/jpeg", "format", G_TYPE_STRING, "RGB", "width", G_TYPE_INT, width,
        "height", G_TYPE_INT,
        height, "framerate", GST_TYPE_FRACTION, 30,
        1, NULL);

Я пытался установить этот фильтр сразу после источника и непосредственно перед приемником, но ни одна из них не решила проблему. У меня также есть JPEG-декодер в моем конвейере.

Я действительно понятия не имею, как это исправить. Любая помощь или советы с благодарностью!

1 Ответ

0 голосов
/ 15 июня 2019

Я понял это самостоятельно.Проблема заключалась в том, что выход конвейера не был в RGB.Я пытался реализовать capsfilter для решения этой проблемы, но это не сработало (я не понимаю, почему).

Я решил это, просто преобразовав выходные данные конвейера.В здесь вы можете видеть, что предпочтительным выходом является I420 (формат цвета YUV).Я использовал код, предложенный в этом посте , чтобы преобразовать BGRA.Мой окончательный код выглядел так:

GstSample* sample;
    GstBuffer* buffer;
    GstMapInfo map;
    GstMemory *mem;
    mem = gst_allocator_alloc(NULL, 1000000, NULL);
    gst_memory_map(mem, &map, GST_MAP_WRITE);
    g_signal_emit_by_name(sink, "pull-sample", &sample);
    g_print("Check frame");
    if (sample != NULL) {

        buffer = gst_sample_get_buffer(sample);
        if (gst_buffer_map(buffer, &map, GST_MAP_READ)) 
        {

            g_print("size: %d", map.size);
            Mat frameYUV(height+height/2, width, CV_8UC1 , map.data, cv::Mat::AUTO_STEP);
            cv::Mat frameRGB(height, width, CV_8UC4);
            cv::cvtColor(frameYUV, frameRGB, CV_YUV2BGRA_I420);
            imwrite("elephant.jpg", frameRGB);


        }
        g_print("Found frame");
        return GST_FLOW_OK;
    }
    gst_memory_unmap(mem, &map);
    return GST_FLOW_ERROR;
...