kinect环境获取mkv视频中的点云数据,放到pcl点云数组中,实现的类

26 篇文章 0 订阅

文章链接:https://codemouse.online/archives/2020-05-16225206

kinectRecord.h

#pragma once

#include <k4a/k4a.h>
#include <k4arecord/playback.h>
#include <pcl/io/io.h>
#include <pcl/io/pcd_io.h>
#include <pcl/features/integral_image_normal.h>
#include <pcl/visualization/cloud_viewer.h>
#include <pcl/point_types.h>
#include <pcl/features/normal_3d.h>
#include <pcl/filters/filter.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <boost/parameter/parameters.hpp>
#include <stdio.h>
#include <stdlib.h>
#include <k4a/k4a.h>
#include <k4arecord/playback.h>


#include <stdio.h>
#include <malloc.h>
#include <iostream>
#include <vector>
#include<algorithm>
#include<cmath>
#include <time.h>
#include <string>


using namespace std;

class kinectRecord
{
public:

	kinectRecord();

	int getPointsCloud(pcl::PointCloud<pcl::PointXYZRGB>::Ptr &point_cloud_ptr); // 获取点云
	int setRecordTime(long long offset); // 设置视频帧位置
	int initRecord(string filename); // 初始化视频
private:
	int addPointsCloud(pcl::PointCloud<pcl::PointXYZRGB>::Ptr &point_cloud_ptr, k4a_image_t point_cloud_image, k4a_image_t color_image);
	k4a_image_t getPointsCloudImage(k4a_image_t color_image, k4a_image_t depth_image);

private:
	string filename; // 文件名
	k4a_playback_t handle; // 视频句柄
	k4a_record_configuration_t record_config; // 视频配置
	k4a_capture_t capture; // 获取到的视频帧
	k4a_transformation_t transformation_handle; // 点云转换的东西
};


kinectRecord.cpp

#include "kinectRecord.h"

kinectRecord::kinectRecord() {
	transformation_handle = NULL;
	handle = NULL;
	capture = NULL;
	
}

int kinectRecord::initRecord(string filename) {
	if (filename.size() == 0)
	{
		printf("请不要输入一个空的文件名,重新初始化\n");
		return -1;
	}
	this->filename = filename;
	k4a_result_t result = K4A_RESULT_SUCCEEDED;
	// 打开视频
	result = k4a_playback_open(filename.c_str(), &handle);
	if (result != K4A_RESULT_SUCCEEDED)
	{
		printf("Failed to open file: %s\n", filename.c_str());
		return -2;
	}
	// 获取视频的配置信息
	result = k4a_playback_get_record_configuration(handle, &record_config);
	if (result != K4A_RESULT_SUCCEEDED)
	{
		printf("Failed to get record configuration for file: %s\n", filename.c_str());
		return -3;
	}
	printf("startOffset:%d  suborDelay:%d \n", record_config.start_timestamp_offset_usec, record_config.subordinate_delay_off_master_usec);

	k4a_calibration_t calibration;
	k4a_playback_get_calibration(handle, &calibration);
	// 用来转换3d点云的玩意,一定要弄
	transformation_handle = k4a_transformation_create(&calibration);
	return 1;
}


