Openni2 читает записи (.oni) в неправильном порядке

У меня проблемы с чтением записи, которую я сделал, используя класс Recorder в openni2 с asus Xtion PRO LIVE. Проблема заключается в том, что после того, как каждые ~50 кадров считывается неправильный кадр из записи, это проверялось путем сохранения сгенерированного изображения (преобразованного в матрицу opencv) в виде изображения.png (с использованием функции opencv imwrite) с индексом. Ниже показан мой код, я также попробовал код, опубликованный в вопросе "OpenNI2: чтение в.oni Recording". Это также не работает. Видеопотоки, устройство, videoFrameRefs и контроллер воспроизведения все инициализируются в функции инициализации. Я могу опубликовать это, если это необходимо.

openni::VideoStream depthStream;
openni::VideoStream colorStream;
openni::Device      device;

openni::VideoFrameRef       m_depthFrame;
openni::VideoFrameRef       m_colorFrame;

openni::PlaybackControl *controler;

typedef struct _ImagePair {
    cv::Mat GrayscaleImage;
    cv::Mat DepthImage;
    cv::Mat RGBImage;
    float AverageDistance;
    std::string FileName;
    int index;
}ImagePair;

ImagePair SensorData::getNextRawImagePair(){
    ImagePair result;
    openni::Status rc;
    std::cout<<"Getting next raw image pair...";
    rc = controler->seek(depthStream, rawPairIndex);
    if(!correctStatus(rc,"Seek depth"))return result;

    openni::VideoStream** m_streams = new openni::VideoStream*[2];
    m_streams[0] = &depthStream;
    m_streams[1] = &colorStream;
    bool newDepth=false,newColor=false;

    while(!newDepth || !newColor){
        int changedIndex;
        openni::Status rc = openni::OpenNI::waitForAnyStream(m_streams, 2, &changedIndex);
        if (rc != openni::STATUS_OK)
        {
            printf("Wait failed\n");
            //return 1;
        }

        switch (changedIndex)
        {
            case 0:
                rc = depthStream.readFrame(&m_depthFrame);
                if(!correctStatus(rc,"Read depth")){
                    return result;
                }
                newDepth = true;
                break;
            case 1:
                rc = colorStream.readFrame(&m_colorFrame); 
                if(!correctStatus(rc,"Read color")){
                    return result;
                }
                newColor = true;
                break;
            default:
                printf("Error in wait\n");
        }
    }

    //convert rgb to bgr cv::matrix
    cv::Mat cv_image;
    const openni::RGB888Pixel* colorImageBuffer = (const openni::RGB888Pixel*)m_colorFrame.getData();
    cv_image.create(m_colorFrame.getHeight(), m_colorFrame.getWidth(), CV_8UC3);
    memcpy( cv_image.data, colorImageBuffer,3*m_colorFrame.getHeight()*m_colorFrame.getWidth()*sizeof(uint8_t) );

    //convert to BGR opencv color order
    cv::cvtColor(cv_image,cv_image,cv::COLOR_RGB2BGR);
    result.RGBImage = cv_image.clone(); 

    //convert to grayscale
    cv::cvtColor(cv_image,cv_image,cv::COLOR_BGR2GRAY);
    result.GrayscaleImage =cv_image.clone();

    //convert depth to cv::Mat INT16
    const openni::DepthPixel* depthImageBuffer = (const openni::DepthPixel*)m_depthFrame.getData();
    cv_image.create(m_depthFrame.getHeight(), m_depthFrame.getWidth(), CV_16UC1);
    memcpy( cv_image.data, depthImageBuffer,m_depthFrame.getHeight()*m_depthFrame.getWidth()*sizeof(INT16) );

    result.DepthImage = cv_image.clone();
    result.index = rawPairIndex;

    rawPairIndex++;

    std::cout<<"done"<<std::endl;
    return result;
}

Я также попробовал это без использования части waitForAnyStream, но это только ухудшило ситуацию. Файл, который я пытаюсь загрузить, превышает 1 ГБ, но я не уверен, что это проблема. Поведение кажется случайным, потому что индексы неправильных изображений не всегда одинаковы.

ОБНОВЛЕНИЕ: я изменил функцию поиска, чтобы искать в потоке цвета вместо потока глубины. Я также обеспечил, чтобы каждый поток ожидался только один раз в функции waitForAnyStream, установив для соответствующей точки в m_streams значение null.

Я узнал, что можно найти фактический индекс кадра для каждого кадра (.getFrameIndex), поэтому я смог сравнить индексы. После получения 1000 изображений там было 18 неправильных цветных изображений, 17 из которых имели ошибку индекса 53, а 1 имела ошибку 46. Глубинные изображения имели почти постоянную ошибку индекса 9.

Второе, что я обнаружил, было то, что после добавления периода ожидания в 1 мс (также пробовал 10 мс, но результаты были такими же) перед функцией waitForAnyStream, возвращаемые индексы значительно менялись. Индексы больше не делают больших скачков, но цветные изображения имеют стандартное смещение 53, а изображения глубины имеют смещение 9.

Когда я изменяю функцию поиска для поиска в потоке глубины, тогда с задержкой цветовой поток имеет постоянную ошибку 46, а поток глубины имеет ошибку 1. Без задержки поток цвета имеет ошибку 45, а поток глубины не имеет ошибок со случайными всплесками ошибок 1.

Я также посмотрел на индексы, когда я не использую search и waitForAnyStream, а просто делаю это, как предлагается в качестве ответа в "OpenNI2: чтение в записи.oni". Это показывает, что когда файл читается простым вызовом m_readframe несколько раз, то первый цветной фрейм имеет индекс 59 вместо 0. После проверки выясняется, что фрейм 0 действительно существует и является более ранним фреймом, чем фрейм 59. Так что просто открываем файл и использование readframe не работает вообще. Однако ошибок индекса нет, как, например, когда я добавил сон в мою собственную реализацию.

ОБНОВЛЕНИЕ 2: Я пришел к выводу, что либо библиотека openni2 не работает должным образом, либо я установил ее неправильно. Это потому, что у меня также возникают проблемы с установкой Xtion с разрешением 640x480 для обоих потоков. Когда я делаю это, изображение глубины обновляется только один раз каждые ~100 секунд. Я написал быстрое решение для моей первоначальной проблемы, просто отфильтровывая кадры, чьи индексы неверны, и просто продолжая со следующим изображением.

Я все еще хотел бы знать, как это исправить, поэтому, если вы знаете, пожалуйста, скажите мне.

ОБНОВЛЕНИЕ 3: код, который я использую для установки частоты кадров и fps для записи:

//colorstream
openni::VideoMode color_videoMode  = m_colorStream.getVideoMode();
color_videoMode.setResolution(WIDTH,HEIGHT);
color_videoMode.setFps(30);
m_colorStream.setVideoMode(color_videoMode);

//depth stream
openni::VideoMode depth_videoMode  = m_depthStream.getVideoMode();
depth_videoMode.setResolution(WIDTH,HEIGHT);
depth_videoMode.setFps(30);
m_depthStream.setVideoMode(depth_videoMode);

Я забыл упомянуть, что я также проверил разрешение, запустив пример программы sampleviewer (я думаю, это было несколько месяцев назад) и изменив разрешение в файле конфигурации xml. Здесь цветные изображения будут отображаться нормально, но глубина изображения будет обновляться очень редко.

0 ответов

Другие вопросы по тегам