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

news/2024/12/21 21:26:24/

a997cc7f76101abad68a185940910440.png

/*** 注意: Astra2、Gemini2 和 Gemini2L 相机目前仅支持 Windows 以及 Linux 内核版本不高于4.15,更高版本的 Linux 内核可能会有异常。
*/#include <opencv2/videoio.hpp>   // 包含为视频捕捉提供的功能
#include <opencv2/highgui.hpp>   // 包含高层GUI(图形用户界面)功能
#include <opencv2/imgproc.hpp>   // 包含图像处理功能
#include <iostream>              // 包含标准输入输出流库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<cv::Vec3b>(i, j);uint8_t depthValue = 255 - adjDepthMap.at<uint8_t>(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));

655bbd963d98ea0510528124d1df5d17.png

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

2c6350ad168b5c687d281540a597ca35.png

// 设置混合的透明度值
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<cv::Vec3b>(i, j);// 获取深度图中对应的深度值(通过255减去是为了反转深度值,让高值显得更亮)uint8_t depthValue = 255 - adjDepthMap.at<uint8_t>(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较小,则原图的颜色占比较重。通过这种方式,我们可以在彩色图像上“覆盖”深度信息,以视觉上的方式展示出物体的距离信息。


http://www.ppmy.cn/news/1424456.html

相关文章

良心无广的4款软件,每一款都逆天好用,且用且珍惜

闲话少说&#xff0c;直上干货&#xff01; 清浊 清浊是一款异常强大的国产手机清理应用&#xff0c;其设计理念崇尚简洁&#xff0c;用户界面清晰明快&#xff0c;且无任何弹窗广告干扰。更难能可贵的是&#xff0c;这款应用提供全程免费服务&#xff0c;功能多样&#xff0…

python django mvc

MVC框架: 1、URL映射到方法 [rootzz mysite]# cat urls.py """mysite URL Configuration The urlpatterns list routes URLs to views. For more information please see: https://docs.djangoproject.com/en/1.11/topics/http/urls/ Examples: Function …

R语言计算:t分布及t检验

t分布理论基础 t分布也称Student’s t-distribution&#xff0c;主要出现在小样本统计推断中&#xff0c;特别是当样本量较小且总体标准差未知时&#xff0c;用于估计正态分布的均值。其定义基于正态分布和 X 2 X^{2} X2分布&#xff08;卡方分布&#xff09;。如果随机变量X服…

轻量级Rust异步运行时

在Rust编程语言的世界中&#xff0c;异步编程是提高程序效率和性能的重要手段。现代软件开发中&#xff0c;随着并发编程需求的不断增加&#xff0c;异步运行时处理诸如I/O操作、网络通信等任务变得尤为重要。smol是Rust语言中的一个小巧而快速的异步运行时&#xff0c;尽管特性…

拼多多评论怎么删除?拼多多已评价不能删掉吗?

拼多多作为国内知名的电商平台&#xff0c;吸引了大量消费者的关注和参与。在购物过程中&#xff0c;我们经常会看到各种各样的评论&#xff0c;这些评论对于其他消费者来说&#xff0c;具有重要的参考价值。有时我们可能会因为各种原因需要删除自己的评论。那么&#xff0c;拼…

开发语言漫谈-JavaScript

JavaScript、Java名字很相近&#xff0c;但它们没有任何亲缘关系&#xff0c;是由不同公司开发的编程语言。Java由Sun公司&#xff08;后被Oracle收购&#xff09;开发&#xff0c;JavaScript最初是由Netscape公司开发的&#xff08;当年浏览器的霸主&#xff09;。JavaScrip…

Android Gradle 开发与应用 (七) : 实现打包自动复制文件插件

1. 前言 项目中遇到了一个问题 : 其中一个模块MyLibrary的assets文件夹中,需要存放很多文件(每个文件对应一个功能)。 这样导致的问题是MyLibrary打出的这个aar包体积特别大。 如果把MyLibrary严谨地拆解成若干个Module又比较费时,对于现在业务现状来说也显得没那么必要。…

Python项目2 数据可视化

生成数据 数据可视化 指的是通过可视化表示来探索数据&#xff0c;它与数据挖掘 数据挖掘 紧密相关&#xff0c;而数据挖掘指的是使用代码来探索数据集的规律和关联。数据集可以是用一行代码就能表 示的小型数字列表&#xff0c;也可以是数以吉字节的数据。 漂亮地呈现数据关…