/**

* 注意: Astra2、Gemini2 和 Gemini2L 相机目前仅支持 Windows 以及 Linux 内核版本不高于4.15,更高版本的 Linux 内核可能会有异常。

*/

#include // 包含为视频捕捉提供的功能

#include // 包含高层GUI(图形用户界面)功能

#include // 包含图像处理功能

#include // 包含标准输入输出流库

using namespace cv; // 使用cv命名空间

int main()

{

// 尝试打开摄像头

VideoCapture obsensorCapture(0, CAP_OBSENSOR);

// 如果摄像头打开失败

if(!obsensorCapture.isOpened()){

std::cerr << "Failed to open obsensor capture! Index out of range or no response from device";

return -1;

}

// 获取obsensor相机的内参

double fx = obsensorCapture.get(CAP_PROP_OBSENSOR_INTRINSIC_FX);

double fy = obsensorCapture.get(CAP_PROP_OBSENSOR_INTRINSIC_FY);

double cx = obsensorCapture.get(CAP_PROP_OBSENSOR_INTRINSIC_CX);

double cy = obsensorCapture.get(CAP_PROP_OBSENSOR_INTRINSIC_CY);

std::cout << "obsensor camera intrinsic params: fx=" << fx << ", fy=" << fy << ", cx=" << cx << ", cy=" << cy << std::endl;

Mat image; // 创建用于存放图像的矩阵

Mat depthMap; // 创建用于存放深度图的矩阵

Mat adjDepthMap; // 创建用于存放调整后的深度图的矩阵

// 设置深度值的最小和最大范围

const double minVal = 300; // 深度值的最小值

const double maxVal = 5000; // 深度值的最大值

while (true)

{

// 注释代码:用于捕获深度图像

// obsensorCapture >> depthMap;

// 另一种方法捕获深度图(和bgr彩色图像)。

if (obsensorCapture.grab())

{

if (obsensorCapture.retrieve(image, CAP_OBSENSOR_BGR_IMAGE))

{

// 显示RGB彩色图像

imshow("RGB", image);

}

if (obsensorCapture.retrieve(depthMap, CAP_OBSENSOR_DEPTH_MAP))

{

// 转换深度图到CV_8U,并进行调整,以便进行可视化

depthMap.convertTo(adjDepthMap, CV_8U, 255.0 / (maxVal - minVal), -minVal * 255.0 / (maxVal - minVal));

// 应用颜色映射,使深度图可视化更直观

applyColorMap(adjDepthMap, adjDepthMap, COLORMAP_JET);

// 显示调整后的深度图

imshow("DEPTH", adjDepthMap);

}

// 将深度图覆盖在bgr图像上

static const float alpha = 0.6f;

if (!image.empty() && !depthMap.empty())

{

// 再次调整并转换深度图

depthMap.convertTo(adjDepthMap, CV_8U, 255.0 / (maxVal - minVal), -minVal * 255.0 / (maxVal - minVal));

// 改变大小以与彩色图像相匹配

cv::resize(adjDepthMap, adjDepthMap, cv::Size(image.cols, image.rows));

for (int i = 0; i < image.rows; i++)

{

for (int j = 0; j < image.cols; j++)

{

// 混合像素值以获得深度覆盖效果

cv::Vec3b& outRgb = image.at(i, j);

uint8_t depthValue = 255 - adjDepthMap.at(i, j);

if (depthValue != 0 && depthValue != 255)

{

outRgb[0] = (uint8_t)(outRgb[0] * (1.0f - alpha) + depthValue * alpha);

outRgb[1] = (uint8_t)(outRgb[1] * (1.0f - alpha) + depthValue * alpha);

outRgb[2] = (uint8_t)(outRgb[2] * (1.0f - alpha) + depthValue * alpha);

}

}

}

// 显示深度信息叠加到彩色图上的图像

imshow("DepthToColor", image);

}

// 释放图像矩阵占用的内存

image.release();

depthMap.release();

}

// 如果检测到按键,则退出循环

if (pollKey() >= 0)

break;

}

return 0;

}

这段代码实现的功能是使用opencv库来读取和处理通过OBSENSOR摄像头获取的视频流数据。它会尝试打开摄像头,读取摄像头的内参,并不断地捕获视频帧和深度信息。视频帧将以RGB的形式显示,深度信息将会通过调整转换成为可视化的彩色深度图,并显示出来。此外,它还提供了将深度图与RGB图像相结合显示的功能,这通过混合两个图像的像素值实现。整个过程将持续进行,直到检测到按键操作为止。

depthMap.convertTo(adjDepthMap, CV_8U, 255.0 / (maxVal - minVal), -minVal * 255.0 / (maxVal - minVal));

混合像素值以获得深度覆盖效果

// 设置混合的透明度值

static const float alpha = 0.6f; // 可以理解为深度信息在混合中的占比

if (!image.empty() && !depthMap.empty())

{

// 对深度图进行调整和转换

depthMap.convertTo(adjDepthMap, CV_8U, 255.0 / (maxVal - minVal), -minVal * 255.0 / (maxVal - minVal));

// 改变深度图大小以匹配彩色图像的尺寸

cv::resize(adjDepthMap, adjDepthMap, cv::Size(image.cols, image.rows));

// 遍历图像的每个像素

for (int i = 0; i < image.rows; i++)

{

for (int j = 0; j < image.cols; j++)

{

// 获取彩色图像中的像素值

cv::Vec3b& outRgb = image.at(i, j);

// 获取深度图中对应的深度值(通过255减去是为了反转深度值,让高值显得更亮)

uint8_t depthValue = 255 - adjDepthMap.at(i, j);

// 如果深度值有效(非0且非满值)

if (depthValue != 0 && depthValue != 255)

{

// 用alpha值混合原像素值和深度值,更新彩色图像的像素值

outRgb[0] = (uint8_t)(outRgb[0] * (1.0f - alpha) + depthValue * alpha);

outRgb[1] = (uint8_t)(outRgb[1] * (1.0f - alpha) + depthValue * alpha);

outRgb[2] = (uint8_t)(outRgb[2] * (1.0f - alpha) + depthValue * alpha);

}

}

}

// 显示混合了深度信息的彩色图像

imshow("DepthToColor", image);

}

在这个代码中,alpha决定了混合时原图像和深度图的占比,alpha越大,则深度图的信息占比越重,覆盖效果越明显;相反,如果alpha较小,则原图的颜色占比较重。通过这种方式,我们可以在彩色图像上“覆盖”深度信息,以视觉上的方式展示出物体的距离信息。

相关阅读

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: