【RealSense】相机拍摄图像
saveDepthAndColor.cpp
// https://github.com/IntelRealSense/librealsense/tree/master/wrappers/opencv/imshow
// 简单的显示深度图和RGB图
// License: Apache 2.0. See LICENSE file in root directory.
// Copyright(c) 2017 Intel Corporation. All Rights Reserved.
#include <librealsense2/rs.hpp> // Include RealSense Cross Platform API
#include <librealsense2/rsutil.h>
#include <opencv2/opencv.hpp> // Include OpenCV API
#include <string>
using namespace cv;
using namespace std;
// 获取深度像素对应长度单位转换
float get_depth_scale(rs2::device dev);
// 检查摄像头数据管道设置是否改变
bool profile_changed(const std::vector<rs2::stream_profile> ¤t, const std::vector<rs2::stream_profile> &prev);
int main(int argc, char *argv[])
try
{
// 创建opencv窗口
// 创建 opencv 窗口
const char *depth_win = "depth_Image";
namedWindow(depth_win, WINDOW_AUTOSIZE);
const char *color_win = "color_Image";
namedWindow(color_win, WINDOW_AUTOSIZE);
// 声明深度着色器以实现深度数据的漂亮可视化
rs2::colorizer color_map;
rs2::align align_to(RS2_STREAM_COLOR);
// 声明 RealSense 管道,封装实际设备和传感器
rs2::pipeline pipe;
rs2::config pipe_config;
pipe_config.enable_stream(RS2_STREAM_DEPTH, 640, 480, RS2_FORMAT_Z16, 30);
pipe_config.enable_stream(RS2_STREAM_COLOR, 640, 480, RS2_FORMAT_BGR8, 30);
// start() 函数返回数据管道的profile
rs2::pipeline_profile profile = pipe.start(pipe_config);
// 使用数据管道的 profile 获取深度图像像素对应于长度单位(米)的转换比例
float depth_scale = get_depth_scale(profile.get_device());
cout << "depth_scale = " << depth_scale << endl;
// // 将深度图对齐到RGB图
rs2::align align(RS2_STREAM_COLOR); // 对齐的是彩色图,所以彩色图是不变的
static int i = 0;
while (getWindowProperty(depth_win, WND_PROP_AUTOSIZE) && getWindowProperty(color_win, WND_PROP_AUTOSIZE))
{
// 堵塞程序直到新的一帧捕获
rs2::frameset frameset = pipe.wait_for_frames();
// 正在对齐深度图到其他图像流,我们要确保对齐的图像流不发生改变
if (profile_changed(pipe.get_active_profile().get_streams(), profile.get_streams()))
{
// 如果profile发生改变,则更新align对象,重新获取深度图像像素到长度单位的转换比例
profile = pipe.get_active_profile();
align = rs2::align(align_to);
depth_scale = get_depth_scale(profile.get_device());
}
// 获取对齐后的帧
auto processed = align.process(frameset);
// 尝试获取对齐后的深度图像帧和其他帧
rs2::frame aligned_color_frame = processed.get_color_frame(); // RGB图
rs2::frame aligned_depth_frame = processed.get_depth_frame(); // 深度图
// 获取宽高
const int depth_w = aligned_depth_frame.as<rs2::video_frame>().get_width();
const int depth_h = aligned_depth_frame.as<rs2::video_frame>().get_height();
const int color_w = aligned_color_frame.as<rs2::video_frame>().get_width();
const int color_h = aligned_color_frame.as<rs2::video_frame>().get_height();
// 如果其中一个未能获取,继续迭代
if (!aligned_depth_frame || !aligned_color_frame)
{
continue;
}
// 创建opencv类型,并传入数据
Mat aligned_depth_image(Size(depth_w, depth_h), CV_16UC1, (void *)aligned_depth_frame.get_data(), Mat::AUTO_STEP);
Mat aligned_color_image(Size(color_w, color_h), CV_8UC3, (void *)aligned_color_frame.get_data(), Mat::AUTO_STEP);
// 图像显示
imshow(color_win, aligned_color_image);
imshow(depth_win, aligned_depth_image);
std::vector<int> compression_param;
compression_param.emplace_back(IMWRITE_PNG_COMPRESSION); // png 16位保存
compression_param.emplace_back(0); // 无压缩
if (waitKey(2) == 32) // 空格
{
std::string rgbFile_name = "rgb_" + std::to_string(i + 1) + ".png";
std::string depthFile_name = "depth_" + std::to_string(i + 1) + ".png";
imwrite(depthFile_name, aligned_depth_image, compression_param);
imwrite(rgbFile_name, aligned_color_image);
i++;
}
}
return EXIT_SUCCESS;
}
catch (const rs2::error &e)
{
std::cerr << "RealSense error calling " << e.get_failed_function() << "(" << e.get_failed_args() << "):\n " << e.what() << std::endl;
return EXIT_FAILURE;
}
catch (const std::exception &e)
{
std::cerr << e.what() << std::endl;
return EXIT_FAILURE;
}
float get_depth_scale(rs2::device dev)
{
// 遍历设备的传感器
for (rs2::sensor &sensor : dev.query_sensors())
{
// 检查传感器是否是深度传感器
if (rs2::depth_sensor dpt = sensor.as<rs2::depth_sensor>())
return dpt.get_depth_scale();
}
throw std::runtime_error("Device does not have a depth sensor");
}
bool profile_changed(const std::vector<rs2::stream_profile> ¤t, const std::vector<rs2::stream_profile> &prev)
{
for (auto &&sp : prev)
{
// if previous profile is in current ( maybe just added another)
auto itr = std::find_if(std::begin(current), std::end(current), [&sp](const rs2::stream_profile ¤t_sp)
{ return sp.unique_id() == current_sp.unique_id(); });
if (itr == std::end(current))
{
return true;
}
}
return false;
}
CMakeLists.txt
# minimum required cmake version: 3.1.0
cmake_minimum_required(VERSION 3.1.0)
project(saveImage)
find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})
set(DEPENDENCIES realsense2 ${OpenCV_LIBS})
add_executable(saveDepthAndColor saveDepthAndColor.cpp)
set_property(TARGET saveDepthAndColor PROPERTY CXX_STANDARD 11)
target_link_libraries(saveDepthAndColor ${DEPENDENCIES})