RGB-D相机(Azure Kinect DK)RGB图、深度图的获取,配准与保存
文章目录
RGB-D相机(Azure Kinect DK)RGB图、深度图的获取,配准与保存1.C++代码:2. CMakeLists3. 编译运行:4. 采集示例5. 参考
前提:官方apt安装Azure Kinect 传感器 SDK
代码AcquiringImages将原始深度图转换到RGB摄像头坐标系下,得到的配准后的深度图,并将转换后的depth图,原始RGB图、原始IR图保存在本地,采集格式仿照TUM数据集,图片的命名格式为时间戳+.png后缀。
1.C++代码:
#include <iostream>
#include <chrono>
#include <string>
#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <k4a/k4a.hpp>
using namespace cv
;
using namespace std
;
#define DEBUG_std_cout 0
int main(int argc
, char *argv
[]) {
const uint32_t device_count
= k4a
::device
::get_installed_count();
if (0 == device_count
) {
std
::cout
<< "Error: no K4A devices found. " << std
::endl
;
return -1;
} else {
std
::cout
<< "Found " << device_count
<< " connected devices. " << std
::endl
;
if (1 != device_count
)
{
std
::cout
<< "Error: more than one K4A devices found. " << std
::endl
;
return -1;
} else
{
std
::cout
<< "Done: found 1 K4A device. " << std
::endl
;
}
}
k4a
::device device
= k4a
::device
::open(K4A_DEVICE_DEFAULT
);
std
::cout
<< "Done: open device. " << std
::endl
;
k4a_device_configuration_t config
= K4A_DEVICE_CONFIG_INIT_DISABLE_ALL
;
config
.camera_fps
= K4A_FRAMES_PER_SECOND_30
;
config
.color_format
= K4A_IMAGE_FORMAT_COLOR_BGRA32
;
config
.color_resolution
= K4A_COLOR_RESOLUTION_1080P
;
config
.depth_mode
= K4A_DEPTH_MODE_NFOV_UNBINNED
;
config
.synchronized_images_only
= true;
device
.start_cameras(&config
);
std
::cout
<< "Done: start camera." << std
::endl
;
ofstream rgb_out
;
ofstream d_out
;
ofstream ir_out
;
rgb_out
.open("./rgb.txt");
d_out
.open("./depth.txt");
ir_out
.open("./ir.txt");
rgb_out
<<"# color images"<<endl
;
rgb_out
<<"# file: rgbd_dataset"<<endl
;
rgb_out
<<"# timestamp"<<" "<<"filename"<<endl
;
d_out
<<"# depth images"<<endl
;
d_out
<<"# file: rgbd_dataset"<<endl
;
d_out
<<"# timestamp"<<" "<<"filename"<<endl
;
ir_out
<<"# ir images"<<endl
;
ir_out
<<"# file: rgbd_dataset"<<endl
;
ir_out
<<"# timestamp"<<" "<<"filename"<<endl
;
rgb_out
<<flush
;
d_out
<<flush
;
k4a
::capture capture
;
int iAuto
= 0;
int iAutoError
= 0;
while (true) {
if (device
.get_capture(&capture
)) {
std
::cout
<< iAuto
<< ". Capture several frames to give auto-exposure" << std
::endl
;
if (iAuto
!= 30) {
iAuto
++;
continue;
} else {
std
::cout
<< "Done: auto-exposure" << std
::endl
;
break;
}
} else {
std
::cout
<< iAutoError
<< ". K4A_WAIT_RESULT_TIMEOUT." << std
::endl
;
if (iAutoError
!= 30) {
iAutoError
++;
continue;
} else {
std
::cout
<< "Error: failed to give auto-exposure. " << std
::endl
;
return -1;
}
}
}
std
::cout
<< "-----------------------------------" << std
::endl
;
std
::cout
<< "----- Have Started Kinect DK. -----" << std
::endl
;
std
::cout
<< "-----------------------------------" << std
::endl
;
k4a
::image rgbImage
;
k4a
::image depthImage
;
k4a
::image irImage
;
k4a
::image transformed_depthImage
;
cv
::Mat cv_rgbImage_with_alpha
;
cv
::Mat cv_rgbImage_no_alpha
;
cv
::Mat cv_depth
;
cv
::Mat cv_depth_8U
;
cv
::Mat cv_irImage
;
cv
::Mat cv_irImage_8U
;
while (true)
{
if (device
.get_capture(&capture
)) {
rgbImage
= capture
.get_color_image();
#if DEBUG_std_cout == 1
std
::cout
<< "[rgb] " << "\n"
<< "format: " << rgbImage
.get_format() << "\n"
<< "device_timestamp: " << rgbImage
.get_device_timestamp().count() << "\n"
<< "system_timestamp: " << rgbImage
.get_system_timestamp().count() << "\n"
<< "height*width: " << rgbImage
.get_height_pixels() << ", " << rgbImage
.get_width_pixels()
<< std
::endl
;
#endif
depthImage
= capture
.get_depth_image();
#if DEBUG_std_cout == 1
std
::cout
<< "[depth] " << "\n"
<< "format: " << depthImage
.get_format() << "\n"
<< "device_timestamp: " << depthImage
.get_device_timestamp().count() << "\n"
<< "system_timestamp: " << depthImage
.get_system_timestamp().count() << "\n"
<< "height*width: " << depthImage
.get_height_pixels() << ", " << depthImage
.get_width_pixels()
<< std
::endl
;
#endif
irImage
= capture
.get_ir_image();
#if DEBUG_std_cout == 1
std
::cout
<< "[ir] " << "\n"
<< "format: " << irImage
.get_format() << "\n"
<< "device_timestamp: " << irImage
.get_device_timestamp().count() << "\n"
<< "system_timestamp: " << irImage
.get_system_timestamp().count() << "\n"
<< "height*width: " << irImage
.get_height_pixels() << ", " << irImage
.get_width_pixels()
<< std
::endl
;
#endif
k4a
::calibration k4aCalibration
= device
.get_calibration(config
.depth_mode
, config
.color_resolution
);
k4a
::transformation k4aTransformation
= k4a
::transformation(k4aCalibration
);
transformed_depthImage
= k4aTransformation
.depth_image_to_color_camera(depthImage
);
cv_rgbImage_with_alpha
= cv
::Mat(rgbImage
.get_height_pixels(), rgbImage
.get_width_pixels(), CV_8UC4
,
(void *) rgbImage
.get_buffer());
cv
::cvtColor(cv_rgbImage_with_alpha
, cv_rgbImage_no_alpha
, cv
::COLOR_BGRA2BGR
);
cv_depth
= cv
::Mat(transformed_depthImage
.get_height_pixels(), transformed_depthImage
.get_width_pixels(), CV_16U
,
(void *) transformed_depthImage
.get_buffer(), static_cast<size_t
>(transformed_depthImage
.get_stride_bytes()));
cv_depth
.convertTo(cv_depth_8U
, CV_8U
, 1);
cv_irImage
= cv
::Mat(irImage
.get_height_pixels(), irImage
.get_width_pixels(), CV_16U
,
(void *) irImage
.get_buffer(), static_cast<size_t
>(irImage
.get_stride_bytes()));
cv_irImage
.convertTo(cv_irImage_8U
, CV_8U
, 1);
cv
::imshow("color", cv_rgbImage_no_alpha
);
cv
::imshow("depth", cv_depth_8U
);
cv
::imshow("ir", cv_irImage_8U
);
double time_rgb
= static_cast<double >(std
::chrono
::duration_cast
<std
::chrono
::microseconds
>(
rgbImage
.get_device_timestamp()).count());
std
::string filename_rgb
= std
::to_string(time_rgb
/1000000)+".png";
double time_d
= static_cast<double >(std
::chrono
::duration_cast
<std
::chrono
::microseconds
>(
depthImage
.get_device_timestamp()).count());
std
::string filename_d
= std
::to_string(time_d
/1000000)+".png";
double time_ir
= static_cast<double >(std
::chrono
::duration_cast
<std
::chrono
::microseconds
>(
irImage
.get_device_timestamp()).count());
std
::string filename_ir
= std
::to_string(time_ir
/1000000)+".png";
imwrite("./rgb/"+filename_rgb
, cv_rgbImage_no_alpha
);
imwrite("./depth/"+filename_d
,cv_depth_8U
);
imwrite("./ir/"+filename_ir
, cv_irImage_8U
);
std
::cout
<<"Acquiring!"<<endl
;
rgb_out
<<std
::to_string(time_rgb
/1000000)<<" "<<"rgb/"<<filename_rgb
<<endl
;
d_out
<<std
::to_string(time_d
/1000000)<<" "<<"depth/"<<filename_d
<<endl
;
ir_out
<<std
::to_string(time_ir
/1000000)<<" "<<"ir/"<<filename_ir
<<endl
;
rgb_out
<<flush
;
d_out
<<flush
;
ir_out
<<flush
;
cv_rgbImage_with_alpha
.release();
cv_rgbImage_no_alpha
.release();
cv_depth
.release();
cv_depth_8U
.release();
cv_irImage
.release();
cv_irImage_8U
.release();
capture
.reset();
} else {
std
::cout
<< "false: K4A_WAIT_RESULT_TIMEOUT." << std
::endl
;
}
}
cv
::destroyAllWindows();
rgb_out
<<flush
;
d_out
<<flush
;
ir_out
<<flush
;
rgb_out
.close();
d_out
.close();
ir_out
.close();
rgbImage
.reset();
depthImage
.reset();
irImage
.reset();
capture
.reset();
device
.close();
return 1;
}
2. CMakeLists
# Enable C++11
set(CMAKE_CXX_FLAGS
"-std=c++11")
set(CMAKE_CXX_STANDARD_REQUIRED TRUE
)
# Define project name
project(AcquiringImages
)
# Kinect DK相机
find_package(k4a REQUIRED
)# 后面的target_link_libraries中用到了k4a
::k4a
# Find OpenCV
find_package(OpenCV REQUIRED
)
# Add includes
include_directories( $
{OpenCV_INCLUDE_DIRS
} )
# Declare the executable target built from your sources
add_executable(AcquiringImages main
.cpp
)
# Link your application with other libraries
target_link_libraries(AcquiringImages k4a
::k4a $
{OpenCV_LIBS
})
3. 编译运行:
进入源码目录:
mkdir build
cd build
mkdir rgb depth ir
cmake
.. -GNinja
ninja
./AcquiringImages
闭终端或终止程序即可结束图像的采集。
结束图像采集后,将RGB图和深度图相关联:
进入源码目录:
cd build
python associate
.py rgb
.txt depth
.txt
> ./associations
.txt
4. 采集示例
以下为409实验室采集的图片示例:
RGB图:
深度图:
IR图:
5. 参考
https://cloud.tencent.com/developer/column/81192