PCL读入Dkam系列3D相机数据
写在前面
- PCL(Point Cloud Library):是一个开源的算法库,用C++编写,是当前点云处理的得力工具;
- 在使用PCL处理3D相机输出的点云中,可能遇到问题,因此编写此文章;
- 未尽问题欢迎与我深入交流:微信号:liu_zhisensor。
PCL在线读入Dkam系列3D相机数据
- 本例程基于WIN10+VisualStudio2019+DkamSDK_1.6.72+PCL1.12.0,采用C++语言;
- PCL配置方法另请查阅.
#include <iostream>
#include<cstring>
//DkamSDK
#include"dkam_discovery.h"
#include"dkam_gige_camera.h"
#include"dkam_gige_stream.h"
//PCL
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
int main()
{
std::cout << "Hello Zhisensor!" << std::endl;
std::cout << "微信:liu_zhisensor" << std::endl;
std::vector<DiscoveryInfo> discovery_info;
Discovery discovery;
GigeCamera camera;
GigeStream* pointgigestream = NULL;
std::vector<DiscoveryInfo>().swap(discovery_info);
//****************************************查找局域网内相机********************************************
int k = -1;
//查找相机
int camer_num = discovery.DiscoverCamera(&discovery_info);
std::cout << "局域网内相机数量为:" << camer_num << std::endl;
//对局域网内的相机进行排序0:IP 1:相机序列号
int camer_sort = discovery.CameraSort(&discovery_info, 1);
std::cout << "camer_sort=" << camer_sort << std::endl;
//显示局域网内相机的IP
for (int i = 0; i < camer_num; i++)
{
std::cout << "IP为:" << discovery.ConvertIpIntToString(discovery_info[i].camera_ip) << std::endl;
if (strcmp((discovery.ConvertIpIntToString(discovery_info[i].camera_ip)), "192.168.30.108") == 0)
{
k = i;
}
}
//****************************************连接局域网内指定的相机******************************************
//连接相机,相机的IP与上面的IP相同,若想获取相机IP可以先通过知微传感提供的DkamViewer软件查询
int connect = camera.CameraConnect(&discovery_info[k]);
//如果connect为0则表示连接成功,如果其他值则表示失败,请查看连接状态或者相机状态灯
std::cout << "connect=" << connect << std::endl;
//****************************************获取相机采集到的数据********************************************
if (connect == 0)
{
//获取当前红外相机的宽和高
int width = -1;
int height = -1;
int height_gray = camera.GetCameraHeight(&height, 0);
int width_gray = camera.GetCameraWidth(&width, 0);
std::cout << "相机灰度图的宽:" << width << std::endl;
std::cout << "相机灰度图的宽:" << height << std::endl;
//定义点云数据大小
PhotoInfo* point_data = new PhotoInfo;
point_data->pixel = new char[width * height * 6];
memset(point_data->pixel, 0, width * height * 6);
//设置触发模式 0 连拍模式 1 触发模式
int tirggerMode = camera.SetTriggerMode(1);
std::cout << "tirggerMode:" << tirggerMode << std::endl;
//开始点云的数据流通道(1:点云 0:红外 2:RGB)
int stream_point = camera.StreamOn(1, &pointgigestream);
std::cout << "stream_point=" << stream_point << std::endl;
//开始接收数据
int acquistion = camera.AcquisitionStart();
std::cout << "acquistion=" << acquistion << std::endl;
//刷新点云数据流通道缓冲区的数据
pointgigestream->FlushBuffer();
//相机固件版本号
std::cout << "camera 1 version" << camera.CameraVerion(discovery_info[k]) << std::endl;
//设置触发模式下触发帧数
int triggerCount = camera.SetTriggerCount();
std::cout << "triggerCount:" << triggerCount << std::endl;
//采集点云数据
int capturePoint = -1;
capturePoint = pointgigestream->TimeoutCapture(point_data, 3000000);
std::cout << "capture_Pointimage: " << capturePoint << std::endl;
//***************************将相机数据转化为PCL中可读的点云文件******************************
float *float_cloud = (float*)malloc(width * height * 3 * sizeof(float));
memset((void *)float_cloud,0,width * height * 3 * sizeof(float));
camera.Convert3DPointFromCharToFloat(*point_data, float_cloud);
pcl::PointCloud<pcl::PointXYZ>::Ptr PointCloud_PCL(new pcl::PointCloud<pcl::PointXYZ>);
PointCloud_PCL->width = width;
PointCloud_PCL->height = height;
PointCloud_PCL->points.resize(PointCloud_PCL->width * PointCloud_PCL->height);
for (size_t i = 0; i < PointCloud_PCL->points.size(); ++i)
{
PointCloud_PCL->points[i].x = float_cloud[3 * i + 0];
PointCloud_PCL->points[i].y = float_cloud[3 * i + 1];
PointCloud_PCL->points[i].z = float_cloud[3 * i + 2];
}
//保存点云
pcl::io::savePCDFile("D:/Zhisensor/Works/3DCode/Dkam_PCL_Con/Outputtestface.pcd", *PointCloud_PCL);
//***************************释放内存,关闭通道,断开相机******************************
memset(point_data->pixel, 0, width * height * 6);
//释放内存
delete[] point_data->pixel;
delete point_data;
//关闭点云数据流通道
int streamoff_point = camera.StreamOff(1, pointgigestream);
std::cout << "streamoff_point=" << streamoff_point << std::endl;
//断开相机
int disconnect = camera.CameraDisconnect();
std::cout << "disconnect=" << disconnect << std::endl;
}
return 0;
}
将保存点云用cloudcompare打开保存的如图
实际场景