从原始缓冲区数据创建 Mat 图像

Posted

技术标签:

【中文标题】从原始缓冲区数据创建 Mat 图像【英文标题】:Mat Image creation from raw buffer data 【发布时间】:2016-08-09 15:22:38 【问题描述】:

我有一个图像的 float x、float y、float z 值。我想通过复制 z 值来构造一个 16 位 png 深度图像。结果我得到的图像有一些无效点。下面是我的代码。

 uint16_t* depthValues = new uint16_t[size];
auto sampleVector(DepthPoints);
for (unsigned int i = 0; i < sampleVector.size(); i++)
    
        depthValues[i] = (sampleVector.at(i).z) * 65536;
    
  Mat newDepthImage = cv::Mat(var.height, var.width, CV_16UC1,depthValues);
imwrite(Location, CImage);

谁能告诉我,如果我可以将浮点值复制到一个无符号字符数组中来创建图像? 这就是我的图像有无效点的原因吗?

【问题讨论】:

“结果有一些无效点”究竟是什么意思? z 值的范围是[0 - 1] 吗?如果 z 的值为 &gt;1,则大于 1 的所有值都是 65535。 图像的某些区域很暗。我不太确定浮点数据是否可以复制到uint16_t* 。这就是我们创建深度图像的方法吗? z 值的范围是多少?也许您只需要depthValues[i] = static_cast&lt;uint16_t&gt;(sampleVector.at(i).z); BTW,x,y,z 指的是 R,G,B? x,y,z 指的是 (x,y,z) 坐标。数据来自点云。 感谢所有帮助。有效。 :) :) 【参考方案1】:
auto sampleVector(DepthPoints);
const int size = sampleVector.size();
float* depthValues = new float[size];
for (unsigned int i = 0; i < sampleVector.size(); i++)
    
      depthValues[i] = (sampleVector.at(i).z);
    
Mat depthImageOne, depthImageTwo;
Mat depthImageNew = cv::Mat(var.height, var.width, CV_32FC1,depthValues);
normalize(newDepthImageNew, depthImageOne, 1, 0, NORM_MINMAX, CV_32FC1);
depthImageOne.convertTo(depthImageTwo, CV_16UC1, 65536.0,0.0);
imwrite("path", depthImageTwo);

归一化可能会导致深度信息丢失。我已经使用标准化来可视化图像。为了保留深度信息,我使用了以下代码。

Mat depthImageNew = cv::Mat(var.height, var.width, CV_32FC1,depthValues);
depthImageOne.convertTo(depthImageTwo, CV_16UC1, 1000.0,0.0);

【讨论】:

以上是关于从原始缓冲区数据创建 Mat 图像的主要内容,如果未能解决你的问题,请参考以下文章

如何使用模板函数从缓冲区(T* 数据数组)创建 cv::Mat?

如何在Android模拟器上显示Mat图像?使用NDK

如何使用 AVFoundation 从视频流中获取原始格式的图像缓冲区?

压缩原始图像缓冲区

如何在 OpenCV Mat 中保留固定的缓冲区大小?

WebGL - 从渲染缓冲区读取像素数据