int kinectRecord::addPointsCloud(pcl::PointCloud<pcl::PointXYZRGB>::Ptr &point_cloud_ptr, k4a_image_t point_cloud_image, k4a_image_t color_image)
{
	if (point_cloud_image == NULL || color_image == NULL)
	{
		printf("point_cloud_image or color image not have\n");
		return -6;
	}
	int width = k4a_image_get_width_pixels(color_image);
	int height = k4a_image_get_height_pixels(color_image);


	int16_t *point_cloud_image_data = (int16_t *)(void *)k4a_image_get_buffer(point_cloud_image);
	uint8_t *color_image_data = k4a_image_get_buffer(color_image);


	for (int i = 0; i < width * height; i++)
	{

		pcl::PointXYZRGB point;
		uint32_t rgb = 0;

		point.x = -point_cloud_image_data[3 * i + 0];
		point.y = -point_cloud_image_data[3 * i + 1];
		point.z = -point_cloud_image_data[3 * i + 2];
		// 这里设置背景深度
		if (point.z == 0 || point.z < -3000)
		{
			continue;
		}
		// 获取到颜色信息,颜色格式:bgra 
		//rgb |= ((color_image_data[4 * i + 0]) << 0);
		//rgb |= ((color_image_data[4 * i + 1]) << 8);
		//rgb |= ((color_image_data[4 * i + 2]) << 16);
		//rgb |= ((color_image_data[4 * i + 3]) << 24);
		// 获取到的彩色图片不知道怎么回事,这里设置颜色就行了
		rgb = 0;


		//cout << static_cast<uint32_t>(color_image_data[4 * i + 3]) << endl;
		//uint8_t alpha = color_image_data[4 * i + 3];
		//&& point.x <= -1000 && point.x >= 1000 && point.y <= -1000 && point.y >= 1000)
		//if (point.x == 0 && point.y == 0 && point.y == 0 && alpha == 0)
		//{
		//	continue;
		//}
		if (point.x == 0 && point.y == 0 && point.y == 0)
		{
			continue;
		}
		point.rgb = rgb;
		point_cloud_ptr->points.push_back(point);
	}
	return 1;

}



k4a_image_t kinectRecord::getPointsCloudImage(k4a_image_t color_image, k4a_image_t depth_image)
{

	int color_image_width_pixels = k4a_image_get_width_pixels(color_image);
	int color_image_height_pixels = k4a_image_get_height_pixels(color_image);
		

	k4a_image_t transformed_depth_image = NULL;
	// 创建点云深度图
	if (K4A_RESULT_SUCCEEDED != k4a_image_create(K4A_IMAGE_FORMAT_DEPTH16,
		color_image_width_pixels,
		color_image_height_pixels,
		color_image_width_pixels  * (int)sizeof(uint16_t),
		&transformed_depth_image))
	{
		cout << "Failed to create transformed depth image" << endl;
		return NULL;
	}


	k4a_image_t point_cloud_image = NULL;
	// 创建点云图片
	if (K4A_RESULT_SUCCEEDED != k4a_image_create(K4A_IMAGE_FORMAT_CUSTOM,
		color_image_width_pixels,
		color_image_height_pixels,
		color_image_width_pixels * 3 * (int)sizeof(int16_t),
		&point_cloud_image))
	{
		cout << "Failed to create point cloud image" << endl;
		return NULL;
	}
	

	// 将深度图转换到彩色图中
	if (K4A_RESULT_SUCCEEDED !=
		k4a_transformation_depth_image_to_color_camera(transformation_handle, depth_image, transformed_depth_image))
	{
		cout << "Failed to compute transformed depth image" << endl;
		return NULL;
	}


	// 初始化点云图片
	if (K4A_RESULT_SUCCEEDED != k4a_transformation_depth_image_to_point_cloud(transformation_handle,
		transformed_depth_image,
		K4A_CALIBRATION_TYPE_COLOR,
		point_cloud_image))
	{
		cout << "Failed to compute point cloud" << endl;
		return NULL;
	}
	k4a_image_release(transformed_depth_image);
	return point_cloud_image;
}


