[英]16-bit depth image getting corrupted
I am using realsense D435 and taking 16-bit depth data and converting into opencv 16-bit Mat and i am having custom-queue written in c++ where i am pushing all my frames and when i am popping out from queue the 16-bit data got corrupted.while pushing frame into queue i am saving into disk and while popping frame from queue that time also i am saving frame into disk.so from there i get to know frame got corrupted while popping.我正在使用 realsense D435 并获取 16 位深度数据并转换为 opencv 16 位 Mat 并且我正在使用 c++ 编写自定义队列,我正在推送所有帧并且当我从队列中弹出 16 位数据时已损坏。将帧推入队列时,我将其保存到磁盘中,而同时从队列中弹出帧时,我还将帧保存到磁盘中。因此,从那里我知道帧在弹出时已损坏。 Same thing i tried with 8-bit data means while converting to opencv mat i converted to 8-bit Mat instead of 16-bit Mat and while popping 8-bit data.The data not get corrupted.
我用 8 位数据尝试过的同样事情意味着在转换为 opencv mat 时我转换为 8 位 Mat 而不是 16 位 Mat 并且在弹出 8 位数据时。数据不会损坏。
Code:代码:
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));
Custom_queue Code:自定义队列代码:
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;
}
So from above you can see that i am pushing fin_rgbd_img,fin_depth_image in queue.所以从上面你可以看到我正在将 fin_rgbd_img,fin_depth_image 推入队列。 fin_rgbd_img is 8bit 4 channel Mat and fin_depth_image is 16-bit Mat.
fin_rgbd_img 是 8 位 4 通道 Mat 而 fin_depth_image 是 16 位 Mat。 so while pushing i am saving also this 16-bit depth Mat by imwrite function that time i am having proper image.
所以在推动的同时,我还通过 imwrite 函数保存了这个 16 位深度的 Mat,那时我有正确的图像。 While popping out this 16-bit Mat got corrupted.
在弹出这个 16 位 Mat 时,它被损坏了。
Below is the png image while pushing into queue i am saving to disk and it's proper and while popping complete black image filled with 0 is coming下面是推入队列时的 png 图像,我正在保存到磁盘,它是正确的,同时弹出填充 0 的完整黑色图像即将到来
Remember that both rs2::frame<\/code> and
cv::Mat<\/code> are basically thin wrappers around smart pointers that manage the actual data.
请记住,
rs2::frame<\/code>和
cv::Mat<\/code>基本上都是管理实际数据的智能指针的薄包装器。
When you use the
当您使用
cv::Mat::Mat (cv::Size size, int type, void* data, size_t step = AUTO_STEP)<\/code>
constructor (or any other cv::Mat ctor that takes a pointer to the data) you are telling OpenCV that you will manage the data, so it does no allocation.构造函数(或任何其他带有指向数据的指针的 cv::Mat ctor)您告诉 OpenCV 您将管理数据,因此它不进行分配。 Once the last copy of the rs2::frame
depth<\/code> goes out of scope, the RealSense library frees the data block, and you have no control over what happens to it.
一旦 rs2::frame
depth<\/code>的最后一个副本超出范围,RealSense 库就会释放数据块,而您无法控制它会发生什么。
You might try keeping copies of the RealSense
rs2::frame<\/code> frames around until you are done processing, which prevents the Realsense library from freeing the data and is relatively cheap in terms of memory and processing time.
您可以尝试保留 RealSense
rs2::frame<\/code>帧的副本,直到您完成处理,这会阻止 Realsense 库释放数据并且在内存和处理时间方面相对便宜。
The other thing you can do (at the cost of more processing time) is use
cv::Mat::clone()<\/code> and let OpenCV manage its own copy of the data, like this:
您可以做的另一件事(以更多处理时间为代价)是使用
cv::Mat::clone()<\/code>并让 OpenCV 管理自己的数据副本,如下所示:
cv::Mat fin_depth_image = cv::Mat(cv::Size(WIDTH,HEIGHT), CV_16UC1, (void*)depth.get_data()).clone();<\/code>
One final note: you probably should not use the
rs2::frame<\/code> class directly, since it is the base class for RealSense frames.
最后一点:您可能不应该直接使用
rs2::frame<\/code>类,因为它是 RealSense 帧的基类。
Instead use
rs2::depth_frame<\/code> for depth images, and
rs2::video_frame<\/code> for color or grayscale images.
而是将
rs2::depth_frame<\/code>用于深度图像,将
rs2::video_frame<\/code>用于彩色或灰度图像。
The reason is that using the base class makes it impossible to use features like
rs2::video_frame::get_height()<\/code> &
rs2::video_frame::get_width()<\/code> .
原因是使用基类使得无法使用
rs2::video_frame::get_height()<\/code>和
rs2::video_frame::get_width()<\/code>之类的功能。
The inheritance goes like this:
继承是这样的:
class frame ...
class video_frame : public frame ...
class depth_frame : public video_frame ...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.