16-битная глубина изображения становится поврежденной - PullRequest
0 голосов
/ 17 марта 2020

Я использую realsense D435 и беру 16-битные данные глубины и преобразую в opencv 16-битный Mat, и у меня есть пользовательская очередь, написанная на c ++, где я выталкиваю все свои кадры, а когда выхожу из очереди, 16 -битные данные были повреждены. При вставке кадра в очередь я сохраняю на диск, и в то же время, извлекая кадр из очереди, я также сохраняю кадр на диск. Поэтому оттуда я узнаю, что кадр был поврежден во время записи. То же самое я попробовал с 8-битными средствами данных при преобразовании в opencv mat, я конвертировал в 8-битный Mat вместо 16-bit Mat и при извлечении 8-битных данных. Данные не повреждены.

Код:

rs2::frameset data = pipe.wait_for_frames(); 
data = align.process(data);         
rs2::frame depth = data.get_depth_frame();
rs2::frame color = data.get_color_frame();

cv::Mat depth_image;        
cv::Mat fin_depth_image(cv::Size(WIDTH,HEIGHT), CV_16UC1, (void*)depth.get_data(), cv::Mat::AUTO_STEP);
cv::Mat color_image(cv::Size(WIDTH,HEIGHT), CV_8UC3, (void*)color.get_data(), cv::Mat::AUTO_STEP);
fin_depth_image.convertTo(depth_image,CV_8UC1);

cv::split(color_image,channels);        
channels.push_back(depth_image);
cv::merge(channels,fin_rgbd_img);           

camera_queue.push(std::make_pair(fin_rgbd_img,fin_depth_image));

Код пользовательской очереди:

inline void push(const T& elem) {
    {
        std::unique_lock<std::mutex> lock(_mutex);

        // wait for timeout while the queue is full
        _not_full.wait_for(lock,std::chrono::milliseconds(5));

        // If the queue is full, remove the old item and add the new item
        if (_queue.size() >= _capacity)
        {
            _queue.pop();
        }
        _queue.push(elem);
    }
    _not_empty.notify_all();
}

inline bool pop(T &elem) {
    bool status = false;
    {
        std::unique_lock<std::mutex> lock(_mutex);

        // wait for timeout while the queue is empty
        _not_empty.wait_for(lock,std::chrono::milliseconds(5));

        if (_queue.size() > 0)
        {
            elem = _queue.front();
            _queue.pop();
            status = true;
        }
    }
    _not_full.notify_one();
    return status;
}

Итак, сверху видно, что я помещаю в очередь fin_rgbd_img, fin_depth_image. fin_rgbd_img - 8-битный 4-канальный Mat, а fin_depth_image - 16-битный Mat. поэтому, нажимая, я сохраняю также этот 16-битный мат глубиной с помощью функции imwrite, в этот раз у меня правильное изображение. Во время выскакивания этот 16-битный мат был поврежден.

Ниже приведено изображение png, когда я помещаю в очередь запись, которую я сохраняю на диск, и это правильно, и при извлечении полного черного изображения, заполненного 0, идет enter image description here

...