int kinectRecord::getPointsCloud(pcl::PointCloud<pcl::PointXYZRGB>::Ptr &point_cloud_ptr)
{
	if (handle == NULL)
		return -7;
	k4a_image_t depth_image = NULL;
	k4a_image_t color_image = NULL;
	k4a_result_t result = K4A_RESULT_SUCCEEDED;
	// 获取capture
	k4a_stream_result_t stream_result = k4a_playback_get_next_capture(handle, &capture);
	if (stream_result == K4A_STREAM_RESULT_EOF)
	{
		printf("ERROR: Recording file is not next capture: %s\n", filename.c_str());
		return -1;
	}

	// 获取深度图
	depth_image = k4a_capture_get_depth_image(capture);
	if (depth_image == NULL)
	{
		cout << "Failed to get depth image from capture" << endl;;
		return -3;
	}

	// 获取彩图
	color_image = k4a_capture_get_color_image(capture);
	if (color_image == NULL)
	{
		k4a_image_release(depth_image);
		cout << "Failed to get color image from capture" << endl;
		return -4;
	}
	
	// 得到点云图片
	k4a_image_t point_cloud_image = NULL;
	point_cloud_image = getPointsCloudImage(color_image, depth_image);

	if (point_cloud_image == NULL)
	{
		k4a_image_release(depth_image);
		k4a_image_release(color_image);
		cout << "Failed to get point_cloud_image from capture" << endl;
		return -4;
	}

	//uint64_t timestamp = k4a_image_get_device_timestamp_usec(color_image);
	//printf("image:  %7ju usec\n", timestamp);
	// 将点云图的点云信息加入到点云结构体中
	addPointsCloud(point_cloud_ptr, point_cloud_image, color_image);

	// 清理图片缓存

	k4a_image_release(point_cloud_image);
	k4a_image_release(depth_image);
	k4a_image_release(color_image);
	// 释放capure
	k4a_capture_release(capture);
	return 1;
}

// 设置视频的时间位置,相当于进度条,1000000是一秒
int kinectRecord::setRecordTime(long long offset) {
	if (k4a_playback_seek_timestamp(handle,
			record_config.start_timestamp_offset_usec,
			K4A_PLAYBACK_SEEK_BEGIN) != K4A_RESULT_SUCCEEDED) {
		return -1; 
	}
	return 1;

}


demo


#include "kinectRecord.h"

//pcl::PointCloud<pcl::PointXYZRGB>::Ptr point_cloud_ptr;
pcl::PointCloud<pcl::PointXYZRGB>::Ptr point_cloud_ptr(new pcl::PointCloud<pcl::PointXYZRGB>);

int main(int argc, char **argv)
{
	if (argc < 3)
	{
		printf("Usage: playback_external_sync.exe <master.mkv> <sub1.mkv>...\n");
		return 1;
	}

	// 输入视频名字
	kinectRecord record1,record2,record3;


	if (record1.initRecord(argv[1]) < 0)
	{
		printf("初始化失败!请检查是否有该文件\n");
		return 1;
	}
	else
	// 设置视频的帧位置
	//record1.setRecordTime(1500000);
	// 获取点云
	for (int i = 0; i < 100; i++)
	{
		if (record1.getPointsCloud(point_cloud_ptr) < 0) {
			printf("没有得到任何的点\n");
			// 重新设置到视频头
			record1.setRecordTime(0);
		}

		printf("size() : %d \n", point_cloud_ptr->points.size());
		point_cloud_ptr->clear();
	}
	


}

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
Azure Kinect是一种先进的深度摄像头设备,能够获取三维场景的点云数据。使用Azure Kinect进行点云获取非常简单。首先,我们需要连接Azure Kinect设备到计算机,并确保设备和计算机的驱动程序已经正确安装。接下来,我们可以使用Azure Kinect SDK的开发工具或编程语言来访问设备。 在编程,我们可以使用Azure Kinect SDK提供的API,通过编写代码来获取点云。在获取点云之前,我们需要首先打开Azure Kinect设备,并创建一个点云数据存储对象。然后,我们可以通过调用相关的函数或方法来启动Azure Kinect设备的深度图像和颜色图像流,并持续获取数据。 在获取到深度图像和颜色图像之后,我们可以使用这些图像来计算点云数据。通过使用深度图像的像素坐标以及该像素在世界坐标系下的三维坐标,可以将深度图像的每个像素点转换为三维空间的一个点。然后,可以将这些点存储到之前创建的点云数据存储对象。 在点云获取完成后,我们可以对点云数据进行处理或使用。例如,可以应用算法来对点云数据进行分割、滤波、拟合等操作。然后,可以将这些处理后的点云数据用于三维建模、虚拟现实、增强现实以及其他应用领域。 总之,通过使用Azure Kinect设备和相应的开发工具,我们可以相对容易地获取点云数据。这些点云数据可以用于许多不同的应用,为我们提供更加丰富和真实的三维场景信息。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值