簡體   English   中英

"16 位深度圖像損壞"

[英]16-bit depth image getting corrupted

我正在使用 realsense D435 並獲取 16 位深度數據並轉換為 opencv 16 位 Mat 並且我正在使用 c++ 編寫自定義隊列,我正在推送所有幀並且當我從隊列中彈出 16 位數據時已損壞。將幀推入隊列時,我將其保存到磁盤中,而同時從隊列中彈出幀時,我還將幀保存到磁盤中。因此,從那里我知道幀在彈出時已損壞。 我用 8 位數據嘗試過的同樣事情意味着在轉換為 opencv mat 時我轉換為 8 位 Mat 而不是 16 位 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。 所以在推動的同時,我還通過 imwrite 函數保存了這個 16 位深度的 Mat,那時我有正確的圖像。 在彈出這個 16 位 Mat 時,它被損壞了。

下面是推入隊列時的 png 圖像,我正在保存到磁盤,它是正確的,同時彈出填充 0 的完整黑色圖像即將到來在此處輸入圖像描述

請記住, rs2::frame<\/code>和cv::Mat<\/code>基本上都是管理實際數據的智能指針的薄包裝器。 當您使用

構造函數(或任何其他帶有指向數據的指針的 cv::Mat ctor)您告訴 OpenCV 您將管理數據,因此它不進行分配。 一旦 rs2::frame depth<\/code>的最后一個副本超出范圍,RealSense 庫就會釋放數據塊,而您無法控制它會發生什么。

您可以嘗試保留 RealSense rs2::frame<\/code>幀的副本,直到您完成處理,這會阻止 Realsense 庫釋放數據並且在內存和處理時間方面相對便宜。 您可以做的另一件事(以更多處理時間為代價)是使用cv::Mat::clone()<\/code>並讓 OpenCV 管理自己的數據副本,如下所示:

最后一點:您可能不應該直接使用rs2::frame<\/code>類,因為它是 RealSense 幀的基類。 而是將rs2::depth_frame<\/code>用於深度圖像,將rs2::video_frame<\/code>用於彩色或灰度圖像。 原因是使用基類使得無法使用rs2::video_frame::get_height()<\/code>和rs2::video_frame::get_width()<\/code>之類的功能。 繼承是這樣的:

class frame ...
class video_frame : public frame ...
class depth_frame : public video_frame ...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM