当前位置:   article > 正文

【opencv】示例-videocapture_obsensor.cpp 读取和处理通过OBSENSOR摄像头获取的视频流数据...

【opencv】示例-videocapture_obsensor.cpp 读取和处理通过OBSENSOR摄像头获取的视频流数据...

a997cc7f76101abad68a185940910440.png

  1. /**
  2. * 注意: Astra2、Gemini2 和 Gemini2L 相机目前仅支持 Windows 以及 Linux 内核版本不高于4.15,更高版本的 Linux 内核可能会有异常。
  3. */
  4. #include <opencv2/videoio.hpp> // 包含为视频捕捉提供的功能
  5. #include <opencv2/highgui.hpp> // 包含高层GUI(图形用户界面)功能
  6. #include <opencv2/imgproc.hpp> // 包含图像处理功能
  7. #include <iostream> // 包含标准输入输出流库
  8. using namespace cv; // 使用cv命名空间
  9. int main()
  10. {
  11. // 尝试打开摄像头
  12. VideoCapture obsensorCapture(0, CAP_OBSENSOR);
  13. // 如果摄像头打开失败
  14. if(!obsensorCapture.isOpened()){
  15. std::cerr << "Failed to open obsensor capture! Index out of range or no response from device";
  16. return -1;
  17. }
  18. // 获取obsensor相机的内参
  19. double fx = obsensorCapture.get(CAP_PROP_OBSENSOR_INTRINSIC_FX);
  20. double fy = obsensorCapture.get(CAP_PROP_OBSENSOR_INTRINSIC_FY);
  21. double cx = obsensorCapture.get(CAP_PROP_OBSENSOR_INTRINSIC_CX);
  22. double cy = obsensorCapture.get(CAP_PROP_OBSENSOR_INTRINSIC_CY);
  23. std::cout << "obsensor camera intrinsic params: fx=" << fx << ", fy=" << fy << ", cx=" << cx << ", cy=" << cy << std::endl;
  24. Mat image; // 创建用于存放图像的矩阵
  25. Mat depthMap; // 创建用于存放深度图的矩阵
  26. Mat adjDepthMap; // 创建用于存放调整后的深度图的矩阵
  27. // 设置深度值的最小和最大范围
  28. const double minVal = 300; // 深度值的最小值
  29. const double maxVal = 5000; // 深度值的最大值
  30. while (true)
  31. {
  32. // 注释代码:用于捕获深度图像
  33. // obsensorCapture >> depthMap;
  34. // 另一种方法捕获深度图(和bgr彩色图像)。
  35. if (obsensorCapture.grab())
  36. {
  37. if (obsensorCapture.retrieve(image, CAP_OBSENSOR_BGR_IMAGE))
  38. {
  39. // 显示RGB彩色图像
  40. imshow("RGB", image);
  41. }
  42. if (obsensorCapture.retrieve(depthMap, CAP_OBSENSOR_DEPTH_MAP))
  43. {
  44. // 转换深度图到CV_8U,并进行调整,以便进行可视化
  45. depthMap.convertTo(adjDepthMap, CV_8U, 255.0 / (maxVal - minVal), -minVal * 255.0 / (maxVal - minVal));
  46. // 应用颜色映射,使深度图可视化更直观
  47. applyColorMap(adjDepthMap, adjDepthMap, COLORMAP_JET);
  48. // 显示调整后的深度图
  49. imshow("DEPTH", adjDepthMap);
  50. }
  51. // 将深度图覆盖在bgr图像上
  52. static const float alpha = 0.6f;
  53. if (!image.empty() && !depthMap.empty())
  54. {
  55. // 再次调整并转换深度图
  56. depthMap.convertTo(adjDepthMap, CV_8U, 255.0 / (maxVal - minVal), -minVal * 255.0 / (maxVal - minVal));
  57. // 改变大小以与彩色图像相匹配
  58. cv::resize(adjDepthMap, adjDepthMap, cv::Size(image.cols, image.rows));
  59. for (int i = 0; i < image.rows; i++)
  60. {
  61. for (int j = 0; j < image.cols; j++)
  62. {
  63. // 混合像素值以获得深度覆盖效果
  64. cv::Vec3b& outRgb = image.at<cv::Vec3b>(i, j);
  65. uint8_t depthValue = 255 - adjDepthMap.at<uint8_t>(i, j);
  66. if (depthValue != 0 && depthValue != 255)
  67. {
  68. outRgb[0] = (uint8_t)(outRgb[0] * (1.0f - alpha) + depthValue * alpha);
  69. outRgb[1] = (uint8_t)(outRgb[1] * (1.0f - alpha) + depthValue * alpha);
  70. outRgb[2] = (uint8_t)(outRgb[2] * (1.0f - alpha) + depthValue * alpha);
  71. }
  72. }
  73. }
  74. // 显示深度信息叠加到彩色图上的图像
  75. imshow("DepthToColor", image);
  76. }
  77. // 释放图像矩阵占用的内存
  78. image.release();
  79. depthMap.release();
  80. }
  81. // 如果检测到按键,则退出循环
  82. if (pollKey() >= 0)
  83. break;
  84. }
  85. return 0;
  86. }

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

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

655bbd963d98ea0510528124d1df5d17.png

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

2c6350ad168b5c687d281540a597ca35.png

  1. // 设置混合的透明度值
  2. static const float alpha = 0.6f; // 可以理解为深度信息在混合中的占比
  3. if (!image.empty() && !depthMap.empty())
  4. {
  5. // 对深度图进行调整和转换
  6. depthMap.convertTo(adjDepthMap, CV_8U, 255.0 / (maxVal - minVal), -minVal * 255.0 / (maxVal - minVal));
  7. // 改变深度图大小以匹配彩色图像的尺寸
  8. cv::resize(adjDepthMap, adjDepthMap, cv::Size(image.cols, image.rows));
  9. // 遍历图像的每个像素
  10. for (int i = 0; i < image.rows; i++)
  11. {
  12. for (int j = 0; j < image.cols; j++)
  13. {
  14. // 获取彩色图像中的像素值
  15. cv::Vec3b& outRgb = image.at<cv::Vec3b>(i, j);
  16. // 获取深度图中对应的深度值(通过255减去是为了反转深度值,让高值显得更亮)
  17. uint8_t depthValue = 255 - adjDepthMap.at<uint8_t>(i, j);
  18. // 如果深度值有效(非0且非满值)
  19. if (depthValue != 0 && depthValue != 255)
  20. {
  21. // 用alpha值混合原像素值和深度值,更新彩色图像的像素值
  22. outRgb[0] = (uint8_t)(outRgb[0] * (1.0f - alpha) + depthValue * alpha);
  23. outRgb[1] = (uint8_t)(outRgb[1] * (1.0f - alpha) + depthValue * alpha);
  24. outRgb[2] = (uint8_t)(outRgb[2] * (1.0f - alpha) + depthValue * alpha);
  25. }
  26. }
  27. }
  28. // 显示混合了深度信息的彩色图像
  29. imshow("DepthToColor", image);
  30. }

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/436213
推荐阅读
相关标签
  

闽ICP备14008679号